#ifndef DATASRC_MEMORY_RDATA_ENCODER_H
#define DATASRC_MEMORY_RDATA_ENCODER_H 1
-#include "rdata_field.h"
+#include <datasrc/memory/rdata_field.h>
#include <exceptions/exceptions.h>
/// Two main classes are provided: one is
/// \c isc::datasrc::memory::RdataEncoder, which allows
/// the application to create encoded data for a set of RDATA;
-/// the other (TBD) provides an interface to iterate over encoded set of
+/// the other is \c isc::datasrc::memory::RdataReader, which provides an
+/// interface to iterate over encoded set of
/// RDATA for purposes such as data lookups or rendering the data into the
/// wire format to create a DNS message.
///
const DataAction& data_action)
{
if (spec_pos_ < spec_count_) {
- const RdataFieldSpec& spec(spec_.fields[(spec_pos_ ++) %
+ const RdataFieldSpec& spec(spec_.fields[(spec_pos_++) %
spec_.field_count]);
if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
const LabelSequence sequence(data_ + data_pos_);
return (Result(sequence, spec.name_attributes));
} else {
const size_t length(spec.type == RdataFieldSpec::FIXEDLEN_DATA ?
- spec.fixeddata_len : lengths_[length_pos_ ++]);
- Result result(data_ + data_pos_, length);
+ spec.fixeddata_len : lengths_[length_pos_++]);
+ const Result result(data_ + data_pos_, length);
data_pos_ += length;
data_action(result.data(), result.size());
return (result);
// We didn't find where the signatures start yet. We do it
// by iterating the whole data and then returning the state
// back.
- size_t data_pos = data_pos_;
- size_t spec_pos = spec_pos_;
- size_t length_pos = length_pos_;
+ const size_t data_pos = data_pos_;
+ const size_t spec_pos = spec_pos_;
+ const size_t length_pos = length_pos_;
// When the next() gets to the last item, it sets the sigs_
while (nextInternal(emptyNameAction, emptyDataAction)) {}
assert(sigs_ != NULL);
length_pos_ = length_pos;
}
// Extract the result
- Result result(sigs_ + sig_data_pos_, lengths_[var_count_total_ +
- sig_pos_]);
+ const Result result(sigs_ + sig_data_pos_, lengths_[var_count_total_ +
+ sig_pos_]);
// Move the position of iterator.
sig_data_pos_ += lengths_[var_count_total_ + sig_pos_];
- sig_pos_ ++;
+ ++sig_pos_;
// Call the callback
data_action_(result.data(), result.size());
return (result);
/// \brief Class to read serialized rdata
///
-/// This class allows you to read the data encoded by RDataEncoder.
+/// This class allows you to read the data encoded by RdataEncoder.
/// It is rather low-level -- it provides sequence of data fields
/// and names. It does not give you convenient Rdata or RRset class.
///
/// It allows two types of operation. First one is by providing callbacks
-/// to the constructor and then iterating by repeatedly calling next, or
-/// calling iterate once. The callbacks are then called with each part of
+/// to the constructor and then iterating by repeatedly calling next(), or
+/// calling iterate() once. The callbacks are then called with each part of
/// the data.
///
/// \code
/// }
///
/// RdataReader reader(RRClass::IN(), RRType::AAAA(), size, data,
-/// &handleLabel, handleData);
+/// handleLabel, handleData);
/// reader.iterate();
/// \endcode
///
/// &handleLabel, handleData);
/// RdataReader::Result data;
/// while (data = reader.next()) {
-/// switch(data.type()) {
+/// switch (data.type()) {
/// case RdataReader::NAME:
/// ...
/// break;
/// \brief Function called on each name encountered in the data.
typedef boost::function<void(const dns::LabelSequence&, unsigned)>
NameAction;
+
/// \brief Function called on each data field in the data.
typedef boost::function<void(const uint8_t*, size_t)> DataAction;
/// as a default in the constructor.
static void emptyNameAction(const dns::LabelSequence& label,
unsigned attributes);
+
/// \brief a DataAction that does nothing.
///
/// This is a DataAction function that does nothing. It is used
compressible_(false),
additional_(false)
{}
+
/// \brief Constructor from a domain label
///
/// Creates the NAME type result. Used internally from RdataReader.
/// \param attributes The attributes, as stored by the serialized
/// data.
Result(const dns::LabelSequence& label, unsigned attributes);
+
/// \brief Constructor from data
///
/// Creates the DATA type result. Used internally from RdataReader.
/// \param data The data pointer to hold.
/// \param size The size to hold.
Result(const uint8_t* data, size_t size);
+
/// \brief The type of data returned.
DataType type() const { return (type_); }
+
/// \brief The raw data.
///
/// This is only valid if type() == DATA.
const uint8_t* data() const { return (data_); }
+
/// \brief The size of the raw data.
///
/// This is the number of bytes the data takes. It is valid only
/// if type() == DATA.
size_t size() const { return (size_); }
+
/// \brief The domain label.
///
/// This holds the domain label. It is only valid if type() == NAME.
const dns::LabelSequence& label() const { return (label_); }
+
/// \brief Is the name in label() compressible?
///
/// This is valid only if type() == NAME.
bool compressible() const { return (compressible_); }
+
/// \brief Does the name expect additional processing?
///
/// This is valid only if type() == NAME.
bool additional() const { return (additional_); }
+
/// \brief If there are data returned.
///
/// This returns if there are any data at all returned. This is
/// If there are no more data, a Result with type END is returned and
/// no callback is called.
Result next();
+
/// \brief Call next() until the end.
///
/// This is just convenience method to iterate through all the data.
- /// It calls next until it reaches the end (it does not revind before,
+ /// It calls next until it reaches the end (it does not rewind before,
/// therefore if you already called next() yourself, it does not start
/// at the beginning).
///
/// The method only makes sense if you set the callbacks in constructor.
void iterate() {
- while (next()) { }
+ while (next()) {}
}
+
/// \brief Step to next piece of RRSig data.
///
/// This is almost the same as next(), but it iterates through the
/// associated RRSig data, not the data for the given RRType.
Result nextSig();
+
/// \brief Iterate through all RRSig data.
///
/// This is almost the same as iterate(), but it iterates through the
/// RRSig data instead.
void iterateSig() {
- while (nextSig()) { }
+ while (nextSig()) {}
}
+
/// \brief Rewind the iterator to the beginnig of data.
///
/// The following next() and nextSig() will start iterating from the
// PERFORMANCE OF THIS SOFTWARE.
// Note: This file tests both the rdata_encoder and rdata_reader. They are
-// tested together because they form kind the oposite sides of the same
+// tested together because they form kind the opposite sides of the same
// functionality.
#include <exceptions/exceptions.h>
renderNameField(MessageRenderer* renderer, bool additional_required,
const LabelSequence& labels, unsigned attributes)
{
- EXPECT_EQ(additional_required,
- (attributes & NAMEATTR_ADDITIONAL) != 0);
+ EXPECT_EQ(additional_required, (attributes & NAMEATTR_ADDITIONAL) != 0);
renderer->writeName(labels, (attributes & NAMEATTR_COMPRESSIBLE) != 0);
}
template<class DecoderStyle>
class RdataEncodeDecodeTest : public RdataSerializationTest {
public:
- // This helper test method constructs encodes the given list of RDATAs
+ // This helper test method encodes the given list of RDATAs
// (in rdata_list), and then iterates over the data, rendering the fields
// in the wire format. It then compares the wire data with the one
// generated by the normal libdns++ interface to see the encoding/decoding
encoded_data.end());
}
- // If RRSIGs are given, we need to extract the list of the RRSIG lengths
- // and adjust encoded_data_ further.
+ // If RRSIGs are given, we need to extract the list of the RRSIG
+ // lengths and adjust encoded_data_ further.
vector<uint16_t> rrsiglen_list;
if (rrsig_count > 0) {
const size_t rrsig_len_size = rrsig_count * sizeof(uint16_t);
additionalRequired(rrtype), _1, _2),
boost::bind(renderDataField, &renderer, _1, _2));
- // 2nd dummy name
- renderer.writeName(dummy_name2);
- // Finally, dump any RRSIGs in wire format.
- foreachRRSig(encoded_data, rrsiglen_list,
- boost::bind(renderDataField, &renderer, _1, _2));
+ // 2nd dummy name
+ renderer.writeName(dummy_name2);
+ // Finally, dump any RRSIGs in wire format.
+ foreachRRSig(encoded_data, rrsiglen_list,
+ boost::bind(renderDataField, &renderer, _1, _2));
}
};
boost::bind(renderNameField, &renderer,
additionalRequired(rrtype), _1, _2),
boost::bind(renderDataField, &renderer, _1, _2));
- while (reader.next()) { }
+ while (reader.next()) {}
renderer.writeName(dummy_name2);
- while (reader.nextSig()) { }
+ while (reader.nextSig()) {}
}
};
TYPED_TEST(RdataEncodeDecodeTest, addRdata) {
vector<ConstRdataPtr> rrsigs;
- this->addRdataCommon(rrsigs); // basic tests without RRSIGs (empty vector)
+ this->addRdataCommon(rrsigs); // basic tests without RRSIGs (empty vector)
// Test with RRSIGs (covered type doesn't always match, but the encoder
// doesn't check that)
// Test the result returns what it was constructed with.
TEST_F(RdataSerializationTest, readerResult) {
// Default constructor
- RdataReader::Result empty;
+ const RdataReader::Result empty;
// Everything should be at the "empty" values, type END
EXPECT_EQ(RdataReader::END, empty.type());
EXPECT_EQ(NULL, empty.data());
EXPECT_FALSE(empty.compressible());
EXPECT_FALSE(empty.additional());
// Constructor from label sequence
- LabelSequence seq(Name("example.org"));
- RdataReader::Result compressible(seq, NAMEATTR_COMPRESSIBLE);
+ const Name name("example.org");
+ const LabelSequence seq(name);
+ const RdataReader::Result compressible(seq, NAMEATTR_COMPRESSIBLE);
EXPECT_EQ(RdataReader::NAME, compressible.type());
EXPECT_EQ(NULL, compressible.data());
EXPECT_EQ(0, compressible.size());
EXPECT_TRUE(compressible);
EXPECT_TRUE(compressible.compressible());
EXPECT_FALSE(compressible.additional());
- RdataReader::Result incompressible(seq, NAMEATTR_ADDITIONAL);
+ const RdataReader::Result incompressible(seq, NAMEATTR_ADDITIONAL);
EXPECT_EQ(RdataReader::NAME, incompressible.type());
EXPECT_EQ(NULL, incompressible.data());
EXPECT_EQ(0, incompressible.size());
EXPECT_FALSE(incompressible.compressible());
EXPECT_TRUE(incompressible.additional());
// Constructor from data
- uint8_t byte;
- RdataReader::Result data(&byte, 1);
+ const uint8_t byte = 0;
+ const RdataReader::Result data(&byte, 1);
EXPECT_EQ(RdataReader::DATA, data.type());
EXPECT_EQ(&byte, data.data());
EXPECT_EQ(1, data.size());