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

#include "ccn_coding.h"

/**
 * @file ccn_coding.c
 * @brief Support for scanning and parsing ccnb-encoded data.
 * 
 * Part of the CCNx C Library.
 *
 * Copyright (C) 2008, 2009 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.
 */
//#include <ccn/coding.h>

/**
 * This macro documents what's happening in the state machine by
 * hinting at the XML syntax would be emitted in a re-encoder.
 * But it actually does nothing.
 */
#define XML(goop) ((void)0)

/**
 * Decodes ccnb decoded data
 *
 * @param d holds the current state of the decoder.
 * @param p points to a new block of ccnb data to feed to the decoder.
 * @param n is the size of the input, in bytes.
 * @returns the number of bytes consumed.
 *
 * The client should ensure that the decoder is initialized to all zero
 * before the first call.  In the default mode, the decoder will return
 * only when it runs out of data, encounters an error, or reaches the end
 * of the element that it started at.  This is a good way to pull
 * ccnb-encoded objects from a byte stream.
 *
 * By setting the CCN_DSTATE_PAUSE bit is set in the decoder state, the
 * decoder will additionally return just after recognizing each token.
 * In this instance, use CCN_GET_TT_FROM_DSTATE() to extract
 * the token type from the decoder state;
 * CCN_CLOSE will be reported as CCN_NO_TOKEN.
 *
 * The pause bit persists, so the end test should take that into account
 * by using the CCN_FINAL_DSTATE() macro instead of testing for state 0.
 *
 * Once an error state is entered, no addition input is processed.
 *
 * @see ccn_buf_decoder_start(), ccn_buf_advance(), ccn_buf_check_close()
 */
ssize_t
ccn_skeleton_decode(struct ccn_skeleton_decoder *d,
                    const unsigned char *p, size_t n)
{
  enum ccn_decoder_state state = (ccn_decoder_state)(d->state);
  int tagstate = 0;
  size_t numval = d->numval;
  ssize_t i = 0;
  unsigned char c;
  size_t chunk;
  int pause = 0;
  if (d->state >= 0) {
    pause = d->state & CCN_DSTATE_PAUSE;
    tagstate = (d->state >> 8) & 3;
    state = (ccn_decoder_state)(d->state & 0xFF);
  }
  while (i < (ssize_t)n) {
    switch (state) {
      case CCN_DSTATE_INITIAL:
      case CCN_DSTATE_NEWTOKEN: /* start new thing */
        d->token_index = i + d->index;
        if (tagstate > 1 && tagstate-- == 2) {
          XML("\""); /* close off the attribute value */
        } 
        if (p[i] == CCN_CLOSE) {
          i++;
          if (d->nest <= 0 || tagstate > 1) {
            state = CCN_DSTATE_ERR_NEST;
            break;
          }
          if (tagstate == 1) {
            tagstate = 0;
            XML("/>");
          }
          else {
            XML("</%s>");
          }
          d->nest -= 1;
          if (d->nest == 0) {
            state = CCN_DSTATE_INITIAL;
            n = i;
          }
          if (pause) {
            int temp = (int)state;
            //state |= (((int)CCN_NO_TOKEN) << 16);
            temp |= (((int)CCN_NO_TOKEN) << 16);
            state = (ccn_decoder_state)temp;
            n = i;
          }
          break;
        }
        numval = 0;
        state = CCN_DSTATE_NUMVAL;
        /* FALLTHRU */
      case CCN_DSTATE_NUMVAL: /* parsing numval */
        c = p[i++];
        if ((c & CCN_TT_HBIT) == CCN_CLOSE) {
          if (numval > ((~(size_t)0U) >> (7 + CCN_TT_BITS)))
            state = CCN_DSTATE_ERR_OVERFLOW;
          numval = (numval << 7) + (c & 127);
        }
        else {
          numval = (numval << (7-CCN_TT_BITS)) +
          ((c >> CCN_TT_BITS) & CCN_MAX_TINY);
          c &= CCN_TT_MASK;
          switch (c) {
            case CCN_EXT:
              if (tagstate == 1) {
                tagstate = 0;
                XML(">");
              }
              d->nest += 1;
              d->element_index = d->token_index;
              state = CCN_DSTATE_NEWTOKEN;
              break;
            case CCN_DTAG:
              if (tagstate == 1) {
                tagstate = 0;
                XML(">");
              }
              d->nest += 1;
              d->element_index = d->token_index;
              XML("<%s");
              tagstate = 1;
              state = CCN_DSTATE_NEWTOKEN;
              break;
            case CCN_BLOB:
              if (tagstate == 1) {
                tagstate = 0;
                XML(" ccnbencoding=\"base64Binary\">");
              }
              state = CCN_DSTATE_BLOB;
              if (numval == 0)
                state = CCN_DSTATE_NEWTOKEN;
              break;
            case CCN_UDATA:
              if (tagstate == 1) {
                tagstate = 0;
                XML(">");
              }
              state = CCN_DSTATE_UDATA;
              if (numval == 0)
                state = CCN_DSTATE_NEWTOKEN;
              break;
            case CCN_DATTR:
              if (tagstate != 1) {
                state = CCN_DSTATE_ERR_ATTR;
                break;
              }
              tagstate = 3;
              state = CCN_DSTATE_NEWTOKEN;
              break;
            case CCN_ATTR:
              if (tagstate != 1) {
                state = CCN_DSTATE_ERR_ATTR;
                break;
              }
              numval += 1; /* encoded as length-1 */
              state = CCN_DSTATE_ATTRNAME;
              break;
            case CCN_TAG:
              if (tagstate == 1) {
                tagstate = 0;
                XML(">");
              }
              numval += 1; /* encoded as length-1 */
              d->nest += 1;
              d->element_index = d->token_index;
              state = CCN_DSTATE_TAGNAME;
              break;
            default:
              state = CCN_DSTATE_ERR_CODING;
          }
          if (pause) {
            int temp = (int)state;
            //state |= (c << 16);
            temp |= (c << 16);
            state = (ccn_decoder_state)temp;
            n = i;
          }
        }
        break;
      case CCN_DSTATE_TAGNAME: /* parsing tag name */
        chunk = n - i;
        if (chunk > numval)
          chunk = numval;
        if (chunk == 0) {
          state = CCN_DSTATE_ERR_BUG;
          break;
        }
        numval -= chunk;
        i += chunk;
        if (numval == 0) {
          if (d->nest == 0) {
            state = CCN_DSTATE_ERR_NEST;
            break;
          }
          XML("<%s");
          tagstate = 1;
          state = CCN_DSTATE_NEWTOKEN;
        }
        break;                
      case CCN_DSTATE_ATTRNAME: /* parsing attribute name */
        chunk = n - i;
        if (chunk > numval)
          chunk = numval;
        if (chunk == 0) {
          state = CCN_DSTATE_ERR_BUG;
          break;
        }
        numval -= chunk;
        i += chunk;
        if (numval == 0) {
          if (d->nest == 0) {
            state = CCN_DSTATE_ERR_ATTR;
            break;
          }
          XML(" %s=\"");
          tagstate = 3;
          state = CCN_DSTATE_NEWTOKEN;
        }
        break;
      case CCN_DSTATE_UDATA: /* utf-8 data */
      case CCN_DSTATE_BLOB: /* BLOB */
        chunk = n - i;
        if (chunk > numval)
          chunk = numval;
        if (chunk == 0) {
          state = CCN_DSTATE_ERR_BUG;
          break;
        }
        numval -= chunk;
        i += chunk;
        if (numval == 0)
          state = CCN_DSTATE_NEWTOKEN;
        break;
      default:
        n = i;
    }
  }
  if (state < 0)
    tagstate = pause = 0;
  d->state = state | pause | (tagstate << 8); 
  d->numval = numval;
  d->index += i;
  return(i);
}
