21 OptionDataTypeUtil::OptionDataTypeUtil() {
65 OptionDataTypeUtil::getDataType(
const std::string& data_type) {
66 return (OptionDataTypeUtil::instance().getDataTypeImpl(data_type));
70 OptionDataTypeUtil::getDataTypeImpl(
const std::string& data_type)
const {
71 std::map<std::string, OptionDataType>::const_iterator data_type_it =
72 data_types_.find(data_type);
73 if (data_type_it != data_types_.end()) {
74 return (data_type_it->second);
96 return (asiolink::V4ADDRESS_LEN);
99 return (asiolink::V6ADDRESS_LEN);
112 return (OptionDataTypeUtil::instance().getDataTypeNameImpl(data_type));
116 OptionDataTypeUtil::getDataTypeNameImpl(
const OptionDataType data_type)
const {
117 std::map<OptionDataType, std::string>::const_iterator data_type_it =
118 data_type_names_.find(data_type);
119 if (data_type_it != data_type_names_.end()) {
120 return (data_type_it->second);
126 OptionDataTypeUtil::instance() {
127 static OptionDataTypeUtil instance;
132 OptionDataTypeUtil::readAddress(
const std::vector<uint8_t>& buf,
133 const short family) {
135 if (family == AF_INET) {
136 if (buf.size() < V4ADDRESS_LEN) {
138 <<
" IPv4 address. Invalid buffer size: " << buf.size());
141 }
else if (family == AF_INET6) {
142 if (buf.size() < V6ADDRESS_LEN) {
144 <<
" IPv6 address. Invalid buffer size: " << buf.size());
149 <<
" IP address. Invalid family: " << family);
155 std::vector<uint8_t>& buf) {
156 const std::vector<uint8_t>& vec = address.
toBytes();
157 buf.insert(buf.end(), vec.begin(), vec.end());
161 OptionDataTypeUtil::writeBinary(
const std::string& hex_str,
162 std::vector<uint8_t>& buf) {
171 <<
" to binary data type: " << ex.
what());
175 buf.insert(buf.end(), binary.begin(), binary.end());
179 OptionDataTypeUtil::readTuple(
const std::vector<uint8_t>& buf,
181 if (lengthfieldtype == OpaqueDataTuple::LENGTH_1_BYTE) {
182 if (buf.size() < 1) {
184 <<
" tuple (length). Invalid buffer size: "
187 uint8_t len = buf[0];
188 if (buf.size() < 1 + len) {
190 <<
" tuple (length " <<
static_cast<unsigned>(len)
191 <<
"). Invalid buffer size: " << buf.size());
195 std::memcpy(&value[0], &buf[1], len);
197 }
else if (lengthfieldtype == OpaqueDataTuple::LENGTH_2_BYTES) {
198 if (buf.size() < 2) {
200 <<
" tuple (length). Invalid buffer size: "
204 if (buf.size() < 2 + len) {
206 <<
" tuple (length " << len
207 <<
"). Invalid buffer size: " << buf.size());
211 std::memcpy(&value[0], &buf[2], len);
215 <<
" tuple. Invalid length type field: "
216 <<
static_cast<unsigned>(lengthfieldtype));
221 OptionDataTypeUtil::readTuple(
const std::vector<uint8_t>& buf,
224 tuple.
unpack(buf.begin(), buf.end());
231 OptionDataTypeUtil::writeTuple(
const std::string& value,
233 std::vector<uint8_t>& buf) {
234 if (lengthfieldtype == OpaqueDataTuple::LENGTH_1_BYTE) {
235 if (value.size() > std::numeric_limits<uint8_t>::max()) {
237 << value.size() <<
" larger than "
238 << std::numeric_limits<uint8_t>::max() <<
")");
240 buf.push_back(
static_cast<uint8_t
>(value.size()));
242 }
else if (lengthfieldtype == OpaqueDataTuple::LENGTH_2_BYTES) {
243 if (value.size() > std::numeric_limits<uint16_t>::max()) {
245 << value.size() <<
" larger than "
246 << std::numeric_limits<uint16_t>::max() <<
")");
248 buf.resize(buf.size() + 2);
250 &buf[buf.size() - 2], 2);
253 <<
" tuple. Invalid length type field: "
254 <<
static_cast<unsigned>(lengthfieldtype));
256 buf.insert(buf.end(), value.begin(), value.end());
261 std::vector<uint8_t>& buf) {
266 if (tuple.
getLength() > std::numeric_limits<uint8_t>::max()) {
269 << std::numeric_limits<uint8_t>::max() <<
")");
271 buf.push_back(
static_cast<uint8_t
>(tuple.
getLength()));
274 if (tuple.
getLength() > std::numeric_limits<uint16_t>::max()) {
277 << std::numeric_limits<uint16_t>::max() <<
")");
279 buf.resize(buf.size() + 2);
281 &buf[buf.size() - 2], 2);
284 <<
" tuple. Invalid length type field: "
287 buf.insert(buf.end(), tuple.
getData().begin(), tuple.
getData().end());
291 OptionDataTypeUtil::readBool(
const std::vector<uint8_t>& buf) {
294 <<
" value. Invalid buffer size " << buf.size());
298 }
else if (buf[0] == 0) {
302 <<
" value. Invalid value " <<
static_cast<int>(buf[0]));
306 OptionDataTypeUtil::writeBool(
const bool value,
307 std::vector<uint8_t>& buf) {
308 buf.push_back(
static_cast<uint8_t
>(value ? 1 : 0));
312 OptionDataTypeUtil::readFqdn(
const std::vector<uint8_t>& buf) {
316 <<
" The buffer is empty.");
333 OptionDataTypeUtil::writeFqdn(
const std::string& fqdn,
334 std::vector<uint8_t>& buf,
341 const uint8_t* data = labels.
getData(&read_len);
342 buf.insert(buf.end(), data, data + read_len);
350 OptionDataTypeUtil::getLabelCount(
const std::string& text_name) {
356 if (text_name.empty()) {
368 OptionDataTypeUtil::readPrefix(
const std::vector<uint8_t>& buf) {
374 "a truncated buffer");
387 uint8_t prefix_len_bytes = (prefix_len.
asUint8() / 8);
397 const uint8_t zero_padded_bits =
398 static_cast<uint8_t
>((8 - (prefix_len.
asUint8() % 8)) % 8);
401 if (zero_padded_bits > 0) {
408 if ((buf.size() - 1) < prefix_len_bytes) {
410 << prefix_len.
asUnsigned() <<
" from a truncated buffer");
419 if (buf.size() > 1) {
422 std::vector<uint8_t> prefix_buf(buf.begin() + 1, buf.end());
425 if (prefix_buf.size() < V6ADDRESS_LEN) {
426 prefix_buf.resize(V6ADDRESS_LEN);
427 if (prefix_len_bytes < prefix_buf.size()) {
430 std::fill(prefix_buf.begin() + prefix_len_bytes,
431 prefix_buf.end(), 0);
433 if (zero_padded_bits) {
437 prefix_buf.at(prefix_len_bytes - 1) =
438 (prefix_buf.at(prefix_len_bytes - 1)
448 return (std::make_pair(prefix_len, prefix));
454 }
catch (
const std::exception& ex) {
464 OptionDataTypeUtil::writePrefix(
const PrefixLen& prefix_len,
466 std::vector<uint8_t>& buf) {
468 if (!prefix.
isV6()) {
475 buf.push_back(prefix_len.
asUint8());
478 uint8_t prefix_len_bytes = prefix_len.
asUint8() / 8;
481 const uint8_t zero_padded_bits =
482 static_cast<uint8_t
>((8 - (prefix_len.
asUint8() % 8)) % 8);
485 if (zero_padded_bits > 0) {
491 std::vector<uint8_t> prefix_bytes = prefix.
toBytes();
492 buf.insert(buf.end(), prefix_bytes.begin(),
493 prefix_bytes.begin() + prefix_len_bytes);
496 if (zero_padded_bits) {
497 *buf.rbegin() = (*buf.rbegin() >> zero_padded_bits) << zero_padded_bits;
502 OptionDataTypeUtil::readPsid(
const std::vector<uint8_t>& buf) {
503 if (buf.size() < 3) {
505 <<
" Invalid buffer size " << buf.size()
506 <<
". Expected 3 bytes (PSID length and PSID value)");
510 uint8_t psid_len = buf[0];
513 if (psid_len >
sizeof(uint16_t) * 8) {
515 <<
static_cast<unsigned>(psid_len)
516 <<
", this value is expected to be in range of 0 to 16");
530 if ((psid_len > 0) &&
531 ((psid &
static_cast<uint16_t
>(
static_cast<uint16_t
>(0xFFFF << psid_len)
532 >> psid_len)) != 0)) {
534 <<
" for a specified PSID length "
535 <<
static_cast<unsigned>(psid_len));
540 if (psid_len ==
sizeof(psid) * 8) {
544 psid = psid >> (
sizeof(psid) * 8 - psid_len);
546 return (std::make_pair(
PSIDLen(psid_len),
PSID(psid)));
550 OptionDataTypeUtil::writePsid(
const PSIDLen& psid_len,
const PSID& psid,
551 std::vector<uint8_t>& buf) {
552 if (psid_len.
asUint8() >
sizeof(psid) * 8) {
555 <<
", this value is expected to be in range of 0 to 16");
559 (psid.
asUint16() > (0xFFFF >> (
sizeof(uint16_t) * 8 - psid_len.
asUint8())))) {
561 <<
" for a specified PSID length "
565 buf.resize(buf.size() + 3);
566 buf.at(buf.size() - 3) = psid_len.
asUint8();
569 &buf[buf.size() - 2], 2);
574 OptionDataTypeUtil::readString(
const std::vector<uint8_t>& buf) {
577 value.insert(value.end(), buf.begin(), buf.end());
583 OptionDataTypeUtil::writeString(
const std::string& value,
584 std::vector<uint8_t>& buf) {
585 if (value.size() > 0) {
586 buf.insert(buf.end(), value.begin(), value.end());