/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
 */

#include <string.h>
#include <stdlib.h>
#include "ccn.h"
#include "ccn_charbuf.h"
#include "ccn_coding.h"
#include "ccn_indexbuf.h"


struct ccn_buf_decoder *
ccn_buf_decoder_start(struct ccn_buf_decoder *d,
                      const unsigned char *buf, size_t size)
{
  memset(&d->decoder, 0, sizeof(d->decoder));
  d->decoder.state |= CCN_DSTATE_PAUSE;
  d->buf = buf;
  d->size = size;
  ccn_skeleton_decode(&d->decoder, buf, size);
  return(d);
}

void
ccn_buf_advance(struct ccn_buf_decoder *d)
{
  ccn_skeleton_decode(&d->decoder,
                      d->buf + d->decoder.index,
                      d->size - d->decoder.index);
}

int
ccn_buf_match_dtag(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
{
  return (d->decoder.state >= 0 &&
          CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG &&
          (int)d->decoder.numval == dtag);
}

int
ccn_buf_match_some_dtag(struct ccn_buf_decoder *d)
{
  return(d->decoder.state >= 0 &&
         CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG);
}

int
ccn_buf_match_some_blob(struct ccn_buf_decoder *d)
{
  return(d->decoder.state >= 0 &&
         CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB);
}

int
ccn_buf_match_blob(struct ccn_buf_decoder *d,
                   const unsigned char **bufp, size_t *sizep)
{
  if (ccn_buf_match_some_blob(d)) {
    if (bufp != NULL)
      *bufp = d->buf + d->decoder.index;
    if (sizep != NULL)
      *sizep = d->decoder.numval;
    return (1);
  }
  if (bufp != NULL)
    *bufp = d->buf + d->decoder.token_index;
  if (sizep != NULL)
    *sizep = 0;
  return(0);
}

int
ccn_buf_match_udata(struct ccn_buf_decoder *d, const char *s)
{
  size_t len = strlen(s);
  return (d->decoder.state >= 0 &&
          CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA &&
          d->decoder.numval == len &&
          0 == memcmp(d->buf + d->decoder.index, s, len));
}

int
ccn_buf_match_attr(struct ccn_buf_decoder *d, const char *s)
{
  size_t len = strlen(s);
  return (d->decoder.state >= 0 &&
          CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_ATTR &&
          d->decoder.numval == len &&
          0 == memcmp(d->buf + d->decoder.index, s, len));
}

void
ccn_buf_check_close(struct ccn_buf_decoder *d)
{
  if (d->decoder.state >= 0) {
    if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) != CCN_NO_TOKEN)
      d->decoder.state = CCN_DSTATE_ERR_NEST;
    else
      ccn_buf_advance(d);
  }
}

int
ccn_buf_advance_past_element(struct ccn_buf_decoder *d)
{
  enum ccn_tt tt;
  int nest;
  if (d->decoder.state < 0)
    return(d->decoder.state);
  tt = (ccn_tt)CCN_GET_TT_FROM_DSTATE(d->decoder.state);
  if (tt == CCN_DTAG || tt == CCN_TAG) {
    nest = d->decoder.nest;
    ccn_buf_advance(d);
    while (d->decoder.state >= 0 && d->decoder.nest >= nest)
      ccn_buf_advance(d);
    /* The nest decrements before the closer is consumed */
    ccn_buf_check_close(d);
  }
  else
    return(-1);
  if (d->decoder.state < 0)
    return(d->decoder.state);
  return (0);
}

int
ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
                               int minlen, int maxlen)
{
  int res = -1;
  size_t len = 0;
  if (ccn_buf_match_dtag(d, dtag)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    if (ccn_buf_match_some_blob(d)) {
      len = d->decoder.numval;
      ccn_buf_advance(d);
    }
    ccn_buf_check_close(d);
    if ((int)len < minlen || (maxlen >= 0 && (int)len > maxlen)) {
      d->decoder.state = -__LINE__;
    }
  }
  else
    d->decoder.state = -__LINE__;
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(res);
}

int
ccn_parse_optional_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
                               int minlen, int maxlen)
{
  if (ccn_buf_match_dtag(d, dtag))
    return(ccn_parse_required_tagged_BLOB(d, dtag, minlen, maxlen));
  return(-1);
}

uintmax_t
ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d,
                                        enum ccn_dtag dtag,
                                        int minlen, int maxlen)
{
  uintmax_t value = 0;
  const unsigned char *p = NULL;
  size_t len = 0;
  int i;
  if (0 <= minlen && minlen <= maxlen && maxlen <= (int)sizeof(value) &&
      ccn_buf_match_dtag(d, dtag)) {
    ccn_buf_advance(d);
    if (ccn_buf_match_blob(d, &p, &len))
      ccn_buf_advance(d);
    ccn_buf_check_close(d);
    if (d->decoder.state < 0)
      return(value);
    if (minlen <= (int)len && (int)len <= maxlen)
      for (i = 0; i < (int)len; i++)
        value = (value << 8) + p[i];
    else
      d->decoder.state = -__LINE__;
  }
  else
    d->decoder.state = -__LINE__;
  return(value);
}

uintmax_t
ccn_parse_optional_tagged_binary_number(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
                                        int minlen, int maxlen, uintmax_t default_value)
{
  if (ccn_buf_match_dtag(d, dtag))
    return(ccn_parse_required_tagged_binary_number(d, dtag, minlen, maxlen));
  return(default_value);
}

int
ccn_parse_required_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
{
  int res = -1;
  if (ccn_buf_match_dtag(d, dtag)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    if (d->decoder.state >= 0 &&
        CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA)
      ccn_buf_advance(d);
    else
      d->decoder.state = -__LINE__;
    ccn_buf_check_close(d);
  }
  else
    d->decoder.state = -__LINE__;
  if (d->decoder.state < 0)
    return (-1);
  return(res);
}

int
ccn_parse_optional_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
{
  if (ccn_buf_match_dtag(d, dtag))
    return(ccn_parse_required_tagged_UDATA(d, dtag));
  return(-1);
}

/**
 * Parses a ccnb-encoded element expected to contain a UDATA string.
 * @param d is the decoder
 * @param dtag is the expected dtag value
 * @param store - on success, the string value is appended to store,
 *        with null termination.
 * @returns the offset into the store buffer of the copied value, or -1 for error.
 *        If a parse error occurs, d->decoder.state is set to a negative value.
 *        If the element is not present, -1 is returned but no parse error
 *        is indicated.
 */
int
ccn_parse_tagged_string(struct ccn_buf_decoder *d, enum ccn_dtag dtag, struct ccn_charbuf *store)
{
  const unsigned char *p = NULL;
  size_t size = 0;
  int res;
  
  if (ccn_buf_match_dtag(d, dtag)) {
    ccn_buf_advance(d);
    if (d->decoder.state >= 0 &&
        CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
      res = store->length;
      p = d->buf + d->decoder.index;
      size = d->decoder.numval;
      ccn_buf_advance(d);
    }
    ccn_buf_check_close(d);
    if (d->decoder.state >= 0) {
      // XXX - should check for valid utf-8 data.
      res = store->length;
      if (size > 0)
        ccn_charbuf_append(store, p, size);
      ccn_charbuf_append_value(store, 0, 1);
      return(res);
    }
  }
  return(-1);
}

/**
 * Parses a ccnb-encoded name
 * @param d is the decoder
 * @param components may be NULL, otherwise is filled in with the 
 *        Component boundary offsets
 * @returns the number of Components in the Name, or -1 if there is an error.
 */
int
ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components)
{
  int ncomp = 0;
  if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
    if (components != NULL) components->n = 0;
    ccn_buf_advance(d);
    while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
      if (components != NULL)
        ccn_indexbuf_append_element(components, d->decoder.token_index);
      ncomp += 1;
      ccn_buf_advance(d);
      if (ccn_buf_match_blob(d, NULL, NULL))
        ccn_buf_advance(d);
      ccn_buf_check_close(d);
    }
    if (components != NULL)
      ccn_indexbuf_append_element(components, d->decoder.token_index);
    ccn_buf_check_close(d);
  }
  else
    d->decoder.state = -__LINE__;
  if (d->decoder.state < 0)
    return(-1);
  else
    return(ncomp);
}

int
ccn_parse_PublisherID(struct ccn_buf_decoder *d, struct ccn_parsed_interest *pi)
{
  int res = -1;
  int iskey = 0;
  unsigned pubstart = d->decoder.token_index;
  unsigned keystart = pubstart;
  unsigned keyend = pubstart;
  unsigned pubend = pubstart;
  iskey = ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest);
  if (iskey                                                          ||
      ccn_buf_match_dtag(d, CCN_DTAG_PublisherCertificateDigest)     ||
      ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerKeyDigest)       ||
      ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerCertificateDigest)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    keystart = d->decoder.token_index;
    if (!ccn_buf_match_some_blob(d))
      return (d->decoder.state = -__LINE__);
    ccn_buf_advance(d);
    keyend = d->decoder.token_index;
    ccn_buf_check_close(d);
    pubend = d->decoder.token_index;
  }
  if (d->decoder.state < 0)
    return (d->decoder.state);
  if (pi != NULL) {
    pi->offset[CCN_PI_B_PublisherID] = pubstart;
    pi->offset[CCN_PI_B_PublisherIDKeyDigest] = keystart;
    pi->offset[CCN_PI_E_PublisherIDKeyDigest] = iskey ? keyend : keystart;
    pi->offset[CCN_PI_E_PublisherID] = pubend;
  }
  return(res);
}

static int
ccn_parse_optional_Any_or_Bloom(struct ccn_buf_decoder *d)
{
  int res;
  res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Bloom, 1, 1024+8);
  if (res >= 0)
    return(res);
  if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
    ccn_buf_advance(d);
    ccn_buf_check_close(d);
    res = 0;
  }
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(res);
}

int
ccn_parse_Exclude(struct ccn_buf_decoder *d)
{
  int res = -1;
  if (ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    ccn_parse_optional_Any_or_Bloom(d);
    while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
      ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1);
      ccn_parse_optional_Any_or_Bloom(d);
    }
    ccn_buf_check_close(d);
  }
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(res);
}



int
ccn_parse_nonNegativeInteger(struct ccn_buf_decoder *d)
{
  const unsigned char *p;
  int i;
  int n;
  int val;
  int newval;
  unsigned char c;
  if (d->decoder.state < 0)
    return(d->decoder.state);
  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
    p = d->buf + d->decoder.index;
    n = d->decoder.numval;
    if (n < 1)
      return(d->decoder.state = -__LINE__);
    val = 0;
    for (i = 0; i < n; i++) {
      c = p[i];
      if ('0' <= c && c <= '9') {
        newval = val * 10 + (c - '0');
        if (newval < val)
          return(d->decoder.state = -__LINE__);
        val = newval;
      }
      else
        return(d->decoder.state = -__LINE__);
    }
    ccn_buf_advance(d);
    return(val);
  }
  return(d->decoder.state = -__LINE__);
}

/**
 * Parse a potentially large non-negative integer.
 *
 * @returns 0 for success, and the value is place in *result; for an error
 * a negative value is returned and *result is unchanged.
 */
int
ccn_parse_uintmax(struct ccn_buf_decoder *d, uintmax_t *result)
{
  const unsigned char *p;
  int i;
  int n;
  uintmax_t val;
  uintmax_t newval;
  unsigned char c;
  if (d->decoder.state < 0)
    return(d->decoder.state);
  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
    p = d->buf + d->decoder.index;
    n = d->decoder.numval;
    if (n < 1)
      return(d->decoder.state = -__LINE__);
    val = 0;
    for (i = 0; i < n; i++) {
      c = p[i];
      if ('0' <= c && c <= '9') {
        newval = val * 10 + (c - '0');
        if (newval < val)
          return(d->decoder.state = -__LINE__);
        val = newval;
      }
      else
        return(d->decoder.state = -__LINE__);
    }
    ccn_buf_advance(d);
    *result = val;
    return(0);
  }
  return(d->decoder.state = -__LINE__);
}

int
ccn_parse_timestamp(struct ccn_buf_decoder *d)
{
  const unsigned char dlm[] = "--T::.Z";
  const unsigned char *p;
  int i;
  int k;
  int n;
  if (d->decoder.state < 0)
    return(d->decoder.state);
  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB) {
    /* New-style binary timestamp, 12-bit fraction */
    n = d->decoder.numval;
    if (n < 3 || n > 7)
      return(d->decoder.state = -__LINE__);
    ccn_buf_advance(d);
    return(0);
  }
  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
    /* This is for some temporary back-compatibility */
    p = d->buf + d->decoder.index;
    n = d->decoder.numval;
    if (n < 8 || n > 40)
      return(d->decoder.state = -__LINE__);
    if (p[n - 1] != 'Z')
      return(d->decoder.state = -__LINE__);
    for (i = 0, k = 0; i < n && '0' <= p[i] && p[i] <= '9';) {
      i++;
      if (i < n && p[i] == dlm[k]) {
        if (dlm[k++] == 0)
          return(d->decoder.state = -__LINE__);
        i++;
      }
    }
    if (k < 5)
      return(d->decoder.state = -__LINE__);
    if (!(i == n || i == n - 1))
      return(d->decoder.state = -__LINE__);
    ccn_buf_advance(d);
    return(0);
  }
  return(d->decoder.state = -__LINE__);
}

int
ccn_parse_required_tagged_timestamp(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
{
  int res = -1;
  if (ccn_buf_match_dtag(d, dtag)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    ccn_parse_timestamp(d);
    ccn_buf_check_close(d);
  }
  else
    d->decoder.state = -__LINE__;
  if (d->decoder.state < 0)
    return (-1);
  return(res);
}

int
ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
{
  int res = -1;
  if (ccn_buf_match_dtag(d, dtag)) {
    ccn_buf_advance(d);
    res = ccn_parse_nonNegativeInteger(d);
    ccn_buf_check_close(d);
  }
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(res);
}

int
ccn_fetch_tagged_nonNegativeInteger(enum ccn_dtag tt,
                                    const unsigned char *buf,
                                    size_t start, size_t stop)
{
  struct ccn_buf_decoder decoder;
  struct ccn_buf_decoder *d;
  int result = -1;
  if (stop < start) return(-1);
  d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
  if (ccn_buf_match_dtag(d, tt)) {
    ccn_buf_advance(d);
    result = ccn_parse_nonNegativeInteger(d);
    ccn_buf_check_close(d);
  }
  if (result < 0)
    return(-1);
  return(result);
}


int
ccn_parse_interest(const unsigned char *msg, size_t size,
                   struct ccn_parsed_interest *interest,
                   struct ccn_indexbuf *components)
{
  struct ccn_buf_decoder decoder;
  struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
  int magic = 0;
  int ncomp = 0;
  int res;
  if (ccn_buf_match_dtag(d, CCN_DTAG_Interest)) {
    if (components == NULL) {
      /* We need to have the component offsets. */
      components = ccn_indexbuf_create();
      if (components == NULL) return(-1);
      res = ccn_parse_interest(msg, size, interest, components);
      ccn_indexbuf_destroy(&components);
      return(res);
    }
    ccn_buf_advance(d);
    interest->offset[CCN_PI_B_Name] = d->decoder.element_index;
    interest->offset[CCN_PI_B_Component0] = d->decoder.index;
    ncomp = ccn_parse_Name(d, components);
    if (d->decoder.state < 0) {
      memset(interest->offset, 0, sizeof(interest->offset));
      return(d->decoder.state);
    }
    interest->offset[CCN_PI_E_ComponentLast] = d->decoder.token_index - 1;
    interest->offset[CCN_PI_E_Name] = d->decoder.token_index;
    interest->prefix_comps = ncomp;
    interest->offset[CCN_PI_B_LastPrefixComponent] = components->buf[(ncomp > 0) ? (ncomp - 1) : 0];
    interest->offset[CCN_PI_E_LastPrefixComponent] = components->buf[ncomp];
    /* optional MinSuffixComponents, MaxSuffixComponents */
    interest->min_suffix_comps = 0;
    interest->max_suffix_comps = 32767;
    interest->offset[CCN_PI_B_MinSuffixComponents] = d->decoder.token_index;
    res = ccn_parse_optional_tagged_nonNegativeInteger(d,
                                                       CCN_DTAG_MinSuffixComponents);
    interest->offset[CCN_PI_E_MinSuffixComponents] = d->decoder.token_index;
    if (res >= 0)
      interest->min_suffix_comps = res;
    interest->offset[CCN_PI_B_MaxSuffixComponents] = d->decoder.token_index;
    res = ccn_parse_optional_tagged_nonNegativeInteger(d,
                                                       CCN_DTAG_MaxSuffixComponents);
    interest->offset[CCN_PI_E_MaxSuffixComponents] = d->decoder.token_index;
    if (res >= 0)
      interest->max_suffix_comps = res;
    if (interest->max_suffix_comps < interest->min_suffix_comps)
      return (d->decoder.state = -__LINE__);
    /* optional PublisherID */
    res = ccn_parse_PublisherID(d, interest);
    /* optional Exclude element */
    interest->offset[CCN_PI_B_Exclude] = d->decoder.token_index;
    res = ccn_parse_Exclude(d);
    interest->offset[CCN_PI_E_Exclude] = d->decoder.token_index;
    /* optional ChildSelector */
    interest->offset[CCN_PI_B_ChildSelector] = d->decoder.token_index;
    res = ccn_parse_optional_tagged_nonNegativeInteger(d,
                                                       CCN_DTAG_ChildSelector);
    if (res < 0)
      res = 0;
    interest->orderpref = res;
    interest->offset[CCN_PI_E_ChildSelector] = d->decoder.token_index;
    if (interest->orderpref > 5)
      return (d->decoder.state = -__LINE__);        
    /* optional AnswerOriginKind */
    interest->offset[CCN_PI_B_AnswerOriginKind] = d->decoder.token_index;
    interest->answerfrom = ccn_parse_optional_tagged_nonNegativeInteger(d,
                                                                        CCN_DTAG_AnswerOriginKind);
    interest->offset[CCN_PI_E_AnswerOriginKind] = d->decoder.token_index;
    if (interest->answerfrom == -1)
      interest->answerfrom = CCN_AOK_DEFAULT;
    else if ((interest->answerfrom & CCN_AOK_NEW) != 0 &&
             (interest->answerfrom & CCN_AOK_CS) == 0)
      return (d->decoder.state = -__LINE__);
    /* optional Scope */
    interest->offset[CCN_PI_B_Scope] = d->decoder.token_index;
    interest->scope = ccn_parse_optional_tagged_nonNegativeInteger(d,
                                                                   CCN_DTAG_Scope);
    interest->offset[CCN_PI_E_Scope] = d->decoder.token_index;
    if (interest->scope > 9)
      return (d->decoder.state = -__LINE__);
    if ((interest->answerfrom & CCN_AOK_EXPIRE) != 0 &&
        interest->scope != 0)
      return (d->decoder.state = -__LINE__);
    /* optional InterestLifetime */
    interest->offset[CCN_PI_B_InterestLifetime] = d->decoder.token_index;
    res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_InterestLifetime, 1, 8);
    if (res >= 0)
      magic |= 20100401;
    interest->offset[CCN_PI_E_InterestLifetime] = d->decoder.token_index;
    /* optional Nonce */
    interest->offset[CCN_PI_B_Nonce] = d->decoder.token_index;
    res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Nonce, 4, 64);
    interest->offset[CCN_PI_E_Nonce] = d->decoder.token_index;
    /* Allow for no experimental stuff */
    interest->offset[CCN_PI_B_OTHER] = d->decoder.token_index;
    interest->offset[CCN_PI_E_OTHER] = d->decoder.token_index;
    ccn_buf_check_close(d);
    interest->offset[CCN_PI_E] = d->decoder.index;
  }
  else
    return (d->decoder.state = -__LINE__);
  if (d->decoder.state < 0)
    return (d->decoder.state);
  if (d->decoder.index != (int)size || !CCN_FINAL_DSTATE(d->decoder.state))
    return (CCN_DSTATE_ERR_CODING);
  if (magic == 0)
    magic = 20090701;
  if (!(magic == 20090701 || magic == 20100401))
    return (d->decoder.state = -__LINE__);
  interest->magic = magic;
  return (ncomp);
}

struct parsed_KeyName {
  int Name;
  int endName;
  int PublisherID;
  int endPublisherID;
};

static int
ccn_parse_KeyName(struct ccn_buf_decoder *d, struct parsed_KeyName *x)
{
  int res = -1;
  if (ccn_buf_match_dtag(d, CCN_DTAG_KeyName)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    x->Name = d->decoder.token_index;
    ccn_parse_Name(d, NULL);
    x->endName = d->decoder.token_index;
    x->PublisherID = ccn_parse_PublisherID(d, NULL);
    x->endPublisherID = d->decoder.token_index;
    ccn_buf_check_close(d);
  }
  else
    d->decoder.state = -__LINE__;
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(res);
}

static int
ccn_parse_Signature(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
{
  int res = -1;
  int i;
  struct ccn_parsed_ContentObject dummy;
  if (x == NULL)
    x = &dummy;
  for (i = CCN_PCO_B_Signature; i <= CCN_PCO_E_Signature; i++) {
    x->offset[i] = d->decoder.token_index;
  }
  if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) {
    res = d->decoder.element_index;
    ccn_buf_advance(d);
    x->offset[CCN_PCO_B_DigestAlgorithm] = d->decoder.token_index;
    ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_DigestAlgorithm);
    x->offset[CCN_PCO_E_DigestAlgorithm] = d->decoder.token_index;
    x->offset[CCN_PCO_B_Witness] = d->decoder.token_index;
    ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 8, -1);
    x->offset[CCN_PCO_E_Witness] = d->decoder.token_index;
    x->offset[CCN_PCO_B_SignatureBits] = d->decoder.token_index;
    ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 16, -1);
    x->offset[CCN_PCO_E_SignatureBits] = d->decoder.token_index;
    ccn_buf_check_close(d);
    x->offset[CCN_PCO_E_Signature] = d->decoder.token_index;
  }
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(res);
}

static int
ccn_parse_SignedInfo(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
{
  x->offset[CCN_PCO_B_SignedInfo] = d->decoder.token_index;
  if (ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) {
    ccn_buf_advance(d);
    x->offset[CCN_PCO_B_PublisherPublicKeyDigest] = d->decoder.token_index;
    ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64);
    x->offset[CCN_PCO_E_PublisherPublicKeyDigest] = d->decoder.token_index;
    
    x->offset[CCN_PCO_B_Timestamp] = d->decoder.token_index;
    ccn_parse_required_tagged_timestamp(d, CCN_DTAG_Timestamp);
    x->offset[CCN_PCO_E_Timestamp] = d->decoder.token_index;
    
    x->offset[CCN_PCO_B_Type] = d->decoder.token_index;
    x->type = CCN_CONTENT_DATA;
    x->type = (ccn_content_type)ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA);
    x->offset[CCN_PCO_E_Type] = d->decoder.token_index;
    
    x->offset[CCN_PCO_B_FreshnessSeconds] = d->decoder.token_index;
    ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
    x->offset[CCN_PCO_E_FreshnessSeconds] = d->decoder.token_index;
    
    x->offset[CCN_PCO_B_FinalBlockID] = d->decoder.token_index;
    ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1);
    x->offset[CCN_PCO_E_FinalBlockID] = d->decoder.token_index;
    
    x->offset[CCN_PCO_B_KeyLocator] = d->decoder.token_index;
    x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
    x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
    x->offset[CCN_PCO_B_KeyName_Name] = d->decoder.token_index;
    x->offset[CCN_PCO_E_KeyName_Name] = d->decoder.token_index;
    x->offset[CCN_PCO_B_KeyName_Pub] = d->decoder.token_index;
    x->offset[CCN_PCO_E_KeyName_Pub] = d->decoder.token_index;
    if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) {
      ccn_buf_advance(d);
      x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
      if (ccn_buf_match_dtag(d, CCN_DTAG_Key)) {
        (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Key, 0, -1);
      }
      else if (ccn_buf_match_dtag(d, CCN_DTAG_Certificate)) {
        (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Certificate, 0, -1);
      }
      else {
        struct parsed_KeyName keyname = {-1, -1, -1, -1};
        if (ccn_parse_KeyName(d, &keyname) >= 0) {
          if (keyname.Name >= 0) {
            x->offset[CCN_PCO_B_KeyName_Name] = keyname.Name;
            x->offset[CCN_PCO_E_KeyName_Name] = keyname.endName;
          }
          if (keyname.PublisherID >= 0) {
            x->offset[CCN_PCO_B_KeyName_Pub] = keyname.PublisherID;
            x->offset[CCN_PCO_E_KeyName_Pub] = keyname.endPublisherID;
          }
        }
      }
      x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
      ccn_buf_check_close(d);
    }
    x->offset[CCN_PCO_E_KeyLocator] = d->decoder.token_index;
    ccn_buf_check_close(d);
  }
  else
    d->decoder.state = -__LINE__;
  x->offset[CCN_PCO_E_SignedInfo] = d->decoder.token_index;
  if (d->decoder.state < 0)
    return (d->decoder.state);
  return(0);
}

int
ccn_parse_ContentObject(const unsigned char *msg, size_t size,
                        struct ccn_parsed_ContentObject *x,
                        struct ccn_indexbuf *components)
{
  struct ccn_buf_decoder decoder;
  struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
  int res;
  x->magic = 20090415;
  x->digest_bytes = 0;
  if (ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) {
    ccn_buf_advance(d);
    res = ccn_parse_Signature(d, x);
    x->offset[CCN_PCO_B_Name] = d->decoder.token_index;
    x->offset[CCN_PCO_B_Component0] = d->decoder.index;
    res = ccn_parse_Name(d, components);
    if (res < 0)
      d->decoder.state = -__LINE__;
    x->name_ncomps = res;
    x->offset[CCN_PCO_E_ComponentLast] = d->decoder.token_index - 1;
    x->offset[CCN_PCO_E_Name] = d->decoder.token_index;
    ccn_parse_SignedInfo(d, x);
    x->offset[CCN_PCO_B_Content] = d->decoder.token_index;
    ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Content, 0, -1);
    x->offset[CCN_PCO_E_Content] = d->decoder.token_index;
    ccn_buf_check_close(d);
    x->offset[CCN_PCO_E] = d->decoder.index;
  }
  else
    d->decoder.state = -__LINE__;
  if (d->decoder.index != (int)size || !CCN_FINAL_DSTATE(d->decoder.state))
    return (CCN_DSTATE_ERR_CODING);
  return(0);
}

int
ccn_ref_tagged_BLOB(enum ccn_dtag tt,
                    const unsigned char *buf, size_t start, size_t stop,
                    const unsigned char **presult, size_t *psize)
{
  struct ccn_buf_decoder decoder;
  struct ccn_buf_decoder *d;
  if (stop < start) return(-1);
  d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
  if (ccn_buf_match_dtag(d, tt)) {
    ccn_buf_advance(d);
    if (ccn_buf_match_blob(d, presult, psize))
      ccn_buf_advance(d);
    ccn_buf_check_close(d);
  }
  else
    return(-1);
  if (d->decoder.index != (int)d->size || !CCN_FINAL_DSTATE(d->decoder.state))
    return (CCN_DSTATE_ERR_CODING);
  return(0);
}

static struct ccn_buf_decoder *
ccn_buf_decoder_start_at_components(struct ccn_buf_decoder *d,
                                    const unsigned char *buf, size_t buflen)
{
  ccn_buf_decoder_start(d, buf, buflen);
  while (ccn_buf_match_dtag(d, CCN_DTAG_Name) ||
         ccn_buf_match_dtag(d, CCN_DTAG_Interest) ||
         ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)
         ) {
    ccn_buf_advance(d);
    ccn_parse_Signature(d, NULL);
  }
  return(d);
}

int
ccn_content_get_value(const unsigned char *data, size_t data_size,
                      const struct ccn_parsed_ContentObject *content,
                      const unsigned char **value, size_t *value_size)
{
  int res;
  res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, data,
                            content->offset[CCN_PCO_B_Content],
                            content->offset[CCN_PCO_E_Content],
                            value, value_size);
  return(res);
}

int
ccn_compare_names(const unsigned char *a, size_t asize,
                  const unsigned char *b, size_t bsize)
{
  struct ccn_buf_decoder a_decoder;
  struct ccn_buf_decoder b_decoder;
  struct ccn_buf_decoder *aa =
  ccn_buf_decoder_start_at_components(&a_decoder, a, asize);
  struct ccn_buf_decoder *bb =
  ccn_buf_decoder_start_at_components(&b_decoder, b, bsize);
  const unsigned char *acp = NULL;
  const unsigned char *bcp = NULL;
  size_t acsize;
  size_t bcsize;
  int cmp = 0;
  int more_a;
  for (;;) {
    more_a = ccn_buf_match_dtag(aa, CCN_DTAG_Component);
    cmp = more_a - ccn_buf_match_dtag(bb, CCN_DTAG_Component);
    if (more_a == 0 || cmp != 0)
      break;
    ccn_buf_advance(aa);
    ccn_buf_advance(bb);
    acsize = bcsize = 0;
    if (ccn_buf_match_blob(aa, &acp, &acsize))
      ccn_buf_advance(aa);
    if (ccn_buf_match_blob(bb, &bcp, &bcsize))
      ccn_buf_advance(bb);
    cmp = acsize - bcsize;
    if (cmp != 0)
      break;
    cmp = memcmp(acp, bcp, acsize);
    if (cmp != 0)
      break;
    ccn_buf_check_close(aa);
    ccn_buf_check_close(bb);
  }
  return (cmp);
}

