11 if (c >=
'0' && c <=
'9') {
14 if (c >=
'a' && c <=
'f') {
17 if (c >=
'A' && c <=
'F') {
29 if (uri.starts_with(
"ndn:")) {
34 if (uri.empty() || uri ==
"/") {
35 return {.value = name, .error = Error::Success};
45 while (start < uri.size()) {
47 size_t end = uri.find(
'/', start);
48 if (end == std::string_view::npos) {
52 const std::string_view compStr = uri.substr(start, end - start);
54 if (!compStr.empty()) {
59 for (
size_t i = 0; i < compStr.size() && compLen <
NAME_MAX_LENGTH; ++i) {
60 if (compStr[i] ==
'%' && i + 2 < compStr.size()) {
61 const int hi = hexValue(compStr[i + 1]);
62 const int lo = hexValue(compStr[i + 2]);
63 if (hi >= 0 && lo >= 0) {
64 compBuf[compLen++] =
static_cast<uint8_t
>((hi << 4) | lo);
69 compBuf[compLen++] =
static_cast<uint8_t
>(compStr[i]);
72 const Error err = name.appendComponentInternal(compBuf, compLen);
73 if (err != Error::Success) {
74 return {.value =
Name{}, .error = err};
81 return {.value = name, .error = Error::Success};
90 if (!headerResult.ok()) {
91 return {.value =
Name{}, .error = headerResult.error};
94 if (headerResult.value.type !=
tlv::Name) {
95 return {.value =
Name{}, .error = Error::DecodeFailed};
98 const size_t nameValueLen = headerResult.value.length;
100 return {.value =
Name{}, .error = Error::DecodeFailed};
104 const size_t nameValueStart = decoder.
position();
107 while (decoder.
position() < nameValueStart + nameValueLen) {
109 if (!compHeader.ok()) {
110 return {.value =
Name{}, .error = compHeader.error};
116 if (decoder.
skip(compHeader.value.length) != Error::Success) {
117 return {.value =
Name{}, .error = Error::DecodeFailed};
122 if (decoder.
remaining() < compHeader.value.length) {
123 return {.value =
Name{}, .error = Error::DecodeFailed};
126 const Error err = name.appendComponentInternal(decoder.
current(), compHeader.value.length);
127 if (err != Error::Success) {
128 return {.value =
Name{}, .error = err};
131 decoder.
skip(compHeader.value.length);
134 if (bytesRead !=
nullptr) {
138 return {.value = name, .error = Error::Success};
148 if (numComponents_ == 0) {
158 for (
size_t i = 0; i < numComponents_; ++i) {
160 if (written < bufSize - 1) {
161 buf[written++] =
'/';
167 for (
size_t j = 0; j < comp.
size && written < bufSize - 1; ++j) {
168 const uint8_t c = comp.
value[j];
170 if ((c >=
'A' && c <=
'Z') || (c >=
'a' && c <=
'z') || (c >=
'0' && c <=
'9') ||
171 c ==
'-' || c ==
'.' || c ==
'_' || c ==
'~') {
172 buf[written++] =
static_cast<char>(c);
173 }
else if (written + 3 < bufSize) {
174 static const char hex[] =
"0123456789ABCDEF";
175 buf[written++] =
'%';
176 buf[written++] = hex[c >> 4];
177 buf[written++] = hex[c & 0x0F];
190 const size_t nameValueLen = length_;
192 const size_t totalSize = headerSize + nameValueLen;
194 if (bufSize < totalSize) {
195 return Error::BufferTooSmall;
201 if (err != Error::Success) {
206 if (err != Error::Success) {
210 err = encoder.
writeBytes(buffer_.data(), length_);
211 if (err != Error::Success) {
215 encodedLen = encoder.
size();
216 return Error::Success;
220 if (index >= numComponents_) {
221 return {.
value =
nullptr, .size = 0};
224 const auto& comp = components_[index];
225 return {.value = buffer_.data() + comp.offset, .size = comp.length};
229 return appendComponentInternal(
reinterpret_cast<const uint8_t*
>(comp.data()), comp.size());
233 return appendComponentInternal(value, len);
236Error Name::appendComponentInternal(
const uint8_t* value,
size_t len) {
237 if (numComponents_ >= NAME_MAX_COMPONENTS) {
238 return Error::TooManyComponents;
244 if (length_ + tlvSize > NAME_MAX_LENGTH) {
245 return Error::NameTooLong;
249 TlvEncoder encoder(buffer_.data() + length_, buffer_.size() - length_);
252 if (err != Error::Success) {
256 err = encoder.writeLength(len);
257 if (err != Error::Success) {
262 const size_t valueOffset = length_ + encoder.size();
264 err = encoder.writeBytes(value, len);
265 if (err != Error::Success) {
270 components_[numComponents_].offset =
static_cast<uint16_t
>(valueOffset);
271 components_[numComponents_].length =
static_cast<uint16_t
>(len);
274 length_ += encoder.size();
276 return Error::Success;
280 const size_t minComponents =
281 (numComponents_ < other.numComponents_) ? numComponents_ : other.numComponents_;
283 for (
size_t i = 0; i < minComponents; ++i) {
300 if (numComponents_ < other.numComponents_) {
303 if (numComponents_ > other.numComponents_) {
314 if (numComponents_ > other.numComponents_) {
318 for (
size_t i = 0; i < numComponents_; ++i) {
337 for (
size_t i = 0; i < length_; ++i) {
338 h = ((h << 5) + h) + buffer_[i];
Error encode(uint8_t *buf, size_t bufSize, size_t &encodedLen) const
Encode the Name to TLV wire format.
static Result< Name > fromWire(const uint8_t *buf, size_t len, size_t *bytesRead=nullptr)
Decode a Name from TLV wire format.
uint32_t hash() const
Compute hash value of the Name.
Error appendComponent(std::string_view comp)
Append a string component.
size_t toUri(char *buf, size_t bufSize) const
Convert the Name to a URI string.
int compare(const Name &other) const
Compare with another Name.
NameComponent component(size_t index) const
Get the component at a given index.
bool equals(const Name &other) const
Check equality with another Name.
bool isPrefixOf(const Name &other) const
Check if this Name is a prefix of another Name.
static Result< Name > fromUri(std::string_view uri)
Create a Name from a URI string.
size_t position() const
Get current position.
const uint8_t * current() const
Pointer to current position.
Result< TlvHeader > readTlvHeader()
Read a TLV header (Type and Length) at once.
Error skip(size_t len)
Skip a specified number of bytes.
size_t remaining() const
Remaining readable bytes.
Error writeLength(size_t length)
Write a TLV Length.
Error writeBytes(const uint8_t *data, size_t len)
Write a byte sequence.
size_t size() const
Current write position (= number of bytes written)
Error writeType(uint32_t type)
Write a TLV Type.
constexpr size_t NAME_MAX_LENGTH
Maximum Name length (bytes)
constexpr uint32_t Name
Name.
constexpr uint32_t GenericNameComponent
Generic Name component.
const uint8_t * value
Pointer to the component value.
size_t size
Size of the component in bytes.
NDN TLV (Type-Length-Value) encoding.
constexpr size_t varNumberSize(uint64_t value)
Calculate the encoded size of a VAR-NUMBER.