Commit aa708cee authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2097] removed now-unneeded files

parent 23492e5e
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "rdata_reader.h"
using namespace isc::dns;
namespace isc {
namespace datasrc {
namespace memory {
void
RdataReader::emptyNameAction(const LabelSequence&, unsigned) {
// Do nothing here. On purpose, it's not unfinished.
}
void
RdataReader::emptyDataAction(const uint8_t*, size_t) {
// Do nothing here. On purpose, it's not unfinished.
}
RdataReader::Result::Result(const LabelSequence& label,
unsigned attributes) :
label_(label),
data_(NULL),
size_(0),
type_(NAME),
compressible_((attributes & NAMEATTR_COMPRESSIBLE) != 0),
additional_((attributes & NAMEATTR_ADDITIONAL) != 0)
{}
RdataReader::Result::Result(const uint8_t* data, size_t size) :
label_(Name::ROOT_NAME()),
data_(data),
size_(size),
type_(DATA),
compressible_(false),
additional_(false)
{}
RdataReader::RdataReader(const RRClass& rrclass, const RRType& rrtype,
const uint8_t* data,
size_t rdata_count, size_t sig_count,
const NameAction& name_action,
const DataAction& data_action) :
name_action_(name_action),
data_action_(data_action),
spec_(getRdataEncodeSpec(rrclass, rrtype)),
var_count_total_(spec_.varlen_count * rdata_count),
sig_count_(sig_count),
spec_count_(spec_.field_count * rdata_count),
// The casts, well, C++ decided it doesn't like completely valid
// and explicitly allowed cast in C, so we need to fool it through
// void.
lengths_(static_cast<const uint16_t*>(
static_cast<const void*>(data))), // The lenghts are stored first
// And the data just after all the lengths
data_(data + (var_count_total_ + sig_count_) * sizeof(uint16_t)),
sigs_(NULL)
{
rewind();
}
void
RdataReader::rewind() {
data_pos_ = 0;
spec_pos_ = 0;
length_pos_ = 0;
sig_data_pos_ = 0;
sig_pos_ = 0;
}
RdataReader::Result
RdataReader::nextInternal(const NameAction& name_action,
const DataAction& data_action)
{
if (spec_pos_ < spec_count_) {
const RdataFieldSpec& spec(spec_.fields[(spec_pos_ ++) %
spec_.field_count]);
if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
const LabelSequence sequence(data_ + data_pos_);
data_pos_ += sequence.getSerializedLength();
name_action(sequence, spec.name_attributes);
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);
data_pos_ += length;
data_action(result.data(), result.size());
return (result);
}
} else {
sigs_ = data_ + data_pos_;
return (Result());
}
}
RdataReader::Result
RdataReader::next() {
return (nextInternal(name_action_, data_action_));
}
RdataReader::Result
RdataReader::nextSig() {
if (sig_pos_ < sig_count_) {
if (sigs_ == NULL) {
// 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_;
// When the next() gets to the last item, it sets the sigs_
while (nextInternal(emptyNameAction, emptyDataAction)) {}
assert(sigs_ != NULL);
// Return the state
data_pos_ = data_pos;
spec_pos_ = spec_pos;
length_pos_ = length_pos;
}
// Extract the result
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_ ++;
// Call the callback
data_action_(result.data(), result.size());
return (result);
} else {
return (Result());
}
}
size_t
RdataReader::getSize() const {
size_t storage_size = 0; // this will be the end result
size_t data_pos = 0;
size_t length_pos = 0;
// Go over all data fields, adding their lengths to storage_size
for (size_t spec_pos = 0; spec_pos < spec_count_; ++spec_pos) {
const RdataFieldSpec& spec =
spec_.fields[spec_pos % spec_.field_count];
if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
const size_t seq_len =
LabelSequence(data_ + data_pos).getSerializedLength();
data_pos += seq_len;
storage_size += seq_len;
} else {
const size_t data_len =
(spec.type == RdataFieldSpec::FIXEDLEN_DATA ?
spec.fixeddata_len : lengths_[length_pos++]);
data_pos += data_len;
storage_size += data_len;
}
}
// Same for all RRSIG data
for (size_t sig_pos = 0; sig_pos < sig_count_; ++sig_pos) {
const size_t sig_data_len = lengths_[length_pos++];
storage_size += sig_data_len;
}
// Finally, add the size for 16-bit length fields
storage_size += (var_count_total_ * sizeof(uint16_t) +
sig_count_ * sizeof(uint16_t));
return (storage_size);
}
}
}
}
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef DATASRC_MEMORY_RDATA_READER_H
#define DATASRC_MEMORY_RDATA_READER_H 1
#include "rdata_field.h"
#include <boost/function.hpp>
#include <dns/labelsequence.h>
#include <dns/name.h>
namespace isc {
// Some forward declarations
namespace dns{
class RRClass;
class RRType;
}
namespace datasrc {
namespace memory {
/// \brief Class to read serialized rdata
///
/// 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
/// the data.
///
/// \code
/// void handleLabel(const dns::LabelSequence& label, unsigned int flags) {
/// ...
/// }
/// void handleData(const uint8_t* data, size_t size) {
/// ...
/// }
///
/// RdataReader reader(RRClass::IN(), RRType::AAAA(), size, data,
/// &handleLabel, handleData);
/// reader.iterate();
/// \endcode
///
/// The other way is to use the return value of next() and loop through
/// it manually. It has the inconvenience of having the type condition, but
/// the code is in one place. The used way is matter of personal preferrence,
/// there's no much difference on the technical side.
///
/// \code
/// RdataReader reader(RRClass::IN(), RRType::AAAA(), size, data,
/// &handleLabel, handleData);
/// RdataReader::Result data;
/// while (data = reader.next()) {
/// switch(data.type()) {
/// case RdataReader::NAME:
/// ...
/// break;
/// case RdataReader::DATA:
/// ...
/// break;
/// default: assert(0); // Can not happen
/// }
/// }
/// \endcode
///
/// \note It is caller's responsibility to pass valid data here. This means
/// the data returned by RdataEncoder and the corresponding class and type.
/// If this is not the case, all the kinds of pointer hell might get loose.
class RdataReader {
public:
/// \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;
/// \brief a NameAction that does nothing.
///
/// This is a NameAction function that does nothing. It is used
/// 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
/// as a default in the constructor.
static void emptyDataAction(const uint8_t* data, size_t size);
/// \brief Constructor
///
/// This constructs the reader on top of some serialized data.
/// It does not copy the data, you have to make sure the data
/// is valid for the whole life of this object and that they
/// don't change.
///
/// \param rrclass The class the encoded rdata belongs to.
/// \param rrtype The type of the encode rdata.
/// \param data The actual data.
/// \param rdata_count The number of Rdata encoded in the data.
/// \param sig_count The number of RRSig rdata bundled with the data.
/// \param name_action The callback to be called on each encountered name.
/// \param data_action The callback to be called on each data chunk.
RdataReader(const dns::RRClass& rrclass, const dns::RRType& rrtype,
const uint8_t* data, size_t rdata_count, size_t sig_count,
const NameAction& name_action = &emptyNameAction,
const DataAction& data_action = &emptyDataAction);
/// \brief The type of data returned from this iteration.
enum DataType {
NAME, ///< This iteration returns domain label
DATA, ///< This iteration returns unstructuder data
END ///< No more data to return
};
/// \brief Data from one iteration
///
/// Each time you call next() or nextSig(), it returns some data.
/// This holds the data.
///
/// It is valid only for as long as the RdataReader that returned it.
///
/// All the methods can be called under any circumstances. However,
/// if the required property is not valid for the given type (eg.
/// when calling size() on type() == NAME), it returns some "empty"
/// value (0, NULL, or the like).
class Result {
public:
/// \brief Default constructor
///
/// It creates an empty result (with no data) of type END.
Result() :
// TODO: Do we maybe want to have a static one to copy
// instead of constructing new one from the root Name?
label_(dns::Name::ROOT_NAME()),
data_(NULL),
size_(0),
type_(END),
compressible_(false),
additional_(false)
{}
/// \brief Constructor from a domain label
///
/// Creates the NAME type result. Used internally from RdataReader.
///
/// \param label The label to hold
/// \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
/// equivalent to action != END, but it allows for more convenient
/// code of a loop through the data.
operator bool() const {
return (type() != END);
}
private:
dns::LabelSequence label_;
const uint8_t* data_;
size_t size_;
DataType type_;
bool compressible_;
bool additional_;
};
/// \brief Step to next piece of data.
///
/// This returns the next available data. Also, the apropriate hook
/// (name_action or data_action, depending on the data type) as passed
/// to the constructor is called.
///
/// 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,
/// 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()) { }
}
/// \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()) { }
}
/// \brief Rewind the iterator to the beginnig of data.
///
/// The following next() and nextSig() will start iterating from the
/// beginning again.
void rewind();
/// \brief Returns the size of associated data.
///
/// This should be the same as the return value of
/// RdataEncoder::getStorageLength() for the same set of data.
/// The intended use of this method is to tell the caller the size of
/// data that were possibly dynamically allocated so that the caller can
/// use it for deallocation.
///
/// This method only uses the parameters given at the construction of the
/// object, and does not rely on or modify other mutable states.
/// In practice, when the caller wants to call this method, that would be
/// the only purpose of that RdataReader object (although it doesn't have
/// to be so).
size_t getSize() const;
private:
const NameAction name_action_;
const DataAction data_action_;
const RdataEncodeSpec& spec_;
// Total number of var-length fields, count of signatures
const size_t var_count_total_, sig_count_, spec_count_;
// Pointer to the beginning of length fields
const uint16_t* const lengths_;
// Pointer to the beginning of the data (after the lengths)
const uint8_t* const data_;
// Pointer to the first data signature
// Will be computed during the normal RR iteration
const uint8_t* sigs_;
// The positions in data.
size_t data_pos_, spec_pos_, length_pos_;
size_t sig_pos_, sig_data_pos_;
Result nextInternal(const NameAction& name_action,
const DataAction& data_action);
};
}
}
}
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment