aJson is the attempt to port a complete JSON implementation to Arduino. It is based on the cJSON implementation, reduced in size and removing one or two feature. The current mbed implementation only supports FILE* as input so you will have to use a temporary file for parsing your json input. https://github.com/interactive-matter/aJson

Dependents:   WIZwikiREST20

Revision:
1:6df1d1f1b372
Parent:
0:428cf9a51873
Child:
2:ece3b5c4afed
--- a/aJSON.cpp	Mon Aug 27 15:15:45 2012 +0000
+++ b/aJSON.cpp	Tue Aug 28 08:16:29 2012 +0000
@@ -1,1201 +1,1201 @@
-/*
- Copyright (c) 2001, Interactive Matter, Marcus Nowotny
-
- Based on the cJSON Library, Copyright (C) 2009 Dave Gamble
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-
-// aJSON
-// aJson Library for Arduino.
-// This library is suited for Atmega328 based Arduinos.
-// The RAM on ATmega168 based Arduinos is too limited
-
-/******************************************************************************
- * Includes
- ******************************************************************************/
-
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-#include <float.h>
-#include <ctype.h>
-//#include <avr/pgmspace.h>
-#include "aJSON.h"
-#include "utility/streamhelper.h"
-#include "utility/stringbuffer.h"
-
-#include "compatibility.h"
-#include "stdio.h"
-
-/******************************************************************************
- * Definitions
- ******************************************************************************/
-//Default buffer sizes - buffers get initialized and grow acc to that size
-#define BUFFER_DEFAULT_SIZE 4
-
-//how much digits after . for float
-#define FLOAT_PRECISION 5
-
-
-
-
-
-
-// Internal constructor.
-aJsonObject*
-aJsonClass::newItem()
-{
-  aJsonObject* node = (aJsonObject*) malloc(sizeof(aJsonObject));
-  if (node)
-    memset(node, 0, sizeof(aJsonObject));
-  return node;
-}
-
-// Delete a aJsonObject structure.
-void
-aJsonClass::deleteItem(aJsonObject *c)
-{
-  aJsonObject *next;
-  while (c)
-    {
-      next = c->next;
-      if (!(c->type & aJson_IsReference) && c->child)
-        {
-          deleteItem(c->child);
-        }
-      if ((c->type == aJson_String) && c->valuestring)
-        {
-          free(c->valuestring);
-        }
-      if (c->name)
-        {
-          free(c->name);
-        }
-      free(c);
-      c = next;
-    }
-}
-
-// Parse the input text to generate a number, and populate the result into item.
-int
-aJsonClass::parseNumber(aJsonObject *item, FILE* stream)
-{
-  int i = 0;
-  char sign = 1;
-
-  int in = fgetc(stream);
-  if (in == EOF)
-    {
-      return EOF;
-    }
-  // It is easier to decode ourselves than to use sscnaf,
-  // since so we can easier decide between int & double
-  if (in == '-')
-    {
-      //it is a negative number
-      sign = -1;
-      in = fgetc(stream);
-      if (in == EOF)
-        {
-          return EOF;
-        }
-    }
-  if (in >= '0' && in <= '9')
-    do
-      {
-        i = (i * 10) + (in - '0');
-        in = fgetc(stream);
-      }
-    while (in >= '0' && in <= '9'); // Number?
-  //end of integer part &#65533; or isn't it?
-  if (!(in == '.' || in == 'e' || in == 'E'))
-    {
-      item->valueint = i * (int) sign;
-      item->type = aJson_Int;
-    }
-  //ok it seems to be a double
-  else
-    {
-      double n = (double) i;
-      int scale = 0;
-      int subscale = 0;
-      char signsubscale = 1;
-      if (in == '.')
-        {
-          in = fgetc(stream);
-          do
-            {
-              n = (n * 10.0) + (in - '0'), scale--;
-              in = fgetc(stream);
-            }
-          while (in >= '0' && in <= '9');
-        } // Fractional part?
-      if (in == 'e' || in == 'E') // Exponent?
-        {
-          in = fgetc(stream);
-          if (in == '+')
-            {
-              in = fgetc(stream);
-            }
-          else if (in == '-')
-            {
-              signsubscale = -1;
-              in = fgetc(stream);
-            }
-          while (in >= '0' && in <= '9')
-            {
-              subscale = (subscale * 10) + (in - '0'); // Number?
-              in = fgetc(stream);
-            }
-        }
-
-      n = sign * n * pow(10.0, ((double) scale + (double) subscale
-          * (double) signsubscale)); // number = +/- number.fraction * 10^+/- exponent
-
-      item->valuefloat = n;
-      item->type = aJson_Float;
-    }
-  //preserve the last character for the next routine
-  ungetc(in, stream);
-  return 0;
-}
-
-// Render the number nicely from the given item into a string.
-int
-aJsonClass::printInt(aJsonObject *item, FILE* stream)
-{
-  if (item != NULL)
-    {
-      return fprintf_P(stream, PSTR("%d"), item->valueint);
-    }
-  //printing nothing is ok
-  return 0;
-}
-
-int
-aJsonClass::printFloat(aJsonObject *item, FILE* stream)
-{
-  if (item != NULL)
-    {
-      double d = item->valuefloat;
-      if (d<0.0) {
-          fprintf_P(stream,PSTR("-"));
-          d=-d;
-      }
-      //print the integer part
-      unsigned long integer_number = (unsigned long)d;
-      fprintf_P(stream,PSTR("%u."),integer_number);
-      //print the fractional part
-      double fractional_part = d - ((double)integer_number);
-      //we do a do-while since we want to print at least one zero
-      //we just support a certain number of digits after the '.'
-      int n = FLOAT_PRECISION;
-      fractional_part += 0.5/pow(10.0, FLOAT_PRECISION);
-      do {
-          //make the first digit non fractional(shift it before the '.'
-          fractional_part *= 10.0;
-          //create an int out of it
-          unsigned int digit = (unsigned int) fractional_part;
-          //print it
-          fprintf_P(stream,PSTR("%u"),digit);
-          //remove it from the number
-          fractional_part -= (double)digit;
-          n--;
-      } while ((fractional_part!=0) && (n>0));
-    }
-  //printing nothing is ok
-  return 0;
-}
-
-// Parse the input text into an unescaped cstring, and populate item.
-int
-aJsonClass::parseString(aJsonObject *item, FILE* stream)
-{
-  //we do not need to skip here since the first byte should be '\"'
-  int in = fgetc(stream);
-  if (in != '\"')
-    {
-      return EOF; // not a string!
-    }
-  item->type = aJson_String;
-  //allocate a buffer & track how long it is and how much we have read
-  string_buffer* buffer = stringBufferCreate();
-  if (buffer == NULL)
-    {
-      //unable to allocate the string
-      return EOF;
-    }
-  in = fgetc(stream);
-  if (in == EOF)
-    {
-      stringBufferFree(buffer);
-      return EOF;
-    }
-  while (in != EOF)
-    {
-      while (in != '\"' && in >= 32)
-        {
-          if (in != '\\')
-            {
-              stringBufferAdd((char) in, buffer);
-            }
-          else
-            {
-              in = fgetc(stream);
-              if (in == EOF)
-                {
-                  stringBufferFree(buffer);
-                  return EOF;
-                }
-              switch (in)
-                {
-              case '\\':
-                stringBufferAdd('\\', buffer);
-                break;
-              case '\"':
-                stringBufferAdd('\"', buffer);
-                break;
-              case 'b':
-                stringBufferAdd('\b', buffer);
-                break;
-              case 'f':
-                stringBufferAdd('\f', buffer);
-                break;
-              case 'n':
-                stringBufferAdd('\n', buffer);
-                break;
-              case 'r':
-                stringBufferAdd('\r', buffer);
-                break;
-              case 't':
-                stringBufferAdd('\t', buffer);
-                break;
-              default:
-                //we do not understand it so we skip it
-                break;
-                }
-            }
-          in = fgetc(stream);
-          if (in == EOF)
-            {
-              stringBufferFree(buffer);
-              return EOF;
-            }
-        }
-      //the string ends here
-      item->valuestring = stringBufferToString(buffer);
-      return 0;
-    }
-  //we should not be here but it is ok
-  return 0;
-}
-
-// Render the cstring provided to an escaped version that can be printed.
-int
-aJsonClass::printStringPtr(const char *str, FILE* stream)
-{
-  if (fputc('\"', stream) == EOF)
-    {
-      return EOF;
-    }
-  char* ptr = (char*) str;
-  if (ptr != NULL)
-    {
-      while (*ptr != 0)
-        {
-          if ((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\')
-            {
-              if (fputc(*ptr, stream) == EOF)
-                {
-                  return EOF;
-                }
-              ptr++;
-            }
-          else
-            {
-              if (fputc('\\', stream) == EOF)
-                {
-                  return EOF;
-                }
-              switch (*ptr++)
-                {
-              case '\\':
-                if (fputc('\\', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              case '\"':
-                if (fputc('\"', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              case '\b':
-                if (fputc('b', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              case '\f':
-                if (fputc('f', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              case '\n':
-                if (fputc('n', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              case '\r':
-                if (fputc('r', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              case '\t':
-                if (fputc('t', stream) == EOF)
-                  {
-                    return EOF;
-                  }
-                break;
-              default:
-                break; // eviscerate with prejudice.
-                }
-            }
-
-        }
-    }
-  if (fputc('\"', stream) == EOF)
-    {
-      return EOF;
-    }
-  return 0;
-}
-
-// Invote print_string_ptr (which is useful) on an item.
-int
-aJsonClass::printString(aJsonObject *item, FILE* stream)
-{
-  return printStringPtr(item->valuestring, stream);
-}
-
-// Utility to jump whitespace and cr/lf
-int
-aJsonClass::skip(FILE* stream)
-{
-  if (stream == NULL)
-    {
-      return EOF;
-    }
-  int in = fgetc(stream);
-  while (in != EOF && (in <= 32))
-    {
-      in = fgetc(stream);
-    }
-  if (in != EOF)
-    {
-      if (ungetc(in, stream) == EOF)
-        {
-          return EOF;
-        }
-      return 0;
-    }
-  return EOF;
-}
-
-// Parse an object - create a new root, and populate.
-/*aJsonObject*
-aJsonClass::parse(char *value)
-{
-  FILE* string_input_stream = openStringInputStream(value);
-  aJsonObject* result = parse(string_input_stream, NULL);
-  closeStringInputStream(string_input_stream);
-  return result;
-}*/
-
-// Parse an object - create a new root, and populate.
-aJsonObject*
-aJsonClass::parse(FILE* stream)
-{
-  return parse(stream, NULL);
-}
-
-// Parse an object - create a new root, and populate.
-aJsonObject*
-aJsonClass::parse(FILE* stream, char** filter)
-{
-  if (stream == NULL)
-    {
-      return NULL;
-    }
-  aJsonObject *c = newItem();
-  if (!c)
-    return NULL; /* memory fail */
-
-  skip(stream);
-  if (parseValue(c, stream, filter) == EOF)
-    {
-      deleteItem(c);
-      return NULL;
-    }
-  return c;
-}
-
-// Render a aJsonObject item/entity/structure to text.
-int
-aJsonClass::print(aJsonObject* item, FILE* stream)
-{
-  return printValue(item, stream);
-}
-
-/*char*
-aJsonClass::print(aJsonObject* item)
-{
-  FILE* stream = openStringOutputStream();
-  if (stream == NULL)
-    {
-      return NULL;
-    }
-  print(item, stream);
-  return closeStringOutputStream(stream);
-}*/
-
-// Parser core - when encountering text, process appropriately.
-int
-aJsonClass::parseValue(aJsonObject *item, FILE* stream, char** filter)
-{
-  if (stream == NULL)
-    {
-      return EOF; // Fail on null.
-    }
-  if (skip(stream) == EOF)
-    {
-      return EOF;
-    }
-  //read the first byte from the stream
-  int in = fgetc(stream);
-  if (in == EOF)
-    {
-      return EOF;
-    }
-  if (ungetc(in, stream) == EOF)
-    {
-      return EOF;
-    }
-  if (in == '\"')
-    {
-      return parseString(item, stream);
-    }
-  else if (in == '-' || (in >= '0' && in <= '9'))
-    {
-      return parseNumber(item, stream);
-    }
-  else if (in == '[')
-    {
-      return parseArray(item, stream, filter);
-    }
-  else if (in == '{')
-    {
-      return parseObject(item, stream, filter);
-    }
-  //it can only be null, false or true
-  else if (in == 'n')
-    {
-      //a buffer to read the value
-      char buffer[] =
-        { 0, 0, 0, 0 };
-      if (fread(buffer, sizeof(char), 4, stream) != 4)
-        {
-          return EOF;
-        }
-      if (!strncmp(buffer, "null", 4))
-        {
-          item->type = aJson_NULL;
-          return 0;
-        }
-      else
-        {
-          return EOF;
-        }
-    }
-  else if (in == 'f')
-    {
-      //a buffer to read the value
-      char buffer[] =
-        { 0, 0, 0, 0, 0 };
-      if (fread(buffer, sizeof(char), 5, stream) != 5)
-        {
-          return EOF;
-        }
-      if (!strncmp(buffer, "false", 5))
-        {
-          item->type = aJson_False;
-          item->valuebool = 0;
-          return 0;
-        }
-    }
-  else if (in == 't')
-    {
-      //a buffer to read the value
-      char buffer[] =
-        { 0, 0, 0, 0 };
-      if (fread(buffer, sizeof(char), 4, stream) != 4)
-        {
-          return EOF;
-        }
-      if (!strncmp(buffer, "true", 4))
-        {
-          item->type = aJson_True;
-          item->valuebool = -1;
-          return 0;
-        }
-    }
-
-  return EOF; // failure.
-}
-
-// Render a value to text.
-int
-aJsonClass::printValue(aJsonObject *item, FILE* stream)
-{
-  int result = 0;
-  if (item == NULL)
-    {
-      //nothing to do
-      return 0;
-    }
-  switch (item->type)
-    {
-  case aJson_NULL:
-    result = fprintf_P(stream, PSTR("null"));
-    break;
-  case aJson_False:
-    result = fprintf_P(stream, PSTR("false"));
-    break;
-  case aJson_True:
-    result = fprintf_P(stream, PSTR("true"));
-    break;
-  case aJson_Int:
-    result = printInt(item, stream);
-    break;
-  case aJson_Float:
-    result = printFloat(item, stream);
-    break;
-  case aJson_String:
-    result = printString(item, stream);
-    break;
-  case aJson_Array:
-    result = printArray(item, stream);
-    break;
-  case aJson_Object:
-    result = printObject(item, stream);
-    break;
-    }
-  //good time to flush the stream
-  fflush(stream);
-  return result;
-}
-
-// Build an array from input text.
-int
-aJsonClass::parseArray(aJsonObject *item, FILE* stream, char** filter)
-{
-  int in = fgetc(stream);
-  if (in != '[')
-    {
-      return EOF; // not an array!
-    }
-
-  item->type = aJson_Array;
-  skip(stream);
-  in = fgetc(stream);
-  //check for empty array
-  if (in == ']')
-    {
-      return 0; // empty array.
-    }
-  //now put back the last character
-  ungetc(in, stream);
-  aJsonObject *child;
-  char first = -1;
-  while ((first) || (in == ','))
-    {
-      aJsonObject *new_item = newItem();
-      if (new_item == NULL)
-        {
-          return EOF; // memory fail
-        }
-      if (first)
-        {
-          item->child = new_item;
-          first = 0;
-        }
-      else
-        {
-          child->next = new_item;
-          new_item->prev = child;
-        }
-      child = new_item;
-      skip(stream);
-      if (parseValue(child, stream, filter))
-        {
-          return EOF;
-        }
-      skip(stream);
-      in = fgetc(stream);
-    }
-  if (in == ']')
-    {
-      return 0; // end of array
-    }
-  else
-    {
-      return EOF; // malformed.
-    }
-}
-
-// Render an array to text
-int
-aJsonClass::printArray(aJsonObject *item, FILE* stream)
-{
-  if (item == NULL)
-    {
-      //nothing to do
-      return 0;
-    }
-  aJsonObject *child = item->child;
-  if (fputc('[', stream) == EOF)
-    {
-      return EOF;
-    }
-  while (child)
-    {
-      if (printValue(child, stream) == EOF)
-        {
-          return EOF;
-        }
-      child = child->next;
-      if (child)
-        {
-          if (fputc(',', stream) == EOF)
-            {
-              return EOF;
-            }
-        }
-    }
-  if (fputc(']', stream) == EOF)
-    {
-      return EOF;
-    }
-  return 0;
-}
-
-// Build an object from the text.
-int
-aJsonClass::parseObject(aJsonObject *item, FILE* stream, char** filter)
-{
-  int in = fgetc(stream);
-  if (in != '{')
-    {
-      return EOF; // not an object!
-    }
-
-  item->type = aJson_Object;
-  skip(stream);
-  //check for an empty object
-  in = fgetc(stream);
-  if (in == '}')
-    {
-      return 0; // empty object.
-    }
-  //preserve the char for the next parser
-  ungetc(in, stream);
-
-  aJsonObject* child;
-  char first = -1;
-  while ((first) || (in == ','))
-    {
-      //in = fgetc(stream);
-      aJsonObject* new_item = newItem();
-      if (new_item == NULL)
-        {
-          return EOF; // memory fail
-        }
-      if (first)
-        {
-          first = 0;
-          item->child = new_item;
-        }
-      else
-        {
-          child->next = new_item;
-          new_item->prev = child;
-        }
-      child = new_item;
-      skip(stream);
-      if (parseString(child, stream) == EOF)
-        {
-          return EOF;
-        }
-      skip(stream);
-      child->name = child->valuestring;
-      child->valuestring = NULL;
-
-      in = fgetc(stream);
-      if (in != ':')
-        {
-          return EOF; // fail!
-        }
-      // skip any spacing, get the value.
-      skip(stream);
-      if (parseValue(child, stream, filter) == EOF)
-        {
-          return EOF;
-        }
-      in = fgetc(stream);
-    }
-
-  if (in == '}')
-    {
-      return 0; // end of array
-    }
-  else
-    {
-      return EOF; // malformed.
-    }
-}
-
-// Render an object to text.
-int
-aJsonClass::printObject(aJsonObject *item, FILE* stream)
-{
-  if (item == NULL)
-    {
-      //nothing to do
-      return 0;
-    }
-  aJsonObject *child = item->child;
-  if (fputc('{', stream) == EOF)
-    {
-      return EOF;
-    }
-  while (child)
-    {
-      if (printStringPtr(child->name, stream) == EOF)
-        {
-          return EOF;
-        }
-      if (fputc(':', stream) == EOF)
-        {
-          return EOF;
-        }
-      if (printValue(child, stream) == EOF)
-        {
-          return EOF;
-        }
-      child = child->next;
-      if (child)
-        {
-          if (fputc(',', stream) == EOF)
-            {
-              return EOF;
-            }
-        }
-    }
-  if (fputc('}', stream) == EOF)
-    {
-      return EOF;
-    }
-  return 0;
-}
-
-// Get Array size/item / object item.
-unsigned char
-aJsonClass::getArraySize(aJsonObject *array)
-{
-  aJsonObject *c = array->child;
-  unsigned char i = 0;
-  while (c)
-    i++, c = c->next;
-  return i;
-}
-aJsonObject*
-aJsonClass::getArrayItem(aJsonObject *array, unsigned char item)
-{
-  aJsonObject *c = array->child;
-  while (c && item > 0)
-    item--, c = c->next;
-  return c;
-}
-aJsonObject*
-aJsonClass::getObjectItem(aJsonObject *object, const char *string)
-{
-  aJsonObject *c = object->child;
-  while (c && strcasecmp(c->name, string))
-    c = c->next;
-  return c;
-}
-
-// Utility for array list handling.
-void
-aJsonClass::suffixObject(aJsonObject *prev, aJsonObject *item)
-{
-  prev->next = item;
-  item->prev = prev;
-}
-// Utility for handling references.
-aJsonObject*
-aJsonClass::createReference(aJsonObject *item)
-{
-  aJsonObject *ref = newItem();
-  if (!ref)
-    return 0;
-  memcpy(ref, item, sizeof(aJsonObject));
-  ref->name = 0;
-  ref->type |= aJson_IsReference;
-  ref->next = ref->prev = 0;
-  return ref;
-}
-
-// Add item to array/object.
-void
-aJsonClass::addItemToArray(aJsonObject *array, aJsonObject *item)
-{
-  aJsonObject *c = array->child;
-  if (!item)
-    return;
-  if (!c)
-    {
-      array->child = item;
-    }
-  else
-    {
-      while (c && c->next)
-        c = c->next;
-      suffixObject(c, item);
-    }
-}
-void
-aJsonClass::addItemToObject(aJsonObject *object, const char *string,
-    aJsonObject *item)
-{
-  if (!item)
-    return;
-  if (item->name)
-    free(item->name);
-  item->name = strdup(string);
-  addItemToArray(object, item);
-}
-void
-aJsonClass::addItemReferenceToArray(aJsonObject *array, aJsonObject *item)
-{
-  addItemToArray(array, createReference(item));
-}
-void
-aJsonClass::addItemReferenceToObject(aJsonObject *object, const char *string,
-    aJsonObject *item)
-{
-  addItemToObject(object, string, createReference(item));
-}
-
-aJsonObject*
-aJsonClass::detachItemFromArray(aJsonObject *array, unsigned char which)
-{
-  aJsonObject *c = array->child;
-  while (c && which > 0)
-    c = c->next, which--;
-  if (!c)
-    return 0;
-  if (c->prev)
-    c->prev->next = c->next;
-  if (c->next)
-    c->next->prev = c->prev;
-  if (c == array->child)
-    array->child = c->next;
-  c->prev = c->next = 0;
-  return c;
-}
-void
-aJsonClass::deleteItemFromArray(aJsonObject *array, unsigned char which)
-{
-  deleteItem(detachItemFromArray(array, which));
-}
-aJsonObject*
-aJsonClass::detachItemFromObject(aJsonObject *object, const char *string)
-{
-  unsigned char i = 0;
-  aJsonObject *c = object->child;
-  while (c && strcasecmp(c->name, string))
-    i++, c = c->next;
-  if (c)
-    return detachItemFromArray(object, i);
-  return 0;
-}
-void
-aJsonClass::deleteItemFromObject(aJsonObject *object, const char *string)
-{
-  deleteItem(detachItemFromObject(object, string));
-}
-
-// Replace array/object items with new ones.
-void
-aJsonClass::replaceItemInArray(aJsonObject *array, unsigned char which,
-    aJsonObject *newitem)
-{
-  aJsonObject *c = array->child;
-  while (c && which > 0)
-    c = c->next, which--;
-  if (!c)
-    return;
-  newitem->next = c->next;
-  newitem->prev = c->prev;
-  if (newitem->next)
-    newitem->next->prev = newitem;
-  if (c == array->child)
-    array->child = newitem;
-  else
-    newitem->prev->next = newitem;
-  c->next = c->prev = 0;
-  deleteItem(c);
-}
-void
-aJsonClass::replaceItemInObject(aJsonObject *object, const char *string,
-    aJsonObject *newitem)
-{
-  unsigned char i = 0;
-  aJsonObject *c = object->child;
-  while (c && strcasecmp(c->name, string))
-    i++, c = c->next;
-  if (c)
-    {
-      newitem->name = strdup(string);
-      replaceItemInArray(object, i, newitem);
-    }
-}
-
-// Create basic types:
-aJsonObject*
-aJsonClass::createNull()
-{
-  aJsonObject *item = newItem();
-  if (item)
-    item->type = aJson_NULL;
-  return item;
-}
-
-aJsonObject*
-aJsonClass::createTrue()
-{
-  aJsonObject *item = newItem();
-  if (item)
-    {
-      item->type = aJson_True;
-      item->valuebool = -1;
-    }
-  return item;
-}
-aJsonObject*
-aJsonClass::createFalse()
-{
-  aJsonObject *item = newItem();
-  if (item)
-    {
-      item->type = aJson_False;
-      item->valuebool = 0;
-    }
-  return item;
-}
-aJsonObject*
-aJsonClass::createItem(char b)
-{
-  aJsonObject *item = newItem();
-  if (item)
-    {
-      item->type = b ? aJson_True : aJson_False;
-      item->valuebool = b ? -1 : 0;
-    }
-  return item;
-}
-
-aJsonObject*
-aJsonClass::createItem(int num)
-{
-  aJsonObject *item = newItem();
-  if (item)
-    {
-      item->type = aJson_Int;
-      item->valueint = (int) num;
-    }
-  return item;
-}
-
-aJsonObject*
-aJsonClass::createItem(double num)
-{
-  aJsonObject *item = newItem();
-  if (item)
-    {
-      item->type = aJson_Float;
-      item->valuefloat = num;
-    }
-  return item;
-}
-
-aJsonObject*
-aJsonClass::createItem(const char *string)
-{
-  aJsonObject *item = newItem();
-  if (item)
-    {
-      item->type = aJson_String;
-      item->valuestring = strdup(string);
-    }
-  return item;
-}
-
-aJsonObject*
-aJsonClass::createArray()
-{
-  aJsonObject *item = newItem();
-  if (item)
-    item->type = aJson_Array;
-  return item;
-}
-aJsonObject*
-aJsonClass::createObject()
-{
-  aJsonObject *item = newItem();
-  if (item)
-    item->type = aJson_Object;
-  return item;
-}
-
-// Create Arrays:
-aJsonObject*
-aJsonClass::createIntArray(int *numbers, unsigned char count)
-{
-  unsigned char i;
-  aJsonObject *n = 0, *p = 0, *a = createArray();
-  for (i = 0; a && i < count; i++)
-    {
-      n = createItem(numbers[i]);
-      if (!i)
-        a->child = n;
-      else
-        suffixObject(p, n);
-      p = n;
-    }
-  return a;
-}
-
-aJsonObject*
-aJsonClass::createFloatArray(double *numbers, unsigned char count)
-{
-  unsigned char i;
-  aJsonObject *n = 0, *p = 0, *a = createArray();
-  for (i = 0; a && i < count; i++)
-    {
-      n = createItem(numbers[i]);
-      if (!i)
-        a->child = n;
-      else
-        suffixObject(p, n);
-      p = n;
-    }
-  return a;
-}
-
-aJsonObject*
-aJsonClass::createDoubleArray(double *numbers, unsigned char count)
-{
-  unsigned char i;
-  aJsonObject *n = 0, *p = 0, *a = createArray();
-  for (i = 0; a && i < count; i++)
-    {
-      n = createItem(numbers[i]);
-      if (!i)
-        a->child = n;
-      else
-        suffixObject(p, n);
-      p = n;
-    }
-  return a;
-}
-
-aJsonObject*
-aJsonClass::createStringArray(const char **strings, unsigned char count)
-{
-  unsigned char i;
-  aJsonObject *n = 0, *p = 0, *a = createArray();
-  for (i = 0; a && i < count; i++)
-    {
-      n = createItem(strings[i]);
-      if (!i)
-        a->child = n;
-      else
-        suffixObject(p, n);
-      p = n;
-    }
-  return a;
-}
-
-void
-aJsonClass::addNullToObject(aJsonObject* object, const char* name)
-{
-  addItemToObject(object, name, createNull());
-}
-
-void
-aJsonClass::addTrueToObject(aJsonObject* object, const char* name)
-{
-  addItemToObject(object, name, createTrue());
-}
-
-void
-aJsonClass::addFalseToObject(aJsonObject* object, const char* name)
-{
-  addItemToObject(object, name, createFalse());
-}
-
-void
-aJsonClass::addNumberToObject(aJsonObject* object, const char* name, int n)
-{
-  addItemToObject(object, name, createItem(n));
-}
-
-void
-aJsonClass::addNumberToObject(aJsonObject* object, const char* name, double n)
-{
-  addItemToObject(object, name, createItem(n));
-}
-
-void
-aJsonClass::addStringToObject(aJsonObject* object, const char* name,
-    const char* s)
-{
-  addItemToObject(object, name, createItem(s));
-}
-
-//TODO conversion routines btw. float & int types?
-
-aJsonClass aJson;
+/*
+ Copyright (c) 2001, Interactive Matter, Marcus Nowotny
+
+ Based on the cJSON Library, Copyright (C) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+// aJSON
+// aJson Library for Arduino.
+// This library is suited for Atmega328 based Arduinos.
+// The RAM on ATmega168 based Arduinos is too limited
+
+/******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include <ctype.h>
+//#include <avr/pgmspace.h>
+#include "aJSON.h"
+#include "utility/streamhelper.h"
+#include "utility/stringbuffer.h"
+
+#include "compatibility.h"
+#include "stdio.h"
+
+/******************************************************************************
+ * Definitions
+ ******************************************************************************/
+//Default buffer sizes - buffers get initialized and grow acc to that size
+#define BUFFER_DEFAULT_SIZE 4
+
+//how much digits after . for float
+#define FLOAT_PRECISION 5
+
+
+
+
+
+
+// Internal constructor.
+aJsonObject*
+aJsonClass::newItem()
+{
+  aJsonObject* node = (aJsonObject*) malloc(sizeof(aJsonObject));
+  if (node)
+    memset(node, 0, sizeof(aJsonObject));
+  return node;
+}
+
+// Delete a aJsonObject structure.
+void
+aJsonClass::deleteItem(aJsonObject *c)
+{
+  aJsonObject *next;
+  while (c)
+    {
+      next = c->next;
+      if (!(c->type & aJson_IsReference) && c->child)
+        {
+          deleteItem(c->child);
+        }
+      if ((c->type == aJson_String) && c->valuestring)
+        {
+          free(c->valuestring);
+        }
+      if (c->name)
+        {
+          free(c->name);
+        }
+      free(c);
+      c = next;
+    }
+}
+
+// Parse the input text to generate a number, and populate the result into item.
+int
+aJsonClass::parseNumber(aJsonObject *item, FILE* stream)
+{
+  int i = 0;
+  char sign = 1;
+
+  int in = fgetc(stream);
+  if (in == EOF)
+    {
+      return EOF;
+    }
+  // It is easier to decode ourselves than to use sscnaf,
+  // since so we can easier decide between int & double
+  if (in == '-')
+    {
+      //it is a negative number
+      sign = -1;
+      in = fgetc(stream);
+      if (in == EOF)
+        {
+          return EOF;
+        }
+    }
+  if (in >= '0' && in <= '9')
+    do
+      {
+        i = (i * 10) + (in - '0');
+        in = fgetc(stream);
+      }
+    while (in >= '0' && in <= '9'); // Number?
+  //end of integer part &#65533; or isn't it?
+  if (!(in == '.' || in == 'e' || in == 'E'))
+    {
+      item->valueint = i * (int) sign;
+      item->type = aJson_Int;
+    }
+  //ok it seems to be a double
+  else
+    {
+      double n = (double) i;
+      int scale = 0;
+      int subscale = 0;
+      char signsubscale = 1;
+      if (in == '.')
+        {
+          in = fgetc(stream);
+          do
+            {
+              n = (n * 10.0) + (in - '0'), scale--;
+              in = fgetc(stream);
+            }
+          while (in >= '0' && in <= '9');
+        } // Fractional part?
+      if (in == 'e' || in == 'E') // Exponent?
+        {
+          in = fgetc(stream);
+          if (in == '+')
+            {
+              in = fgetc(stream);
+            }
+          else if (in == '-')
+            {
+              signsubscale = -1;
+              in = fgetc(stream);
+            }
+          while (in >= '0' && in <= '9')
+            {
+              subscale = (subscale * 10) + (in - '0'); // Number?
+              in = fgetc(stream);
+            }
+        }
+
+      n = sign * n * pow(10.0, ((double) scale + (double) subscale
+          * (double) signsubscale)); // number = +/- number.fraction * 10^+/- exponent
+
+      item->valuefloat = n;
+      item->type = aJson_Float;
+    }
+  //preserve the last character for the next routine
+  ungetc(in, stream);
+  return 0;
+}
+
+// Render the number nicely from the given item into a string.
+int
+aJsonClass::printInt(aJsonObject *item, FILE* stream)
+{
+  if (item != NULL)
+    {
+      return fprintf_P(stream, PSTR("%d"), item->valueint);
+    }
+  //printing nothing is ok
+  return 0;
+}
+
+int
+aJsonClass::printFloat(aJsonObject *item, FILE* stream)
+{
+  if (item != NULL)
+    {
+      double d = item->valuefloat;
+      if (d<0.0) {
+          fprintf_P(stream,PSTR("-"));
+          d=-d;
+      }
+      //print the integer part
+      unsigned long integer_number = (unsigned long)d;
+      fprintf_P(stream,PSTR("%u."),integer_number);
+      //print the fractional part
+      double fractional_part = d - ((double)integer_number);
+      //we do a do-while since we want to print at least one zero
+      //we just support a certain number of digits after the '.'
+      int n = FLOAT_PRECISION;
+      fractional_part += 0.5/pow(10.0, FLOAT_PRECISION);
+      do {
+          //make the first digit non fractional(shift it before the '.'
+          fractional_part *= 10.0;
+          //create an int out of it
+          unsigned int digit = (unsigned int) fractional_part;
+          //print it
+          fprintf_P(stream,PSTR("%u"),digit);
+          //remove it from the number
+          fractional_part -= (double)digit;
+          n--;
+      } while ((fractional_part!=0) && (n>0));
+    }
+  //printing nothing is ok
+  return 0;
+}
+
+// Parse the input text into an unescaped cstring, and populate item.
+int
+aJsonClass::parseString(aJsonObject *item, FILE* stream)
+{
+  //we do not need to skip here since the first byte should be '\"'
+  int in = fgetc(stream);
+  if (in != '\"')
+    {
+      return EOF; // not a string!
+    }
+  item->type = aJson_String;
+  //allocate a buffer & track how long it is and how much we have read
+  string_buffer* buffer = stringBufferCreate();
+  if (buffer == NULL)
+    {
+      //unable to allocate the string
+      return EOF;
+    }
+  in = fgetc(stream);
+  if (in == EOF)
+    {
+      stringBufferFree(buffer);
+      return EOF;
+    }
+  while (in != EOF)
+    {
+      while (in != '\"' && in >= 32)
+        {
+          if (in != '\\')
+            {
+              stringBufferAdd((char) in, buffer);
+            }
+          else
+            {
+              in = fgetc(stream);
+              if (in == EOF)
+                {
+                  stringBufferFree(buffer);
+                  return EOF;
+                }
+              switch (in)
+                {
+              case '\\':
+                stringBufferAdd('\\', buffer);
+                break;
+              case '\"':
+                stringBufferAdd('\"', buffer);
+                break;
+              case 'b':
+                stringBufferAdd('\b', buffer);
+                break;
+              case 'f':
+                stringBufferAdd('\f', buffer);
+                break;
+              case 'n':
+                stringBufferAdd('\n', buffer);
+                break;
+              case 'r':
+                stringBufferAdd('\r', buffer);
+                break;
+              case 't':
+                stringBufferAdd('\t', buffer);
+                break;
+              default:
+                //we do not understand it so we skip it
+                break;
+                }
+            }
+          in = fgetc(stream);
+          if (in == EOF)
+            {
+              stringBufferFree(buffer);
+              return EOF;
+            }
+        }
+      //the string ends here
+      item->valuestring = stringBufferToString(buffer);
+      return 0;
+    }
+  //we should not be here but it is ok
+  return 0;
+}
+
+// Render the cstring provided to an escaped version that can be printed.
+int
+aJsonClass::printStringPtr(const char *str, FILE* stream)
+{
+  if (fputc('\"', stream) == EOF)
+    {
+      return EOF;
+    }
+  char* ptr = (char*) str;
+  if (ptr != NULL)
+    {
+      while (*ptr != 0)
+        {
+          if ((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\')
+            {
+              if (fputc(*ptr, stream) == EOF)
+                {
+                  return EOF;
+                }
+              ptr++;
+            }
+          else
+            {
+              if (fputc('\\', stream) == EOF)
+                {
+                  return EOF;
+                }
+              switch (*ptr++)
+                {
+              case '\\':
+                if (fputc('\\', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              case '\"':
+                if (fputc('\"', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              case '\b':
+                if (fputc('b', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              case '\f':
+                if (fputc('f', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              case '\n':
+                if (fputc('n', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              case '\r':
+                if (fputc('r', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              case '\t':
+                if (fputc('t', stream) == EOF)
+                  {
+                    return EOF;
+                  }
+                break;
+              default:
+                break; // eviscerate with prejudice.
+                }
+            }
+
+        }
+    }
+  if (fputc('\"', stream) == EOF)
+    {
+      return EOF;
+    }
+  return 0;
+}
+
+// Invote print_string_ptr (which is useful) on an item.
+int
+aJsonClass::printString(aJsonObject *item, FILE* stream)
+{
+  return printStringPtr(item->valuestring, stream);
+}
+
+// Utility to jump whitespace and cr/lf
+int
+aJsonClass::skip(FILE* stream)
+{
+  if (stream == NULL)
+    {
+      return EOF;
+    }
+  int in = fgetc(stream);
+  while (in != EOF && (in <= 32))
+    {
+      in = fgetc(stream);
+    }
+  if (in != EOF)
+    {
+      if (ungetc(in, stream) == EOF)
+        {
+          return EOF;
+        }
+      return 0;
+    }
+  return EOF;
+}
+
+// Parse an object - create a new root, and populate.
+/*aJsonObject*
+aJsonClass::parse(char *value)
+{
+  FILE* string_input_stream = openStringInputStream(value);
+  aJsonObject* result = parse(string_input_stream, NULL);
+  closeStringInputStream(string_input_stream);
+  return result;
+}*/
+
+// Parse an object - create a new root, and populate.
+aJsonObject*
+aJsonClass::parse(FILE* stream)
+{
+  return parse(stream, NULL);
+}
+
+// Parse an object - create a new root, and populate.
+aJsonObject*
+aJsonClass::parse(FILE* stream, char** filter)
+{
+  if (stream == NULL)
+    {
+      return NULL;
+    }
+  aJsonObject *c = newItem();
+  if (!c)
+    return NULL; /* memory fail */
+
+  skip(stream);
+  if (parseValue(c, stream, filter) == EOF)
+    {
+      deleteItem(c);
+      return NULL;
+    }
+  return c;
+}
+
+// Render a aJsonObject item/entity/structure to text.
+int
+aJsonClass::print(aJsonObject* item, FILE* stream)
+{
+  return printValue(item, stream);
+}
+
+/*char*
+aJsonClass::print(aJsonObject* item)
+{
+  FILE* stream = openStringOutputStream();
+  if (stream == NULL)
+    {
+      return NULL;
+    }
+  print(item, stream);
+  return closeStringOutputStream(stream);
+}*/
+
+// Parser core - when encountering text, process appropriately.
+int
+aJsonClass::parseValue(aJsonObject *item, FILE* stream, char** filter)
+{
+  if (stream == NULL)
+    {
+      return EOF; // Fail on null.
+    }
+  if (skip(stream) == EOF)
+    {
+      return EOF;
+    }
+  //read the first byte from the stream
+  int in = fgetc(stream);
+  if (in == EOF)
+    {
+      return EOF;
+    }
+  if (ungetc(in, stream) == EOF)
+    {
+      return EOF;
+    }
+  if (in == '\"')
+    {
+      return parseString(item, stream);
+    }
+  else if (in == '-' || (in >= '0' && in <= '9'))
+    {
+      return parseNumber(item, stream);
+    }
+  else if (in == '[')
+    {
+      return parseArray(item, stream, filter);
+    }
+  else if (in == '{')
+    {
+      return parseObject(item, stream, filter);
+    }
+  //it can only be null, false or true
+  else if (in == 'n')
+    {
+      //a buffer to read the value
+      char buffer[] =
+        { 0, 0, 0, 0 };
+      if (fread(buffer, sizeof(char), 4, stream) != 4)
+        {
+          return EOF;
+        }
+      if (!strncmp(buffer, "null", 4))
+        {
+          item->type = aJson_NULL;
+          return 0;
+        }
+      else
+        {
+          return EOF;
+        }
+    }
+  else if (in == 'f')
+    {
+      //a buffer to read the value
+      char buffer[] =
+        { 0, 0, 0, 0, 0 };
+      if (fread(buffer, sizeof(char), 5, stream) != 5)
+        {
+          return EOF;
+        }
+      if (!strncmp(buffer, "false", 5))
+        {
+          item->type = aJson_False;
+          item->valuebool = 0;
+          return 0;
+        }
+    }
+  else if (in == 't')
+    {
+      //a buffer to read the value
+      char buffer[] =
+        { 0, 0, 0, 0 };
+      if (fread(buffer, sizeof(char), 4, stream) != 4)
+        {
+          return EOF;
+        }
+      if (!strncmp(buffer, "true", 4))
+        {
+          item->type = aJson_True;
+          item->valuebool = -1;
+          return 0;
+        }
+    }
+
+  return EOF; // failure.
+}
+
+// Render a value to text.
+int
+aJsonClass::printValue(aJsonObject *item, FILE* stream)
+{
+  int result = 0;
+  if (item == NULL)
+    {
+      //nothing to do
+      return 0;
+    }
+  switch (item->type)
+    {
+  case aJson_NULL:
+    result = fprintf_P(stream, PSTR("null"));
+    break;
+  case aJson_False:
+    result = fprintf_P(stream, PSTR("false"));
+    break;
+  case aJson_True:
+    result = fprintf_P(stream, PSTR("true"));
+    break;
+  case aJson_Int:
+    result = printInt(item, stream);
+    break;
+  case aJson_Float:
+    result = printFloat(item, stream);
+    break;
+  case aJson_String:
+    result = printString(item, stream);
+    break;
+  case aJson_Array:
+    result = printArray(item, stream);
+    break;
+  case aJson_Object:
+    result = printObject(item, stream);
+    break;
+    }
+  //good time to flush the stream
+  fflush(stream);
+  return result;
+}
+
+// Build an array from input text.
+int
+aJsonClass::parseArray(aJsonObject *item, FILE* stream, char** filter)
+{
+  int in = fgetc(stream);
+  if (in != '[')
+    {
+      return EOF; // not an array!
+    }
+
+  item->type = aJson_Array;
+  skip(stream);
+  in = fgetc(stream);
+  //check for empty array
+  if (in == ']')
+    {
+      return 0; // empty array.
+    }
+  //now put back the last character
+  ungetc(in, stream);
+  aJsonObject *child;
+  char first = -1;
+  while ((first) || (in == ','))
+    {
+      aJsonObject *new_item = newItem();
+      if (new_item == NULL)
+        {
+          return EOF; // memory fail
+        }
+      if (first)
+        {
+          item->child = new_item;
+          first = 0;
+        }
+      else
+        {
+          child->next = new_item;
+          new_item->prev = child;
+        }
+      child = new_item;
+      skip(stream);
+      if (parseValue(child, stream, filter))
+        {
+          return EOF;
+        }
+      skip(stream);
+      in = fgetc(stream);
+    }
+  if (in == ']')
+    {
+      return 0; // end of array
+    }
+  else
+    {
+      return EOF; // malformed.
+    }
+}
+
+// Render an array to text
+int
+aJsonClass::printArray(aJsonObject *item, FILE* stream)
+{
+  if (item == NULL)
+    {
+      //nothing to do
+      return 0;
+    }
+  aJsonObject *child = item->child;
+  if (fputc('[', stream) == EOF)
+    {
+      return EOF;
+    }
+  while (child)
+    {
+      if (printValue(child, stream) == EOF)
+        {
+          return EOF;
+        }
+      child = child->next;
+      if (child)
+        {
+          if (fputc(',', stream) == EOF)
+            {
+              return EOF;
+            }
+        }
+    }
+  if (fputc(']', stream) == EOF)
+    {
+      return EOF;
+    }
+  return 0;
+}
+
+// Build an object from the text.
+int
+aJsonClass::parseObject(aJsonObject *item, FILE* stream, char** filter)
+{
+  int in = fgetc(stream);
+  if (in != '{')
+    {
+      return EOF; // not an object!
+    }
+
+  item->type = aJson_Object;
+  skip(stream);
+  //check for an empty object
+  in = fgetc(stream);
+  if (in == '}')
+    {
+      return 0; // empty object.
+    }
+  //preserve the char for the next parser
+  ungetc(in, stream);
+
+  aJsonObject* child;
+  char first = -1;
+  while ((first) || (in == ','))
+    {
+      //in = fgetc(stream);
+      aJsonObject* new_item = newItem();
+      if (new_item == NULL)
+        {
+          return EOF; // memory fail
+        }
+      if (first)
+        {
+          first = 0;
+          item->child = new_item;
+        }
+      else
+        {
+          child->next = new_item;
+          new_item->prev = child;
+        }
+      child = new_item;
+      skip(stream);
+      if (parseString(child, stream) == EOF)
+        {
+          return EOF;
+        }
+      skip(stream);
+      child->name = child->valuestring;
+      child->valuestring = NULL;
+
+      in = fgetc(stream);
+      if (in != ':')
+        {
+          return EOF; // fail!
+        }
+      // skip any spacing, get the value.
+      skip(stream);
+      if (parseValue(child, stream, filter) == EOF)
+        {
+          return EOF;
+        }
+      in = fgetc(stream);
+    }
+
+  if (in == '}')
+    {
+      return 0; // end of array
+    }
+  else
+    {
+      return EOF; // malformed.
+    }
+}
+
+// Render an object to text.
+int
+aJsonClass::printObject(aJsonObject *item, FILE* stream)
+{
+  if (item == NULL)
+    {
+      //nothing to do
+      return 0;
+    }
+  aJsonObject *child = item->child;
+  if (fputc('{', stream) == EOF)
+    {
+      return EOF;
+    }
+  while (child)
+    {
+      if (printStringPtr(child->name, stream) == EOF)
+        {
+          return EOF;
+        }
+      if (fputc(':', stream) == EOF)
+        {
+          return EOF;
+        }
+      if (printValue(child, stream) == EOF)
+        {
+          return EOF;
+        }
+      child = child->next;
+      if (child)
+        {
+          if (fputc(',', stream) == EOF)
+            {
+              return EOF;
+            }
+        }
+    }
+  if (fputc('}', stream) == EOF)
+    {
+      return EOF;
+    }
+  return 0;
+}
+
+// Get Array size/item / object item.
+unsigned char
+aJsonClass::getArraySize(aJsonObject *array)
+{
+  aJsonObject *c = array->child;
+  unsigned char i = 0;
+  while (c)
+    i++, c = c->next;
+  return i;
+}
+aJsonObject*
+aJsonClass::getArrayItem(aJsonObject *array, unsigned char item)
+{
+  aJsonObject *c = array->child;
+  while (c && item > 0)
+    item--, c = c->next;
+  return c;
+}
+aJsonObject*
+aJsonClass::getObjectItem(aJsonObject *object, const char *string)
+{
+  aJsonObject *c = object->child;
+  while (c && strcasecmp(c->name, string))
+    c = c->next;
+  return c;
+}
+
+// Utility for array list handling.
+void
+aJsonClass::suffixObject(aJsonObject *prev, aJsonObject *item)
+{
+  prev->next = item;
+  item->prev = prev;
+}
+// Utility for handling references.
+aJsonObject*
+aJsonClass::createReference(aJsonObject *item)
+{
+  aJsonObject *ref = newItem();
+  if (!ref)
+    return 0;
+  memcpy(ref, item, sizeof(aJsonObject));
+  ref->name = 0;
+  ref->type |= aJson_IsReference;
+  ref->next = ref->prev = 0;
+  return ref;
+}
+
+// Add item to array/object.
+void
+aJsonClass::addItemToArray(aJsonObject *array, aJsonObject *item)
+{
+  aJsonObject *c = array->child;
+  if (!item)
+    return;
+  if (!c)
+    {
+      array->child = item;
+    }
+  else
+    {
+      while (c && c->next)
+        c = c->next;
+      suffixObject(c, item);
+    }
+}
+void
+aJsonClass::addItemToObject(aJsonObject *object, const char *string,
+    aJsonObject *item)
+{
+  if (!item)
+    return;
+  if (item->name)
+    free(item->name);
+  item->name = strdup(string);
+  addItemToArray(object, item);
+}
+void
+aJsonClass::addItemReferenceToArray(aJsonObject *array, aJsonObject *item)
+{
+  addItemToArray(array, createReference(item));
+}
+void
+aJsonClass::addItemReferenceToObject(aJsonObject *object, const char *string,
+    aJsonObject *item)
+{
+  addItemToObject(object, string, createReference(item));
+}
+
+aJsonObject*
+aJsonClass::detachItemFromArray(aJsonObject *array, unsigned char which)
+{
+  aJsonObject *c = array->child;
+  while (c && which > 0)
+    c = c->next, which--;
+  if (!c)
+    return 0;
+  if (c->prev)
+    c->prev->next = c->next;
+  if (c->next)
+    c->next->prev = c->prev;
+  if (c == array->child)
+    array->child = c->next;
+  c->prev = c->next = 0;
+  return c;
+}
+void
+aJsonClass::deleteItemFromArray(aJsonObject *array, unsigned char which)
+{
+  deleteItem(detachItemFromArray(array, which));
+}
+aJsonObject*
+aJsonClass::detachItemFromObject(aJsonObject *object, const char *string)
+{
+  unsigned char i = 0;
+  aJsonObject *c = object->child;
+  while (c && strcasecmp(c->name, string))
+    i++, c = c->next;
+  if (c)
+    return detachItemFromArray(object, i);
+  return 0;
+}
+void
+aJsonClass::deleteItemFromObject(aJsonObject *object, const char *string)
+{
+  deleteItem(detachItemFromObject(object, string));
+}
+
+// Replace array/object items with new ones.
+void
+aJsonClass::replaceItemInArray(aJsonObject *array, unsigned char which,
+    aJsonObject *newitem)
+{
+  aJsonObject *c = array->child;
+  while (c && which > 0)
+    c = c->next, which--;
+  if (!c)
+    return;
+  newitem->next = c->next;
+  newitem->prev = c->prev;
+  if (newitem->next)
+    newitem->next->prev = newitem;
+  if (c == array->child)
+    array->child = newitem;
+  else
+    newitem->prev->next = newitem;
+  c->next = c->prev = 0;
+  deleteItem(c);
+}
+void
+aJsonClass::replaceItemInObject(aJsonObject *object, const char *string,
+    aJsonObject *newitem)
+{
+  unsigned char i = 0;
+  aJsonObject *c = object->child;
+  while (c && strcasecmp(c->name, string))
+    i++, c = c->next;
+  if (c)
+    {
+      newitem->name = strdup(string);
+      replaceItemInArray(object, i, newitem);
+    }
+}
+
+// Create basic types:
+aJsonObject*
+aJsonClass::createNull()
+{
+  aJsonObject *item = newItem();
+  if (item)
+    item->type = aJson_NULL;
+  return item;
+}
+
+aJsonObject*
+aJsonClass::createTrue()
+{
+  aJsonObject *item = newItem();
+  if (item)
+    {
+      item->type = aJson_True;
+      item->valuebool = -1;
+    }
+  return item;
+}
+aJsonObject*
+aJsonClass::createFalse()
+{
+  aJsonObject *item = newItem();
+  if (item)
+    {
+      item->type = aJson_False;
+      item->valuebool = 0;
+    }
+  return item;
+}
+aJsonObject*
+aJsonClass::createItem(char b)
+{
+  aJsonObject *item = newItem();
+  if (item)
+    {
+      item->type = b ? aJson_True : aJson_False;
+      item->valuebool = b ? -1 : 0;
+    }
+  return item;
+}
+
+aJsonObject*
+aJsonClass::createItem(int num)
+{
+  aJsonObject *item = newItem();
+  if (item)
+    {
+      item->type = aJson_Int;
+      item->valueint = (int) num;
+    }
+  return item;
+}
+
+aJsonObject*
+aJsonClass::createItem(double num)
+{
+  aJsonObject *item = newItem();
+  if (item)
+    {
+      item->type = aJson_Float;
+      item->valuefloat = num;
+    }
+  return item;
+}
+
+aJsonObject*
+aJsonClass::createItem(const char *string)
+{
+  aJsonObject *item = newItem();
+  if (item)
+    {
+      item->type = aJson_String;
+      item->valuestring = strdup(string);
+    }
+  return item;
+}
+
+aJsonObject*
+aJsonClass::createArray()
+{
+  aJsonObject *item = newItem();
+  if (item)
+    item->type = aJson_Array;
+  return item;
+}
+aJsonObject*
+aJsonClass::createObject()
+{
+  aJsonObject *item = newItem();
+  if (item)
+    item->type = aJson_Object;
+  return item;
+}
+
+// Create Arrays:
+aJsonObject*
+aJsonClass::createIntArray(int *numbers, unsigned char count)
+{
+  unsigned char i;
+  aJsonObject *n = 0, *p = 0, *a = createArray();
+  for (i = 0; a && i < count; i++)
+    {
+      n = createItem(numbers[i]);
+      if (!i)
+        a->child = n;
+      else
+        suffixObject(p, n);
+      p = n;
+    }
+  return a;
+}
+
+aJsonObject*
+aJsonClass::createFloatArray(double *numbers, unsigned char count)
+{
+  unsigned char i;
+  aJsonObject *n = 0, *p = 0, *a = createArray();
+  for (i = 0; a && i < count; i++)
+    {
+      n = createItem(numbers[i]);
+      if (!i)
+        a->child = n;
+      else
+        suffixObject(p, n);
+      p = n;
+    }
+  return a;
+}
+
+aJsonObject*
+aJsonClass::createDoubleArray(double *numbers, unsigned char count)
+{
+  unsigned char i;
+  aJsonObject *n = 0, *p = 0, *a = createArray();
+  for (i = 0; a && i < count; i++)
+    {
+      n = createItem(numbers[i]);
+      if (!i)
+        a->child = n;
+      else
+        suffixObject(p, n);
+      p = n;
+    }
+  return a;
+}
+
+aJsonObject*
+aJsonClass::createStringArray(const char **strings, unsigned char count)
+{
+  unsigned char i;
+  aJsonObject *n = 0, *p = 0, *a = createArray();
+  for (i = 0; a && i < count; i++)
+    {
+      n = createItem(strings[i]);
+      if (!i)
+        a->child = n;
+      else
+        suffixObject(p, n);
+      p = n;
+    }
+  return a;
+}
+
+void
+aJsonClass::addNullToObject(aJsonObject* object, const char* name)
+{
+  addItemToObject(object, name, createNull());
+}
+
+void
+aJsonClass::addTrueToObject(aJsonObject* object, const char* name)
+{
+  addItemToObject(object, name, createTrue());
+}
+
+void
+aJsonClass::addFalseToObject(aJsonObject* object, const char* name)
+{
+  addItemToObject(object, name, createFalse());
+}
+
+void
+aJsonClass::addNumberToObject(aJsonObject* object, const char* name, int n)
+{
+  addItemToObject(object, name, createItem(n));
+}
+
+void
+aJsonClass::addNumberToObject(aJsonObject* object, const char* name, double n)
+{
+  addItemToObject(object, name, createItem(n));
+}
+
+void
+aJsonClass::addStringToObject(aJsonObject* object, const char* name,
+    const char* s)
+{
+  addItemToObject(object, name, createItem(s));
+}
+
+//TODO conversion routines btw. float & int types?
+
+aJsonClass aJson;