/*
 *  ccn_buf_decoder.cc
 *  Abstraction
 *
 *  Created by Ilya on 7/29/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

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

/**
 * @file ccn_buf_decoder.c
 * @brief Support for Interest and ContentObject decoding.
 * 
 * Part of the CCNx C Library.
 *
 * Copyright (C) 2008, 2009, 2010 Palo Alto Research Center, Inc.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation.
 * This library 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
 * Lesser General Public License for more details. You should have received
 * a copy of the GNU Lesser General Public License along with this library;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301 USA.
 */


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);
}

