/**
 * @author: Jeff Thompson
 * See COPYING for copyright and distribution information.
 */

#include "BinaryXML.h"
#include "BinaryXMLDecoder.h"

/**
 * Return the octet at self->offset, converting to unsigned int.  Increment self->offset.
 * This does not check for reading past the end of the input, so this is called "unsafe".
 */
static inline unsigned int unsafeReadOctet(struct ndn_BinaryXMLDecoder *self) 
{
  return (unsigned int)(self->input[self->offset++] & 0xff);  
}

/**
 * Return the octet at self->offset, converting to unsigned int.  Do not increment self->offset.
 * This does not check for reading past the end of the input, so this is called "unsafe".
 */
static inline unsigned int unsafeGetOctet(struct ndn_BinaryXMLDecoder *self) 
{
  return (unsigned int)(self->input[self->offset] & 0xff);  
}

/**
 * Parse the value as a decimal unsigned integer.  This does not check for whitespace or + sign.
 * If valueLength is 0, this succeeds with resultOut 0.
 * @param value
 * @param valueLength
 * @param resultOut output the parsed integer.
 * @return 0 for success, else an error string, including if an element of value is not a decimal digit.
 */
static char *parseUnsignedDecimalInt(unsigned char *value, unsigned int valueLength, unsigned int *resultOut)
{
  unsigned int result = 0;
  
  unsigned int i;
  for (i = 0; i < valueLength; ++i) {
    unsigned char digit = value[i];
    if (!(digit >= '0' && digit <= '9'))
      return "parseUnsignedDecimalInt: element of value is not a decimal digit";

    result *= 10;
    result += (unsigned int)(digit - '0');
  }
    
  *resultOut = result;
  return 0;
}

char *ndn_BinaryXMLDecoder_decodeTypeAndValue(struct ndn_BinaryXMLDecoder *self, unsigned int *type, unsigned int *valueOut) 
{
  unsigned int value = 0;
  int gotFirstOctet = 0;
  
	while (1) {
    if (self->offset >= self->inputLength)
      return "ndn_BinaryXMLDecoder_decodeTypeAndVal: read past the end of the input";
    
		unsigned int octet = unsafeReadOctet(self);
		
    if (!gotFirstOctet) {
      if (octet == 0)
        return "ndn_BinaryXMLDecoder_decodeTypeAndVal: the first header octet may not be zero";
      
      gotFirstOctet = 1;
    }
    
		if (octet & ndn_BinaryXML_TT_FINAL) {
      // Finished.
			*type = octet & ndn_BinaryXML_TT_MASK;
			value = (value << ndn_BinaryXML_TT_VALUE_BITS) | ((octet >> ndn_BinaryXML_TT_BITS) & ndn_BinaryXML_TT_VALUE_MASK);
      break;
		}
		
    value = (value << ndn_BinaryXML_REGULAR_VALUE_BITS) | (octet & ndn_BinaryXML_REGULAR_VALUE_MASK);		
	}

	*valueOut = value;
  return 0;
}

char *ndn_BinaryXMLDecoder_readElementStartDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag)
{
  char *error;
  unsigned int type;
  unsigned int value;
  if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &type, &value))
    return error;
  
  if (type != ndn_BinaryXML_DTAG)
    return "ndn_BinaryXMLDecoder_readElementStartDTag: header type is not a DTAG";
  
  if (value != expectedTag)
    return "ndn_BinaryXMLDecoder_readElementStartDTag: did not get the expected DTAG";
  
  return 0;
}

char *ndn_BinaryXMLDecoder_readElementClose(struct ndn_BinaryXMLDecoder *self)
{
  if (self->offset >= self->inputLength)
    return "ndn_BinaryXMLDecoder_readElementClose: read past the end of the input";
  
  if (unsafeReadOctet(self) != ndn_BinaryXML_CLOSE)
    return "ndn_BinaryXMLDecoder_readElementStartDTag: did not get the expected element close";
  
  return 0;
}

char *ndn_BinaryXMLDecoder_peekDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *gotExpectedTag)
{
  // Default to 0.
  *gotExpectedTag = 0;

  // First check if it is an element close (which cannot be the expected tag).  
  if (self->offset >= self->inputLength)
    return "ndn_BinaryXMLDecoder_readElementClose: read past the end of the input";
  if (unsafeGetOctet(self) == 0)
    return 0;

  unsigned int type;
  unsigned int value;
  unsigned int saveOffset = self->offset;
  char *error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &type, &value);
  // Restore offset.
  self->offset = saveOffset;
  
  if (error)
    return error;
  
  if (type == ndn_BinaryXML_DTAG && value == expectedTag)
    *gotExpectedTag = 1;
  
  return 0;
}

char *ndn_BinaryXMLDecoder_readBinaryDTagElement
  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int allowNull, unsigned char **value, unsigned int *valueLen)
{
  char *error;
  if (error = ndn_BinaryXMLDecoder_readElementStartDTag(self, expectedTag))
    return error;
  
  if (allowNull) {
    if (self->offset >= self->inputLength)
      return "ndn_BinaryXMLDecoder_readBinaryDTagElement: read past the end of the input";
  
    if (unsafeGetOctet(self) == ndn_BinaryXML_CLOSE) {
      // The binary item is missing, and this is allowed, so read the element close and return a null value.
      ++self->offset;
      *value = 0;
      *valueLen = 0;
      return 0;
    }
  }
  
  unsigned int itemType;
  if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &itemType, valueLen))
    return error;
  // Ignore itemType.
  *value = self->input + self->offset;
  self->offset += *valueLen;
  
  if (error = ndn_BinaryXMLDecoder_readElementClose(self))
    return error;
  
  return 0;
}

char *ndn_BinaryXMLDecoder_readUDataDTagElement
  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, unsigned char **value, unsigned int *valueLen)
{
  char *error;
  if (error = ndn_BinaryXMLDecoder_readElementStartDTag(self, expectedTag))
    return error;
    
  unsigned int itemType;
  if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &itemType, valueLen))
    return error;
  if (itemType != ndn_BinaryXML_UDATA)
    return "ndn_BinaryXMLDecoder_readUDataDTagElement: item is not UDATA";
  *value = self->input + self->offset;
  self->offset += *valueLen;
  
  if (error = ndn_BinaryXMLDecoder_readElementClose(self))
    return error;
  
  return 0;
}

char *ndn_BinaryXMLDecoder_readUnsignedIntegerDTagElement
  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, unsigned int *value)
{
  unsigned char *udataValue;
  unsigned int udataValueLength;
  char *error;
  if (error = ndn_BinaryXMLDecoder_readUDataDTagElement(self, expectedTag, &udataValue, &udataValueLength))
    return error;
  
  if (error = parseUnsignedDecimalInt(udataValue, udataValueLength, value))
    return error;
  
  return 0;
}

char *ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *value)
{
  int gotExpectedTag;
  char *error;
  if (error = ndn_BinaryXMLDecoder_peekDTag(self, expectedTag, &gotExpectedTag))
    return error;
    
  if (!gotExpectedTag) {
    *value = -1;
    return 0;
  }

  unsigned int unsignedValue;
  if (error = ndn_BinaryXMLDecoder_readUnsignedIntegerDTagElement(self, expectedTag, &unsignedValue))
    return error;
  
  *value = (int)unsignedValue;
  return 0;
}

// TODO: This could be in a more central source file.
unsigned int ndn_BinaryXMLDecoder_bigEndianToUnsignedInt(unsigned char *bytes, unsigned int bytesLength) 
{
  unsigned int result = 0;
  unsigned int i;
  for (i = 0; i < bytesLength; ++i) {
    result <<= 8;
    result += (unsigned int)bytes[i];
  }
  
  return result;
}
