All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
tlv-decoder.h
1 
22 #ifndef NDN_TLV_DECODER_H
23 #define NDN_TLV_DECODER_H
24 
25 #include <ndn-cpp/c/common.h>
26 #include <ndn-cpp/c/errors.h>
27 #include "../../util/blob.h"
28 #include "tlv.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
35  const uint8_t *input;
36  size_t inputLength;
37  size_t offset;
38 };
39 
46 static __inline void
47 ndn_TlvDecoder_initialize(struct ndn_TlvDecoder *self, const uint8_t *input, size_t inputLength)
48 {
49  self->input = input;
50  self->inputLength = inputLength;
51  self->offset = 0;
52 }
53 
61 ndn_Error
62 ndn_TlvDecoder_readExtendedVarNumber(struct ndn_TlvDecoder *self, unsigned int firstOctet, uint64_t *varNumber);
63 
70 static __inline ndn_Error
71 ndn_TlvDecoder_readVarNumber(struct ndn_TlvDecoder *self, uint64_t *varNumber)
72 {
73  unsigned int firstOctet;
74 
75  // Read the first octet inline.
76  if (self->offset >= self->inputLength)
77  return NDN_ERROR_read_past_the_end_of_the_input;
78 
79  firstOctet = (unsigned int)self->input[self->offset++];
80  if (firstOctet < 253) {
81  // The value is simple, so we can return it inline.
82  *varNumber = (uint64_t)firstOctet;
83  return NDN_ERROR_success;
84  }
85  else
86  return ndn_TlvDecoder_readExtendedVarNumber(self, firstOctet, varNumber);
87 }
88 
98 static __inline ndn_Error
99 ndn_TlvDecoder_readTypeAndLength
100  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t *length)
101 {
102  ndn_Error error;
103  uint64_t type;
104  uint64_t lengthVarNumber;
105 
106  if ((error = ndn_TlvDecoder_readVarNumber(self, &type)))
107  return error;
108 
109  if (type != (uint64_t)expectedType)
110  return NDN_ERROR_did_not_get_the_expected_TLV_type;
111 
112  if ((error = ndn_TlvDecoder_readVarNumber(self, &lengthVarNumber)))
113  return error;
114 
115  // Silently ignore if the length is larger than size_t.
116  *length = (size_t)lengthVarNumber;
117  if (self->offset + *length > self->inputLength)
118  return NDN_ERROR_TLV_length_exceeds_buffer_length;
119 
120  return NDN_ERROR_success;
121 }
122 
134 static __inline ndn_Error
135 ndn_TlvDecoder_readNestedTlvsStart(struct ndn_TlvDecoder *self, unsigned int expectedType, size_t *endOffset)
136 {
137  ndn_Error error;
138  size_t length;
139  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &length)))
140  return error;
141  *endOffset = self->offset + length;
142 
143  return NDN_ERROR_success;
144 }
145 
159 ndn_Error
160 ndn_TlvDecoder_skipRemainingNestedTlvs
161  (struct ndn_TlvDecoder *self, size_t endOffset, int skipCritical);
162 
177 static __inline ndn_Error
178 ndn_TlvDecoder_finishNestedTlvs(struct ndn_TlvDecoder *self, size_t endOffset)
179 {
180  // Check the simple, expected case inline.
181  if (self->offset != endOffset)
182  return ndn_TlvDecoder_skipRemainingNestedTlvs(self, endOffset, 0);
183 
184  return NDN_ERROR_success;
185 }
186 
196 static __inline ndn_Error
197 ndn_TlvDecoder_finishNestedTlvsSkipCritical
198  (struct ndn_TlvDecoder *self, size_t endOffset)
199 {
200  // Check the simple, expected case inline.
201  if (self->offset != endOffset)
202  return ndn_TlvDecoder_skipRemainingNestedTlvs(self, endOffset, 1);
203 
204  return NDN_ERROR_success;
205 }
206 
218 static __inline ndn_Error
219 ndn_TlvDecoder_peekType(struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset, int *gotExpectedType)
220 {
221  if (self->offset >= endOffset)
222  // No more sub TLVs to look at.
223  *gotExpectedType = 0;
224  else {
225  size_t saveOffset = self->offset;
226  uint64_t type;
227  ndn_Error error = ndn_TlvDecoder_readVarNumber(self, &type);
228  // Restore offset.
229  self->offset = saveOffset;
230  if (error)
231  return error;
232 
233  *gotExpectedType = (type == expectedType ? 1 : 0);
234  }
235 
236  return NDN_ERROR_success;
237 }
238 
246 ndn_Error
247 ndn_TlvDecoder_readExtendedNonNegativeInteger(struct ndn_TlvDecoder *self, size_t length, uint64_t *value);
248 
256 static __inline ndn_Error
257 ndn_TlvDecoder_readNonNegativeInteger(struct ndn_TlvDecoder *self, size_t length, uint64_t *value)
258 {
259  if (length == 1) {
260  // Read the simple integer inline.
261  if (self->offset >= self->inputLength)
262  return NDN_ERROR_read_past_the_end_of_the_input;
263 
264  *value = (uint64_t)self->input[self->offset++];
265  return NDN_ERROR_success;
266  }
267  else
268  return ndn_TlvDecoder_readExtendedNonNegativeInteger(self, length, value);
269 }
270 
280 static __inline ndn_Error
281 ndn_TlvDecoder_readNonNegativeIntegerTlv(struct ndn_TlvDecoder *self, unsigned int expectedType, uint64_t *value)
282 {
283  ndn_Error error;
284  size_t length;
285  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &length)))
286  return error;
287  if ((error = ndn_TlvDecoder_readNonNegativeInteger(self, length, value)))
288  return error;
289 
290  return NDN_ERROR_success;
291 }
292 
303 static __inline ndn_Error
304 ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv
305  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset,
306  int *value)
307 {
308  int gotExpectedType;
309  ndn_Error error;
310  uint64_t unsignedValue;
311 
312  if ((error = ndn_TlvDecoder_peekType
313  (self, expectedType, endOffset, &gotExpectedType)))
314  return error;
315 
316  if (!gotExpectedType) {
317  *value = -1;
318  return NDN_ERROR_success;
319  }
320 
321  if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv
322  (self, expectedType, &unsignedValue)))
323  return error;
324 
325  *value = (int)unsignedValue;
326  return NDN_ERROR_success;
327 }
328 
339 static __inline ndn_Error
340 ndn_TlvDecoder_readOptionalNonNegativeIntegerTlvAsDouble
341  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset,
342  double *value)
343 {
344  int gotExpectedType;
345  ndn_Error error;
346  uint64_t unsignedValue;
347 
348  if ((error = ndn_TlvDecoder_peekType
349  (self, expectedType, endOffset, &gotExpectedType)))
350  return error;
351 
352  if (!gotExpectedType) {
353  *value = -1;
354  return NDN_ERROR_success;
355  }
356 
357  if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv
358  (self, expectedType, &unsignedValue)))
359  return error;
360 
361  *value = (double)unsignedValue;
362  return NDN_ERROR_success;
363 }
364 
374 static __inline ndn_Error
375 ndn_TlvDecoder_readBlobTlv
376  (struct ndn_TlvDecoder *self, unsigned int expectedType, struct ndn_Blob *value)
377 {
378  ndn_Error error;
379  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &value->length)))
380  return error;
381 
382  // ndn_TlvDecoder_readTypeAndLength already checked if the value->length exceeds the input buffer.
383  value->value = self->input + self->offset;
384  self->offset += value->length;
385 
386  return NDN_ERROR_success;
387 }
388 
402 static __inline ndn_Error
403 ndn_TlvDecoder_readOptionalBlobTlv
404  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset,
405  struct ndn_Blob *value)
406 {
407  int gotExpectedType;
408  ndn_Error error;
409 
410  if ((error = ndn_TlvDecoder_peekType
411  (self, expectedType, endOffset, &gotExpectedType)))
412  return error;
413 
414  if (!gotExpectedType) {
415  value->value = 0;
416  value->length = 0;
417  return NDN_ERROR_success;
418  }
419 
420  if ((error = ndn_TlvDecoder_readBlobTlv(self, expectedType, value)))
421  return error;
422 
423  return NDN_ERROR_success;
424 }
425 
436 static __inline ndn_Error
437 ndn_TlvDecoder_readBooleanTlv
438  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset, int *value)
439 {
440  int gotExpectedType;
441  ndn_Error error;
442  if ((error = ndn_TlvDecoder_peekType(self, expectedType, endOffset, &gotExpectedType)))
443  return error;
444 
445  if (!gotExpectedType)
446  *value = 0;
447  else {
448  size_t length;
449  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &length)))
450  return error;
451  // We expect the length to be 0, but update offset anyway.
452  self->offset += length;
453 
454  *value = 1;
455  }
456 
457  return NDN_ERROR_success;
458 }
459 
469 static __inline ndn_Error
470 ndn_TlvDecoder_skipTlv
471  (struct ndn_TlvDecoder *self, unsigned int expectedType)
472 {
473  ndn_Error error;
474  size_t length;
475 
476  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &length)))
477  return error;
478  // readTypeAndLength already checked if the length exceeds the input buffer.
479  self->offset += length;
480 
481  return NDN_ERROR_success;
482 }
483 
493 static __inline ndn_Error
494 ndn_TlvDecoder_skipOptionalTlv
495  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset)
496 {
497  int gotExpectedType;
498  ndn_Error error;
499 
500  if ((error = ndn_TlvDecoder_peekType
501  (self, expectedType, endOffset, &gotExpectedType)))
502  return error;
503 
504  if (gotExpectedType)
505  return ndn_TlvDecoder_skipTlv(self, expectedType);
506 
507  return NDN_ERROR_success;
508 }
509 
515 static __inline void ndn_TlvDecoder_seek(struct ndn_TlvDecoder *self, size_t offset)
516 {
517  self->offset = offset;
518 }
519 
529 static __inline ndn_Error
530 ndn_TlvDecoder_getSlice
531  (struct ndn_TlvDecoder *self, size_t beginOffset, size_t endOffset,
532  struct ndn_Blob *slice)
533 {
534  if (beginOffset > self->inputLength || endOffset > self->inputLength)
535  return NDN_ERROR_read_past_the_end_of_the_input;
536 
537  slice->value = self->input + beginOffset;
538  if (beginOffset > endOffset)
539  // We don't expect this to happen.
540  slice->length = 0;
541  else
542  slice->length = endOffset - beginOffset;
543 
544  return NDN_ERROR_success;
545 }
546 
547 #ifdef __cplusplus
548 }
549 #endif
550 
551 #endif
size_t length
the number of bytes in value.
Definition: blob-types.h:35
const uint8_t * value
pointer to the pre-allocated buffer for the value.
Definition: blob-types.h:34
Copyright (C) 2015-2018 Regents of the University of California.
Definition: blob-types.h:33
Copyright (C) 2014-2018 Regents of the University of California.
Definition: tlv-decoder.h:34