Commit 863da09e authored by Marcin Siodelski's avatar Marcin Siodelski

[2312] Implemented toText method for custom options.

parent ff216738
......@@ -15,6 +15,7 @@
#include <dhcp/libdhcp++.h>
#include <dhcp/option_data_types.h>
#include <dhcp/option_custom.h>
#include <util/encode/hex.h>
namespace isc {
namespace dhcp {
......@@ -144,6 +145,62 @@ OptionCustom::createBuffers() {
std::swap(buffers_, buffers);
}
std::string
OptionCustom::dataFieldToText(const OptionDataType data_type,
const uint32_t index) const {
std::ostringstream tmp;
// Get the value of the data field.
switch (data_type) {
case OPT_BINARY_TYPE:
tmp << util::encode::encodeHex(readBinary(index));
break;
case OPT_BOOLEAN_TYPE:
tmp << (readBoolean(index) ? "true" : "false");
break;
case OPT_INT8_TYPE:
tmp << readInteger<int8_t>(index);
break;
case OPT_INT16_TYPE:
tmp << readInteger<int16_t>(index);
break;
case OPT_INT32_TYPE:
tmp << readInteger<int32_t>(index);
break;
case OPT_UINT8_TYPE:
tmp << readInteger<uint8_t>(index);
break;
case OPT_UINT16_TYPE:
tmp << readInteger<uint16_t>(index);
break;
case OPT_UINT32_TYPE:
tmp << readInteger<uint32_t>(index);
break;
case OPT_IPV4_ADDRESS_TYPE:
case OPT_IPV6_ADDRESS_TYPE:
{
asiolink::IOAddress address("127.0.0.1");
readAddress(index, address);
tmp << address.toText();
break;
}
case OPT_STRING_TYPE:
{
std::string s;
readString(index, s);
tmp << s;
break;
}
default:
;
}
// Append data field type in brackets.
tmp << " ( " << OptionDataTypeUtil::getDataTypeName(data_type) << " ) ";
return (tmp.str());
}
void
OptionCustom::pack4(isc::util::OutputBuffer& buf) {
if (len() > 255) {
......@@ -242,6 +299,17 @@ OptionCustom::len() {
return (length);
}
void OptionCustom::setData(const OptionBufferConstIter first,
const OptionBufferConstIter last) {
// We will copy entire option buffer, so we have to resize data_.
data_.resize(std::distance(first, last));
std::copy(first, last, data_.begin());
// Chop the data_ buffer into set of buffers that represent
// option fields data.
createBuffers();
}
std::string OptionCustom::toText(int indent /* = 0 */ ) {
std::stringstream tmp;
......@@ -252,19 +320,35 @@ std::string OptionCustom::toText(int indent /* = 0 */ ) {
<< ", data fields:" << std::endl;
OptionDataType data_type = definition_.getType();
for (unsigned int i = 0; i < getDataFieldsNum(); ++i) {
if (data_type == OPT_RECORD_TYPE) {
const OptionDefinition::RecordFieldsCollection& fields =
definition_.getRecordFields();
for (OptionDefinition::RecordFieldsConstIter field = fields.begin();
field != fields.end(); ++field) {
for (int j = 0; j < indent + 2; ++j) {
tmp << " ";
}
tmp << OptionDataTypeUtil::getDataTypeName(*field)
<< ", value = " << "here is a value" << std::endl;
if (data_type == OPT_RECORD_TYPE) {
const OptionDefinition::RecordFieldsCollection& fields =
definition_.getRecordFields();
// For record types we iterate over fields defined in
// option definition and match the appropriate buffer
// with them.
for (OptionDefinition::RecordFieldsConstIter field = fields.begin();
field != fields.end(); ++field) {
for (int j = 0; j < indent + 2; ++j) {
tmp << " ";
}
tmp << "#" << distance(fields.begin(), field) << " "
<< dataFieldToText(*field, distance(fields.begin(), field))
<< std::endl;
}
} else {
// For non-record types we iterate over all buffers
// and print the data type set globally for an option
// definition. We take the same code path for arrays
// and non-arrays as they only differ in such a way that
// non-arrays have just single data field.
for (unsigned int i = 0; i < getDataFieldsNum(); ++i) {
for (int j = 0; j < indent + 2; ++j) {
tmp << " ";
}
tmp << "#" << i << " "
<< dataFieldToText(definition_.getType(), i)
<< std::endl;
}
}
......@@ -277,16 +361,5 @@ std::string OptionCustom::toText(int indent /* = 0 */ ) {
return tmp.str();
}
void OptionCustom::setData(const OptionBufferConstIter first,
const OptionBufferConstIter last) {
// We will copy entire option buffer, so we have to resize data_.
data_.resize(std::distance(first, last));
std::copy(first, last, data_.begin());
// Chop the data_ buffer into set of buffers that represent
// option fields data.
createBuffers();
}
} // end of isc::dhcp namespace
} // end of isc namespace
......@@ -198,6 +198,15 @@ private:
/// @brief Create collection of buffers representing data field values.
void createBuffers();
/// @brief Return a text representation of a data field.
///
/// @param data_type data type of a field.
/// @param index data field buffer index within a custom option.
///
/// @return text representation of a data field.
std::string dataFieldToText(const OptionDataType data_type,
const uint32_t index) const;
/// Option definition used to create an option.
OptionDefinition definition_;
......
......@@ -44,7 +44,7 @@ OptionDataTypeUtil::OptionDataTypeUtil() {
data_type_names_[OPT_UINT16_TYPE] = "uint16";
data_type_names_[OPT_UINT32_TYPE] = "uint32";
data_type_names_[OPT_IPV4_ADDRESS_TYPE] = "ipv4-address";
data_type_names_[OPT_IPV6_ADDRESS_TYPE] = "ipv4-address";
data_type_names_[OPT_IPV6_ADDRESS_TYPE] = "ipv6-address";
data_type_names_[OPT_STRING_TYPE] = "string";
data_type_names_[OPT_FQDN_TYPE] = "fqdn";
data_type_names_[OPT_RECORD_TYPE] = "record";
......
Markdown is supported
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