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 
155 ndn_Error
156 ndn_TlvDecoder_skipRemainingNestedTlvs
157  (struct ndn_TlvDecoder *self, size_t endOffset);
158 
167 static __inline ndn_Error
168 ndn_TlvDecoder_finishNestedTlvs(struct ndn_TlvDecoder *self, size_t endOffset)
169 {
170  // Check the simple, expected case inline.
171  if (self->offset != endOffset)
172  return ndn_TlvDecoder_skipRemainingNestedTlvs(self, endOffset);
173 
174  return NDN_ERROR_success;
175 }
176 
188 static __inline ndn_Error
189 ndn_TlvDecoder_peekType(struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset, int *gotExpectedType)
190 {
191  if (self->offset >= endOffset)
192  // No more sub TLVs to look at.
193  *gotExpectedType = 0;
194  else {
195  size_t saveOffset = self->offset;
196  uint64_t type;
197  ndn_Error error = ndn_TlvDecoder_readVarNumber(self, &type);
198  // Restore offset.
199  self->offset = saveOffset;
200  if (error)
201  return error;
202 
203  *gotExpectedType = (type == expectedType ? 1 : 0);
204  }
205 
206  return NDN_ERROR_success;
207 }
208 
216 ndn_Error
217 ndn_TlvDecoder_readExtendedNonNegativeInteger(struct ndn_TlvDecoder *self, size_t length, uint64_t *value);
218 
226 static __inline ndn_Error
227 ndn_TlvDecoder_readNonNegativeInteger(struct ndn_TlvDecoder *self, size_t length, uint64_t *value)
228 {
229  if (length == 1) {
230  // Read the simple integer inline.
231  if (self->offset >= self->inputLength)
232  return NDN_ERROR_read_past_the_end_of_the_input;
233 
234  *value = (uint64_t)self->input[self->offset++];
235  return NDN_ERROR_success;
236  }
237  else
238  return ndn_TlvDecoder_readExtendedNonNegativeInteger(self, length, value);
239 }
240 
250 static __inline ndn_Error
251 ndn_TlvDecoder_readNonNegativeIntegerTlv(struct ndn_TlvDecoder *self, unsigned int expectedType, uint64_t *value)
252 {
253  ndn_Error error;
254  size_t length;
255  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &length)))
256  return error;
257  if ((error = ndn_TlvDecoder_readNonNegativeInteger(self, length, value)))
258  return error;
259 
260  return NDN_ERROR_success;
261 }
262 
273 static __inline ndn_Error
274 ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv
275  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset,
276  int *value)
277 {
278  int gotExpectedType;
279  ndn_Error error;
280  uint64_t unsignedValue;
281 
282  if ((error = ndn_TlvDecoder_peekType
283  (self, expectedType, endOffset, &gotExpectedType)))
284  return error;
285 
286  if (!gotExpectedType) {
287  *value = -1;
288  return NDN_ERROR_success;
289  }
290 
291  if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv
292  (self, expectedType, &unsignedValue)))
293  return error;
294 
295  *value = (int)unsignedValue;
296  return NDN_ERROR_success;
297 }
298 
309 static __inline ndn_Error
310 ndn_TlvDecoder_readOptionalNonNegativeIntegerTlvAsDouble
311  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset,
312  double *value)
313 {
314  int gotExpectedType;
315  ndn_Error error;
316  uint64_t unsignedValue;
317 
318  if ((error = ndn_TlvDecoder_peekType
319  (self, expectedType, endOffset, &gotExpectedType)))
320  return error;
321 
322  if (!gotExpectedType) {
323  *value = -1;
324  return NDN_ERROR_success;
325  }
326 
327  if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv
328  (self, expectedType, &unsignedValue)))
329  return error;
330 
331  *value = (double)unsignedValue;
332  return NDN_ERROR_success;
333 }
334 
344 static __inline ndn_Error
345 ndn_TlvDecoder_readBlobTlv
346  (struct ndn_TlvDecoder *self, unsigned int expectedType, struct ndn_Blob *value)
347 {
348  ndn_Error error;
349  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &value->length)))
350  return error;
351 
352  // ndn_TlvDecoder_readTypeAndLength already checked if the value->length exceeds the input buffer.
353  value->value = self->input + self->offset;
354  self->offset += value->length;
355 
356  return NDN_ERROR_success;
357 }
358 
372 static __inline ndn_Error
373 ndn_TlvDecoder_readOptionalBlobTlv
374  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset,
375  struct ndn_Blob *value)
376 {
377  int gotExpectedType;
378  ndn_Error error;
379 
380  if ((error = ndn_TlvDecoder_peekType
381  (self, expectedType, endOffset, &gotExpectedType)))
382  return error;
383 
384  if (!gotExpectedType) {
385  value->value = 0;
386  value->length = 0;
387  return NDN_ERROR_success;
388  }
389 
390  if ((error = ndn_TlvDecoder_readBlobTlv(self, expectedType, value)))
391  return error;
392 
393  return NDN_ERROR_success;
394 }
395 
406 static __inline ndn_Error
407 ndn_TlvDecoder_readBooleanTlv
408  (struct ndn_TlvDecoder *self, unsigned int expectedType, size_t endOffset, int *value)
409 {
410  int gotExpectedType;
411  ndn_Error error;
412  if ((error = ndn_TlvDecoder_peekType(self, expectedType, endOffset, &gotExpectedType)))
413  return error;
414 
415  if (!gotExpectedType)
416  *value = 0;
417  else {
418  size_t length;
419  if ((error = ndn_TlvDecoder_readTypeAndLength(self, expectedType, &length)))
420  return error;
421  // We expect the length to be 0, but update offset anyway.
422  self->offset += length;
423 
424  *value = 1;
425  }
426 
427  return NDN_ERROR_success;
428 }
429 
435 static __inline void ndn_TlvDecoder_seek(struct ndn_TlvDecoder *self, size_t offset)
436 {
437  self->offset = offset;
438 }
439 
449 static __inline ndn_Error
450 ndn_TlvDecoder_getSlice
451  (struct ndn_TlvDecoder *self, size_t beginOffset, size_t endOffset,
452  struct ndn_Blob *slice)
453 {
454  if (beginOffset > self->inputLength || endOffset > self->inputLength)
455  return NDN_ERROR_read_past_the_end_of_the_input;
456 
457  slice->value = self->input + beginOffset;
458  if (beginOffset > endOffset)
459  // We don't expect this to happen.
460  slice->length = 0;
461  else
462  slice->length = endOffset - beginOffset;
463 
464  return NDN_ERROR_success;
465 }
466 
467 #ifdef __cplusplus
468 }
469 #endif
470 
471 #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-2016 Regents of the University of California.
Definition: blob-types.h:33
Copyright (C) 2014-2016 Regents of the University of California.
Definition: tlv-decoder.h:34