/** * Parse a ndnb-encoded Header */ struct ndn_header * ndn_header_parse(const unsigned char *p, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, p, size); struct ndn_header *result; const unsigned char *blob; size_t blobsize; int res = 0; result = calloc(1, sizeof(*result)); if (result == NULL) return (NULL); if (ndn_buf_match_dtag(d, NDN_DTAG_Header)) { ndn_buf_advance(d); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_Start, &result->start); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_Count, &result->count); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_BlockSize, &result->block_size); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_Length, &result->length); if (res != 0) { free(result); return (NULL); } if (ndn_buf_match_dtag(d, NDN_DTAG_ContentDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &blob, &blobsize)) { result->content_digest = ndn_charbuf_create(); ndn_charbuf_append(result->content_digest, blob, blobsize); ndn_buf_advance(d); } ndn_buf_check_close(d); } if (ndn_buf_match_dtag(d, NDN_DTAG_RootDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &blob, &blobsize)) { result->root_digest = ndn_charbuf_create(); ndn_charbuf_append(result->root_digest, blob, blobsize); ndn_buf_advance(d); } ndn_buf_check_close(d); } ndn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !NDN_FINAL_DSTATE(d->decoder.state)) { ndn_header_destroy(&result); } return (result); }
/** * Extract a pointer to and size of component at * given index i. The first component is index 0. * @returns 0, or -1 for error. */ int ndn_name_comp_get(const unsigned char *data, const struct ndn_indexbuf *indexbuf, unsigned int i, const unsigned char **comp, size_t *size) { int len; struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d; /* indexbuf should have an extra value marking end of last component, so we need to use last 2 values */ if (indexbuf->n < 2 || i > indexbuf->n - 2) { /* There isn't a component at this index */ return(-1); } len = indexbuf->buf[i + 1]-indexbuf->buf[i]; d = ndn_buf_decoder_start(&decoder, data + indexbuf->buf[i], len); if (ndn_buf_match_dtag(d, NDN_DTAG_Component)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, comp, size)) return(0); *comp = d->buf + d->decoder.index; *size = 0; ndn_buf_check_close(d); if (d->decoder.state >= 0) return(0); } return(-1); }
int ndn_uri_append(struct ndn_charbuf *c, const unsigned char *ndnb, size_t size, int flags) { int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, ndnb, size); if (ndn_buf_match_dtag(d, NDN_DTAG_Interest) || ndn_buf_match_dtag(d, NDN_DTAG_ContentObject)) { ndn_buf_advance(d); if (ndn_buf_match_dtag(d, NDN_DTAG_Signature)) ndn_buf_advance_past_element(d); } if (!ndn_buf_match_dtag(d, NDN_DTAG_Name)) return(-1); if (flags & NDN_URI_INCLUDESCHEME) ndn_charbuf_append_string(c, "ndn:"); ndn_buf_advance(d); while (ndn_buf_match_dtag(d, NDN_DTAG_Component)) { ndn_buf_advance(d); compsize = 0; if (ndn_buf_match_blob(d, &comp, &compsize)) ndn_buf_advance(d); ndn_buf_check_close(d); if (d->decoder.state < 0) return(d->decoder.state); ncomp += 1; ndn_charbuf_append(c, "/", 1); if ((flags & NDN_URI_ESCAPE_MASK) == 0) flags |= NDN_URI_DEFAULT_ESCAPE; if (flags & NDN_URI_MIXEDESCAPE) { ndn_uri_append_mixedescaped(c, comp, compsize); } else if (flags & NDN_URI_PERCENTESCAPE) ndn_uri_append_percentescaped(c, comp, compsize); } ndn_buf_check_close(d); if (d->decoder.state < 0) return (d->decoder.state); if (ncomp == 0) ndn_charbuf_append(c, "/", 1); return(ncomp); }
static int ndn_name_last_component_offset(const unsigned char *ndnb, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, ndnb, size); int res = -1; if (ndn_buf_match_dtag(d, NDN_DTAG_Name)) { ndn_buf_advance(d); res = d->decoder.token_index; /* in case of 0 components */ while (ndn_buf_match_dtag(d, NDN_DTAG_Component)) { res = d->decoder.token_index; ndn_buf_advance(d); if (ndn_buf_match_blob(d, NULL, NULL)) ndn_buf_advance(d); ndn_buf_check_close(d); } ndn_buf_check_close(d); } return ((d->decoder.state >= 0) ? res : -1); }
struct ndn_forwarding_entry * ndn_forwarding_entry_parse(const unsigned char *p, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, p, size); struct ndn_charbuf *store = ndn_charbuf_create(); struct ndn_forwarding_entry *result; const unsigned char *val; size_t sz; size_t start; size_t end; int action_off = -1; int ndnd_id_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ndn_charbuf_destroy(&store); return(NULL); } if (ndn_buf_match_dtag(d, NDN_DTAG_ForwardingEntry)) { ndn_buf_advance(d); action_off = ndn_parse_tagged_string(d, NDN_DTAG_Action, store); if (ndn_buf_match_dtag(d, NDN_DTAG_Name)) { result->name_prefix = ndn_charbuf_create(); start = d->decoder.token_index; ndn_parse_Name(d, NULL); end = d->decoder.token_index; ndn_charbuf_append(result->name_prefix, p + start, end - start); } else result->name_prefix = NULL; if (ndn_buf_match_dtag(d, NDN_DTAG_PublisherPublicKeyDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &val, &sz)) { ndn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ndn_buf_check_close(d); if (d->decoder.state >= 0) { ndnd_id_off = store->length; ndn_charbuf_append(store, val, sz); result->ndnd_id_size = sz; } } result->faceid = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FaceID); result->flags = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_ForwardingFlags); result->lifetime = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FreshnessSeconds); ndn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !NDN_FINAL_DSTATE(d->decoder.state) || store->length > sizeof(result->store)) ndn_forwarding_entry_destroy(&result); else { char *b = (char *)result->store; memcpy(b, store->buf, store->length); result->action = (action_off == -1) ? NULL : b + action_off; result->ndnd_id = (ndnd_id_off == -1) ? NULL : result->store + ndnd_id_off; } ndn_charbuf_destroy(&store); return(result); }
/** * Parse a ndnb-ecoded FaceInstance into an internal representation * * The space used for the various strings is held by the charbuf. * A client may replace the strings with other pointers, but then * assumes responsibilty for managing those pointers. * @returns pointer to newly allocated structure describing the face, or * NULL if there is an error. */ struct ndn_face_instance * ndn_face_instance_parse(const unsigned char *p, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, p, size); struct ndn_charbuf *store = ndn_charbuf_create(); struct ndn_face_instance *result; const unsigned char *val; size_t sz; int action_off = -1; int ndnd_id_off = -1; int host_off = -1; int port_off = -1; int mcast_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ndn_charbuf_destroy(&store); return(NULL); } result->store = store; if (ndn_buf_match_dtag(d, NDN_DTAG_FaceInstance)) { ndn_buf_advance(d); action_off = ndn_parse_tagged_string(d, NDN_DTAG_Action, store); if (ndn_buf_match_dtag(d, NDN_DTAG_PublisherPublicKeyDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &val, &sz)) { ndn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ndn_buf_check_close(d); if (d->decoder.state >= 0) { ndnd_id_off = store->length; ndn_charbuf_append(store, val, sz); result->ndnd_id_size = sz; } } result->faceid = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FaceID); result->descr.ipproto = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_IPProto); host_off = ndn_parse_tagged_string(d, NDN_DTAG_Host, store); port_off = ndn_parse_tagged_string(d, NDN_DTAG_Port, store); mcast_off = ndn_parse_tagged_string(d, NDN_DTAG_MulticastInterface, store); result->descr.mcast_ttl = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_MulticastTTL); result->lifetime = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FreshnessSeconds); ndn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !NDN_FINAL_DSTATE(d->decoder.state)) ndn_face_instance_destroy(&result); else { char *b = (char *)store->buf; result->action = (action_off == -1) ? NULL : b + action_off; result->ndnd_id = (ndnd_id_off == -1) ? NULL : store->buf + ndnd_id_off; result->descr.address = (host_off == -1) ? NULL : b + host_off; result->descr.port = (port_off == -1) ? NULL : b + port_off; result->descr.source_address = (mcast_off == -1) ? NULL : b + mcast_off; } return(result); }