A client for the SmartREST protocol from Cumulocity.

Dependencies:   SmartRest

Fork of MbedSmartRest by Vincent Wochnik

Files at this revision

API Documentation at this revision

Comitter:
vwochnik
Date:
Sun Feb 02 14:55:57 2014 +0000
Parent:
7:26524a6a04a1
Child:
9:3bbb83e7cbfd
Commit message:
fix

Changed in this revision

SmartRest.lib Show diff for this revision Revisions of this file
SmartRest/AbstractClient.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/AbstractDataSink.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/AbstractDataSource.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/Aggregator.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/Aggregator.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/CharValue.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/CharValue.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/ComposedRecord.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/ComposedRecord.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/DataGenerator.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/FloatValue.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/FloatValue.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/IntegerValue.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/IntegerValue.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/NullValue.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/NullValue.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/ParsedRecord.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/ParsedRecord.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/ParsedValue.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/ParsedValue.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/Parser.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/Parser.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/Record.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/Record.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/SmartRest.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/SmartRest.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/StaticData.cpp Show annotated file Show diff for this revision Revisions of this file
SmartRest/StaticData.h Show annotated file Show diff for this revision Revisions of this file
SmartRest/Value.h Show annotated file Show diff for this revision Revisions of this file
--- a/SmartRest.lib	Sun Feb 02 14:55:16 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-SmartRest#fc337461afe3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/AbstractClient.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,122 @@
+/*
+ * AbstractClient.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+/**
+ * @file AbstractClient.h
+ * An abstraction layer for the SmartREST http client.
+ */
+
+#ifndef ABSTRACTCLIENT_H
+#define ABSTRACTCLIENT_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DataGenerator.h"
+#include "AbstractDataSource.h"
+#include "AbstractDataSink.h"
+
+/** Return value indicating that the operation has been successful. */
+#define CLIENT_OK 0
+/** Return value indicating that there has been a connection error. */
+#define CLIENT_CONNECTION_ERROR 1
+/** Return value indicating that an internal error occurred. */
+#define CLIENT_INTERNAL_ERROR 2
+
+/*
+ * An abstraction layer for the SmartREST http client.
+ * 
+ * All methods have to be called in the following order:
+ * - beginRequest()
+ * - sendIdentifier() (optional)
+ * - sendData() (optional)
+ * - endRequest()
+ * - awaitResponse()
+ * - receiveData() (optional)
+ * - stop()
+ * 
+ * Additionally, stop() can be called at any time to reset the state of
+ * this instance.
+ */
+class AbstractClient
+{
+public:
+    virtual ~AbstractClient() { };
+
+    /**
+     * Begins a new request. This method has to be the first call for
+     * any request. A connection to the server will be established
+     * and the start of a HTTP post request will be sent over the
+     * connection including Host and Authorization headers.
+     */
+    virtual uint8_t beginRequest() = 0;
+
+    /**
+     * Sends the X-Id device identifier header.
+     * @param identifier the identifier to be sent. The value has to remain
+     *                   valid for the entire request.
+     */
+    virtual uint8_t sendIdentifier(const char*) = 0;
+
+    /**
+     * Sends POST data over the connection. Before the data is sent,
+     * a Content-Length header is also sent over the connection. if the
+     * estimated length does not match the actual conten length,
+     * unexpected behavior will occur.
+     * @param generator the data generator for the data to be sent
+     */
+    virtual uint8_t sendData(DataGenerator& generator) = 0;
+
+    /**
+     * Finishes the request. In case no data has been sent over the
+     * connection, this method will send twice carriage-return new-line.
+     */
+    virtual uint8_t endRequest() = 0;
+
+    /**
+     * Blocks until the start of a response has been received.
+     */
+    virtual uint8_t awaitResponse() = 0;
+
+    /**
+     * Returns a data source for reading data.
+     * When no data can be read for whatever reason,
+     * a data source with an error state may be returned.
+     * @return the data source to read from
+     */
+    virtual AbstractDataSource& receiveData() = 0;
+
+    /**
+     * Resets the connection. This method can be called at any time
+     * and resets the state of this instance.
+     */
+    virtual void stop() = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/AbstractDataSink.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,89 @@
+/*
+ * AbstractDataSink.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+/**
+ * @file AbstractDataSink.h
+ * An abstraction for a data sink which can be used to send data
+ * over a connection.
+ * 
+ * Following write actions are supported:
+ * - write a character
+ * - write a buffer of certain length
+ * - write a character string
+ * - write an unsigned number
+ */
+
+#ifndef ABSTRACTDATASINK_H
+#define ABSTRACTDATASINK_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+
+/*
+ * The AbstractDataSink class provides a way to write data to a
+ * connection.
+ */
+class AbstractDataSink
+{
+public:
+    virtual ~AbstractDataSink() { };
+
+    /**
+     * Writes a single character.
+     * @param c the character to write
+     * @return the number of characters written, in this case 1 or 0
+     */
+    virtual size_t write(char c) = 0;
+
+    /**
+     * Writes a buffer.
+     * @param buf the buffer to write
+     * @param length the length of the buffer in bytes
+     * @return the number of characters written
+     */
+    virtual size_t write(void *buf, size_t length) = 0;
+
+    /**
+     * Writes a character string.
+     * @param str the string to write
+     * @return the number of characters written
+     */
+    virtual size_t write(const char *str) = 0;
+
+    /**
+     * Writes a number with base 10.
+     * @param number the number to write
+     * @return the number of digits written
+     */
+    virtual size_t write(unsigned long number) = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/AbstractDataSource.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,104 @@
+/*
+ * AbstractDataSource.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+/**
+ * @file AbstractDataSource.h
+ * An abstraction layer which provides means to read data from a
+ * connection.
+ * 
+ * Example:
+ * @code
+ * AbstractDataSource source;
+ * char c;
+ * while (((c = source.read()) > 0) || (source.status() == DS_STATUS_OK)) {
+ *     // read action
+ * }
+ * switch (source.status()) {
+ * case DS_STATUS_OK:
+ *     // ok
+ * case DS_STATUS_CLOSED:
+ *     // connection closed
+ * case DS_STATUS_TIMEOUT:
+ *     // timeout
+ * default:
+ *     // other error
+ * }
+ * @encode
+ * 
+ */
+
+#ifndef ABSTRACTDATASOURCE_H
+#define ABSTRACTDATASOURCE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+
+/** Return value indicating that no error has occurred. */
+#define DS_STATUS_OK 0
+/** Return value indicating that the connection has been closed by this
+ * or the foreign host. */
+#define DS_STATUS_CLOSED 1
+/** Return value indicating a transmission timeout. */
+#define DS_STATUS_TIMEOUT 2
+/** Return value indicating a state error. */
+#define DS_STATUS_ERROR 3
+
+/*
+ * The AbstractDataSource class provides a way to read data from a
+ * connection.
+ */
+class AbstractDataSource
+{
+public:
+    virtual ~AbstractDataSource() { };
+
+    /**
+     * Reads one character. When successful, the returned value
+     * represents the character. Otherwise, status() will return a
+     * non-zero value. This function is blocking.
+     * @return the caracter read or zero. If the return value is
+     * non-zero, status() is zero. Otherwise, check status() for a
+     * non-zero value.
+     */
+    virtual char read() = 0;
+
+    /**
+     * Returns the current read state. If a non-zero value is returned,
+     * there is an error. Otherwise, everything is ok.
+     * DS_STATUS_TIMEOUT means that there has been a read timeout.
+     * DS_STATUS_CLOSED means that the connection has been closed
+     * by either this or the foreign host.
+     * @return the status value
+     */
+    virtual uint8_t status() = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Aggregator.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,163 @@
+/*
+ * Aggregator.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "Aggregator.h"
+#include <stdlib.h>
+
+#ifndef AGGREGATOR_FIXED_SIZE
+Aggregator::Aggregator(size_t capacity, bool growing, bool copy)
+{
+    _alloc = copy;
+    _growing = growing;
+    _initial = _capacity = capacity;
+    _list = (const DataGenerator**)malloc(_capacity*sizeof(DataGenerator*));
+    _length = 0;
+}
+#else
+Aggregator::Aggregator(bool copy)
+{
+    _alloc = copy;
+    _length = 0;
+}
+#endif
+
+Aggregator::~Aggregator()
+{
+    if (_alloc) {
+        for (size_t n = 0; n < _length; n++)
+            delete _list[n];
+    }
+    #ifndef AGGREGATOR_FIXED_SIZE
+    free(_list);
+    #endif
+}
+
+bool Aggregator::add(const DataGenerator& generator)
+{
+    if (this == &generator)
+        return false;
+    #ifndef AGGREGATOR_FIXED_SIZE
+    if (_length == _capacity) {
+        if (!_growing)
+            return false;
+
+        size_t capacity = _capacity + AGGREGATOR_MEMORY_INCREMENT;
+        const DataGenerator **list = (const DataGenerator**)realloc(_list,
+            capacity*sizeof(DataGenerator*));
+        if (list == NULL)
+            return false;
+        _list = list;
+        _capacity = capacity;
+    }
+    #else
+    if (_length == AGGREGATOR_FIXED_SIZE)
+        return false;
+    #endif
+
+    if (_alloc) {
+        DataGenerator *copy = generator.copy();
+        if (copy == NULL)
+            return false;
+        _list[_length++] = copy;
+    } else {
+        _list[_length++] = &generator;
+    }
+    return true;
+}
+
+void Aggregator::clear()
+{
+    if (_alloc) {
+        for (size_t n = 0; n < _length; n++)
+            delete _list[n];
+    }
+    _length = 0;
+
+    #ifndef AGGREGATOR_FIXED_SIZE
+    if (_growing) {
+        const DataGenerator **list = (const DataGenerator**)realloc(_list,
+            _initial*sizeof(DataGenerator*));
+        if (list == NULL)
+            return;
+        _list = list;
+        _capacity = _initial;
+    }
+    #endif
+}
+
+size_t Aggregator::length()
+{
+    return _length;
+}
+
+bool Aggregator::full()
+{
+    #ifndef AGGREGATOR_FIXED_SIZE
+    return (_growing) ? false : (_length == _capacity);
+    #else
+    return (_length == AGGREGATOR_FIXED_SIZE);
+    #endif
+}
+
+size_t Aggregator::capacity()
+{
+    #ifndef AGGREGATOR_FIXED_SIZE
+    return (_growing) ? 0 : _capacity;
+    #else
+    return AGGREGATOR_FIXED_SIZE;
+    #endif
+}
+
+size_t Aggregator::writeTo(AbstractDataSink& sink) const
+{
+    size_t len = 0;
+    for (size_t n = 0; n < _length; n++)
+        len += _list[n]->writeTo(sink);
+    return len;
+}
+
+size_t Aggregator::writtenLength() const
+{
+    size_t len = 0;
+    for (size_t n = 0; n < _length; n++)
+        len += _list[n]->writtenLength();
+    return len;
+}
+
+DataGenerator* Aggregator::copy() const
+{
+    #ifndef AGGREGATOR_FIXED_SIZE
+    Aggregator *copy = new Aggregator(_length, _growing, true);
+    #else
+    Aggregator *copy = new Aggregator(true);
+    #endif
+    for (size_t n = 0; n < _length; n++)
+        copy->add(*_list[n]);
+    return copy;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Aggregator.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,126 @@
+/*
+ * Aggregator.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef AGGREGATOR_H
+#define AGGREGATOR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include "DataGenerator.h"
+
+#ifndef AGGREGATOR_INITIAL_CAPACITY
+#define AGGREGATOR_INITIAL_CAPACITY 50
+#endif
+#ifndef AGGREGATOR_MEMORY_INCREMENT
+#define AGGREGATOR_MEMORY_INCREMENT 25
+#endif
+//#define AGGREGATOR_FIXED_SIZE 100
+
+/**
+ * An aggregator of data generators. This class can aggregate instances of
+ * itself.
+ * If the aggregator is set to copying all added data generators using
+ * the copy() method, all objects are being properly deallocated on
+ * destruction.
+ */
+class Aggregator : public DataGenerator
+{
+public:
+    #ifndef AGGREGATOR_FIXED_SIZE
+    /**
+     * Creates a new Aggregator instance.
+     * @param capacity the initial capacity of the instance
+     * @param growing specifies the capability of this instance to grow
+     * @param copy specifies whether all added data generators shall be
+     *             copied using the copy() method
+     */
+    Aggregator(size_t=AGGREGATOR_INITIAL_CAPACITY, bool=true, bool=false);
+    #else
+    /**
+     * Creates a new Aggregator instance.
+     * @param copy specifies whether all added data generators shall be
+     *             copied using the copy() method
+     */
+    Aggregator(bool=false);
+    #endif
+    ~Aggregator();
+
+    /**
+     * Adds a data generator to the aggregator.
+     * @param generator the data generator to add
+     * @return true if added, false otherwise.
+     */
+    bool add(const DataGenerator&);
+
+    /**
+     * Clears the aggregator. The capacity will shrink to it's initial
+     * size.
+     */
+    void clear();
+
+    /**
+     * Returns the number of data generators aggregated by this instance.
+     * @return the number of data generators aggregated
+     */
+    size_t length();
+
+    /**
+     * Returns whether the aggregator is full. If growing, this will
+     * always return false.
+     * @return whether the aggregator is full
+     */
+    bool full();
+
+    /**
+     * Returns the capacity of the aggregator. This will always return zero
+     * if the aggregator is growing.
+     */
+    size_t capacity();
+
+    size_t writeTo(AbstractDataSink&) const;
+    size_t writtenLength() const;
+    DataGenerator* copy() const;
+
+private:
+    #ifdef AGGREGATOR_FIXED_SIZE
+    const DataGenerator *_list[AGGREGATOR_FIXED_SIZE];
+    #else
+    const DataGenerator **_list;
+    #endif
+    size_t _length;
+    bool _alloc;
+    #ifndef AGGREGATOR_FIXED_SIZE
+    size_t _capacity, _initial;
+    bool _growing;
+    #endif
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/CharValue.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,137 @@
+/*
+ * CharValue.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "CharValue.h"
+#include "NullValue.h"
+#include <stdlib.h>
+#include <string.h>
+
+inline int8_t __charvalue_need_escape(const char *str);
+
+CharValue::CharValue(const char *str, bool copy)
+{
+    if ((str == NULL) || (strlen(str) == 0)) {
+        _alloc = false;
+        _str = NULL;
+    } else {
+        _alloc = copy;
+        if (copy) {
+            _str = (const char*)malloc(strlen(str)*sizeof(char));
+            strcpy((char*)_str, str);
+        } else {
+            _str = str;
+        }
+    }
+}
+
+CharValue::~CharValue()
+{
+    if (_alloc)
+        free((void*)_str);
+}
+
+uint8_t CharValue::valueType() const
+{
+    if (_str == NULL)
+        return VALUE_NULL;
+    return VALUE_CHARACTER;
+}
+
+long CharValue::integerValue() const
+{
+    return 0;
+}
+
+double CharValue::floatValue() const
+{
+    return 0.0;
+}
+
+const char * CharValue::characterValue() const
+{
+    return _str;
+}
+
+size_t CharValue::write(AbstractDataSink& sink) const
+{
+    if (_str == NULL)
+        return 0;
+    size_t n = 0;
+    int8_t esc = __charvalue_need_escape(_str) ? 1 : 0;
+    if (esc) n += sink.write('"');
+    for (char *q = (char*)_str, c; (c = *q) > 0; q++) {
+        if ((esc) && (c == '"'))
+            n += sink.write('"');
+        n += sink.write(c);
+    }
+    if (esc) n += sink.write('"');
+    return n;
+}
+
+size_t CharValue::length() const
+{
+    if (_str == NULL)
+        return 0;
+    size_t n = 0;
+    int8_t esc = __charvalue_need_escape(_str) ? 1 : 0;
+    if (esc)
+        n += 2;
+    for (char *q = (char*)_str, c; (c = *q) > 0; q++) {
+        if ((esc) && (c == '"'))
+            n++;
+        n++;
+    }
+    return n;
+}
+
+int8_t __charvalue_need_escape(const char *str)
+{
+    int8_t w = 0;
+    for (char c; (c = *str) > 0; str++) {
+        if ((c == ' ') || (c == '\t')) {
+            if (w == 0)
+                return 1;
+            w = 2;
+        } else {
+            w = 1;
+            if ((c == '"') || (c == ',') || (c == '\r') || (c == '\n'))
+                return 1;
+        }
+    }
+    if (w == 2)
+        return 1;
+    return 0;
+}
+
+Value* CharValue::copy() const
+{
+    if (_str == NULL)
+        return new NullValue();
+    return new CharValue(_str, true);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/CharValue.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,62 @@
+/*
+ * CharValue.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef CHARVALUE_H
+#define CHARVALUE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Value.h"
+
+/**
+ * A basic character value. This value type behaves simmilar to a null
+ * value if the ommitted string is empty.
+ */
+class CharValue : public Value
+{
+public:
+    CharValue(const char*, bool=false);
+    ~CharValue();
+
+    uint8_t valueType() const;
+    long integerValue() const;
+    double floatValue() const;
+    const char * characterValue() const;
+
+    size_t write(AbstractDataSink&) const;
+    size_t length() const;
+    Value* copy() const;
+
+private:
+    const char *_str;
+    bool _alloc;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/ComposedRecord.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,116 @@
+/*
+ * ComposedRecord.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "ComposedRecord.h"
+#include "NullValue.h"
+#include <stdlib.h>
+#include <string.h>
+
+ComposedRecord::ComposedRecord(bool copy)
+{
+    _alloc = copy;
+    #ifndef COMPOSED_FIXED_SIZE
+    _capacity = COMPOSED_INITIAL_CAPACITY;
+    _values = (const Value**)malloc(_capacity*sizeof(Value*));
+    #endif
+    _count = 0;
+}
+
+ComposedRecord::~ComposedRecord()
+{
+    if (_alloc) {
+        for (size_t n = 0; n < _count; n++)
+            delete _values[n];
+    }
+    #ifndef COMPOSED_FIXED_SIZE
+    free(_values);
+    #endif
+}
+
+ComposedRecord& ComposedRecord::add(const Value& value)
+{
+    #ifndef COMPOSED_FIXED_SIZE
+    if (_capacity == _count) {
+        size_t capacity = _capacity + COMPOSED_MEMORY_INCREMENT;
+        const Value **values = (const Value**)realloc(_values,
+            capacity*sizeof(Value*));
+        if (values == NULL)
+            return *this;
+        _values = values;
+        _capacity = capacity;
+    }
+    #else
+    if (_count == COMPOSED_FIXED_SIZE)
+        return *this;
+    #endif
+
+    if (_alloc) {
+        Value *copy = value.copy();
+        if (copy == NULL)
+            return *this;
+        _values[_count++] = copy;
+    } else {
+        _values[_count++] = &value;
+    }
+    return *this;
+}
+
+void ComposedRecord::clear()
+{
+    _count = 0;
+    #ifndef COMPOSED_FIXED_SIZE
+    if (_capacity > COMPOSED_INITIAL_CAPACITY) {
+        Value** values = (Value**)realloc(_values,
+            COMPOSED_INITIAL_CAPACITY*sizeof(Value*));
+        if (values == NULL)
+            return;
+        _capacity = COMPOSED_INITIAL_CAPACITY;
+    }
+    #endif
+}
+
+size_t ComposedRecord::values() const
+{
+    return _count;
+}
+
+const Value& ComposedRecord::value(size_t index) const
+{
+    if (index >= _count)
+        return aNullValue;
+    return *_values[index];
+}
+
+DataGenerator* ComposedRecord::copy() const
+{
+    ComposedRecord *copy = new ComposedRecord(true);
+    for (size_t n = 0; n < _count; n++)
+        copy->add(*_values[n]);
+    return copy;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/ComposedRecord.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,76 @@
+/*
+ * ComposedRecord.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef COMPOSEDRECORD_H
+#define COMPOSEDRECORD_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DataGenerator.h"
+#include "Record.h"
+#include "Value.h"
+
+#ifndef COMPOSED_INITIAL_CAPACITY
+#define COMPOSED_INITIAL_CAPACITY 10
+#endif
+#ifndef COMPOSED_MEMORY_INCREMENT
+#define COMPOSED_MEMORY_INCREMENT 5
+#endif
+//#define COMPOSED_FIXED_SIZE 25
+
+/**
+ * This value set collects values and serializes them.
+ */
+class ComposedRecord : public Record
+{
+public:
+    ComposedRecord(bool=false);
+    ~ComposedRecord();
+
+    ComposedRecord& add(const Value&);
+    void clear();
+
+    size_t values() const;
+    const Value& value(size_t index) const;
+
+    DataGenerator* copy() const;
+
+private:
+    #ifndef COMPOSED_FIXED_SIZE
+    const Value **_values;
+    size_t _capacity;
+    #else
+    Value *_values[COMPOSED_FIXED_SIZE];
+    #endif
+    size_t _count;
+    bool _alloc;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/DataGenerator.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,72 @@
+/*
+ * DataGenerator.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef DATAGENERATOR_H
+#define DATAGENERATOR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include "AbstractDataSink.h"
+
+/*
+ * The DataGenerator class provides a way to stream data to a
+ * connection..
+ */
+class DataGenerator
+{
+public:
+    virtual ~DataGenerator()
+    {
+    }
+
+    /**
+     * Writes the object to the specified destination.
+     * @param s the destination
+     * @return the number of bytes written
+     */
+    virtual size_t writeTo(AbstractDataSink&) const = 0;
+
+    /**
+     * Returns the estimated number of bytes which will be written.
+     * @return the estimated number of bytes printed
+     */
+    virtual size_t writtenLength() const = 0;
+
+    /**
+     * Creates a deep copy on the heap. The class type may be different.
+     * The only thing guaranteed is that the copy behaves exactly
+     * the same.
+     * @return cloned object with no memory dependencies
+     */
+    virtual DataGenerator* copy() const = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/FloatValue.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,137 @@
+/*
+ * FloatValue.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "FloatValue.h"
+#include <math.h>
+
+FloatValue::FloatValue(double number, uint8_t digits, bool zflag)
+{
+    _negative = (number < 0.0);
+    _zflag = zflag;
+    if (_negative)
+        _number = -number;
+    else
+        _number = number;
+    _digits = digits;
+}
+
+uint8_t FloatValue::valueType() const
+{
+    return VALUE_FLOAT;
+}
+
+long FloatValue::integerValue() const
+{
+    return 0L;
+}
+
+double FloatValue::floatValue() const
+{
+    return (_negative) ? -_number : _number;
+}
+
+const char * FloatValue::characterValue() const
+{
+    return 0;
+}
+
+size_t FloatValue::write(AbstractDataSink& sink) const
+{
+    size_t n = 0;
+
+    if (isnan(_number)) return sink.write("nan");
+    if (isinf(_number)) return sink.write("inf");
+    if (_number > 4294967040.0) return sink.write("ovf");
+  
+    if (_negative)
+        sink.write('-');
+
+    double number = _number, rounding = 0.5;
+    for (uint8_t i = 0; i < _digits; ++i)
+        rounding /= 10.0;
+    number += rounding;
+
+    unsigned long int_part = (unsigned long)number;
+    double remainder = number - (double)int_part;
+
+    if ((_zflag) || (int_part))
+        n += sink.write(int_part);
+
+    if (_digits == 0)
+        return n;
+    n += sink.write("."); 
+
+    uint8_t digits = _digits;
+    while (digits-- > 0) {
+        remainder *= 10.0;
+        unsigned long l = (unsigned long)remainder;
+        n += sink.write(l);
+        remainder -= l; 
+    } 
+
+    return n;
+}
+
+size_t FloatValue::length() const
+{
+    if ((isnan(_number)) || (isinf(_number)) ||
+            (_number > 4294967040.0))
+        return 3;
+
+    size_t l = 0;
+
+    if (_negative)
+        l++;
+
+    double number = _number, rounding = 0.5;
+    for (uint8_t i = 0; i < _digits; ++i)
+        rounding /= 10.0;
+    number += rounding;
+
+    unsigned long n = (unsigned long)number;
+    if ((_zflag) || (n)) {
+        do {
+            n /= 10;
+            l++;
+        } while(n);
+    }
+
+    if (_digits > 0)
+        l += 1 + _digits;
+
+    return l;
+}
+
+Value* FloatValue::copy() const
+{
+    double number;
+
+    number = (_negative) ? -_number : _number;
+    return new FloatValue(number, _digits, _zflag);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/FloatValue.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,69 @@
+/*
+ * FloatValue.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef FLOATVALUE_H
+#define FLOATVALUE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+#include "Value.h"
+
+/**
+ * A floating-point value.
+ */
+class FloatValue : public Value
+{
+public:
+    /**
+     * Creates a new instance of a floating-point value.
+     * @param number the floating-point number
+     * @param digits precision in number of digits
+     * @param zflag whether to write a zero before the floating point
+     */
+    FloatValue(double, uint8_t, bool=true);
+
+    uint8_t valueType() const;
+    long integerValue() const;
+    double floatValue() const;
+    const char * characterValue() const;
+
+    size_t write(AbstractDataSink&) const;
+    size_t length() const;
+    Value* copy() const;
+
+private:
+    double _number;
+    bool _negative;
+    uint8_t _digits;
+    bool _zflag;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/IntegerValue.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,92 @@
+/*
+ * IntegerValue.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "IntegerValue.h"
+
+IntegerValue::IntegerValue(long number)
+{
+    _negative = (number < 0L);
+    if (_negative)
+        _number = -number;
+    else
+        _number = number;
+}
+
+uint8_t IntegerValue::valueType() const
+{
+    return VALUE_INTEGER;
+}
+
+long IntegerValue::integerValue() const
+{
+    return (_negative) ? -_number : _number;
+}
+
+double IntegerValue::floatValue() const
+{
+    return 0.0;
+}
+
+const char * IntegerValue::characterValue() const
+{
+    return 0;
+}
+
+size_t IntegerValue::write(AbstractDataSink& sink) const
+{
+    size_t n = 0;
+    if (_negative)
+        n += sink.write('-');
+    n += sink.write(_number);
+    return n;
+}
+
+size_t IntegerValue::length() const
+{
+    size_t l = 0;
+
+    if (_negative)
+        l++;
+
+    unsigned long n = _number;
+
+    do {
+        n /= 10;
+        l++;
+    } while(n);
+    return l;
+}
+
+Value* IntegerValue::copy() const
+{
+    long number;
+
+    number = (_negative) ? -_number : _number;
+    return new IntegerValue(number);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/IntegerValue.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,57 @@
+/*
+ * IntegerValue.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef NUMBERVALUE_H
+#define NUMBERVALUE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Value.h"
+
+class IntegerValue : public Value
+{
+public:
+    IntegerValue(long);
+
+    uint8_t valueType() const;
+    long integerValue() const;
+    double floatValue() const;
+    const char * characterValue() const;
+
+    size_t write(AbstractDataSink&) const;
+    size_t length() const;
+    Value* copy() const;
+
+private:
+    unsigned long _number;
+    bool _negative;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/NullValue.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,71 @@
+/*
+ * NullValue.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "NullValue.h"
+
+NullValue aNullValue;
+
+NullValue::NullValue()
+{
+}
+
+uint8_t NullValue::valueType() const
+{
+    return VALUE_NULL;
+}
+
+long NullValue::integerValue() const
+{
+    return 0;
+}
+
+double NullValue::floatValue() const
+{
+    return 0.0;
+}
+
+char * NullValue::characterValue() const
+{
+    return NULL;
+}
+
+size_t NullValue::write(AbstractDataSink&) const
+{
+    return 0;
+}
+
+size_t NullValue::length() const
+{
+    return 0;
+}
+
+Value* NullValue::copy() const
+{
+    return new NullValue();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/NullValue.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,55 @@
+/*
+ * NullValue.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef NULLVALUE_H
+#define NULLVALUE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Value.h"
+
+class NullValue : public Value
+{
+public:
+    NullValue();
+
+    uint8_t valueType() const;
+    long integerValue() const;
+    double floatValue() const;
+    char * characterValue() const;
+
+    size_t write(AbstractDataSink&) const;
+    size_t length() const;
+    Value* copy() const;
+};
+
+extern NullValue aNullValue;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/ParsedRecord.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,80 @@
+/*
+ * ParsedRecord.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "ParsedRecord.h"
+#include "ComposedRecord.h"
+#include "ParsedValue.h"
+#include "NullValue.h"
+#include <stdlib.h>
+#include <string.h>
+
+ParsedRecord::ParsedRecord()
+{
+    _count = 0;
+}
+
+ParsedRecord::~ParsedRecord()
+{
+    for (size_t n = 0; n < _count; n++)
+        delete _values[n];
+}
+
+size_t ParsedRecord::values() const
+{
+    return _count;
+}
+
+const Value& ParsedRecord::value(size_t index) const
+{
+    if (index >= _count)
+        return aNullValue;
+    return *_values[index];
+}
+
+DataGenerator* ParsedRecord::copy() const
+{
+    ComposedRecord *copy = new ComposedRecord(true);
+    for (size_t n = 0; n < _count; n++)
+        copy->add(*_values[n]);
+    return copy;
+}
+
+void ParsedRecord::set(const char *strs, size_t count)
+{
+    for (size_t n = 0; n < _count; n++)
+        delete _values[n];
+    
+    if (count > PARSED_FIXED_SIZE)
+        count = PARSED_FIXED_SIZE;
+    _count = count;
+    const char *ptr = strs;
+    for (size_t n = 0; n < count; n++) {
+        _values[n] = new ParsedValue(ptr, false);
+        ptr += strlen(ptr) + 1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/ParsedRecord.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,71 @@
+/*
+ * ParsedRecord.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef PARSEDRECORD_H
+#define PARSEDRECORD_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DataGenerator.h"
+#include "Record.h"
+#include "Value.h"
+
+#ifndef PARSED_FIXED_SIZE
+#define PARSED_FIXED_SIZE 24
+#endif
+
+class Parser;
+
+/**
+ * This value set collects values and serializes them.
+ */
+class ParsedRecord : public Record
+{
+public:
+    ParsedRecord();
+    ~ParsedRecord();
+
+    size_t values() const;
+    const Value& value(size_t index) const;
+
+    DataGenerator* copy() const;
+
+private:
+    void set(const char*, size_t);
+
+private:
+    const Value *_values[PARSED_FIXED_SIZE];
+    size_t _count;
+
+friend class Parser;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/ParsedValue.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,128 @@
+/*
+ * ParsedValue.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "ParsedValue.h"
+#include "NullValue.h"
+#include "IntegerValue.h"
+#include "FloatValue.h"
+#include "CharValue.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+ParsedValue::ParsedValue(const char *str, bool copy) : _value(str, copy)
+{
+    if (_value.valueType() != VALUE_NULL) {
+        _type = VALUE_CHARACTER;
+        extractValue();
+    } else {
+        _type = VALUE_NULL;
+    }
+}
+
+uint8_t ParsedValue::valueType() const
+{
+    return _type;
+}
+
+long ParsedValue::integerValue() const
+{
+    if (_type != VALUE_INTEGER)
+        return 0;
+    return _integer;
+}
+
+double ParsedValue::floatValue() const
+{
+    if (_type != VALUE_FLOAT)
+        return 0.0;
+    return _float;
+}
+
+const char * ParsedValue::characterValue() const
+{
+    if (_type != VALUE_CHARACTER)
+        return NULL;
+    return _value.characterValue();
+}
+
+size_t ParsedValue::write(AbstractDataSink& sink) const
+{
+    return _value.write(sink);
+}
+
+size_t ParsedValue::length() const
+{
+    return _value.length();
+}
+
+Value* ParsedValue::copy() const
+{
+    if (_type == VALUE_NULL)
+        return new NullValue();
+    if (_type == VALUE_INTEGER)
+        return new IntegerValue(_integer);
+    if (_type == VALUE_FLOAT)
+        return new FloatValue(_float, _digits, _zflag);
+    return new CharValue(_value.characterValue(), true);
+}
+
+void ParsedValue::extractValue()
+{
+    int len;
+    const char *str = _value.characterValue();
+
+    sscanf(str, "%li%n", &_integer, &len);
+    if ((size_t)len == strlen(str)) {
+        _type = VALUE_INTEGER;
+        return;
+    }
+
+    sscanf(str, "%lf%n", &_float, &len);
+    if ((size_t)len == strlen(str)) {
+        bool floating = false;
+        _digits = 0;
+        _zflag = false;
+        for (char c, *ptr = (char*)str; (c = *ptr) > 0; ptr++) {
+            if (floating) {
+                if (c == '.')
+                    return;
+                _digits++;
+            } else {
+                if (c == '.')
+                    floating = true;
+                else if (isdigit(c))
+                    _zflag = true;
+            }
+        }
+        if (!((floating) && (!_digits))) {
+            _type = VALUE_FLOAT;
+            return;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/ParsedValue.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,69 @@
+/*
+ * ParsedValue.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef PARSEDVALUE_H
+#define PARSEDVALUE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Value.h"
+#include "CharValue.h"
+
+#ifndef PARSED_FIXED_SIZE
+#define PARSED_FIXED_SIZE 16
+#endif
+
+class ParsedValue : public Value
+{
+public:
+    ParsedValue(const char*, bool=false);
+
+    uint8_t valueType() const;
+    long integerValue() const;
+    double floatValue() const;
+    const char * characterValue() const;
+
+    size_t write(AbstractDataSink&) const;
+    size_t length() const;
+    Value* copy() const;
+
+private:
+    void extractValue();
+
+private:
+    CharValue _value;
+    uint8_t _type;
+    double _float;
+    uint8_t _digits;
+    bool _zflag;
+    long _integer;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Parser.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,180 @@
+/*
+ * Parser.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "Parser.h"
+
+#define STATE_BLANK 0
+#define STATE_STRUCTURE 1
+#define STATE_VALUE 2
+#define STATE_INQUOTES 3
+#define STATE_AFTERQUOTE 4
+#define STATE_COMPLETE 5
+#define STATE_ERROR 6
+
+Parser::Parser()
+{
+    reset();
+}
+
+uint8_t Parser::readFrom(AbstractDataSource& source, ParsedRecord& record)
+{
+    uint8_t status; char read;
+
+    reset();
+    record.set(NULL, 0);
+
+    while ((_state < STATE_COMPLETE) &&
+           (((read = source.read()) > 0 ) ||
+            ((status = source.status()) == DS_STATUS_OK)))
+        parse(read);
+
+    if (_state == STATE_COMPLETE)
+        record.set(_buffer, _count);
+
+    if (_state == STATE_COMPLETE)
+        return PARSER_SUCCESS;
+    else if (_state == STATE_BLANK)
+        if (status == DS_STATUS_CLOSED)
+            return PARSER_END_OF_RESPONSE;
+        else
+            return PARSER_TIMEOUT_ERROR;
+    else
+        if (status == DS_STATUS_TIMEOUT)
+            return PARSER_TIMEOUT_ERROR;
+        else
+            return PARSER_PARSE_ERROR;
+}
+
+void Parser::parse(char c)
+{
+    if (_ptr-_buffer >= PARSER_BUFFER_SIZE) {
+        _state = STATE_ERROR;
+        return;
+    }
+
+    switch (_state) {
+    case STATE_BLANK:
+        _state = STATE_STRUCTURE;
+    case STATE_STRUCTURE:
+        switch (c) {
+        case ' ':
+        case '\t':
+        case '\r':
+            break;
+        case '"':
+            _state = STATE_INQUOTES;
+            break;
+        case ',':
+            close();
+            break;
+        case '\0':
+        case '\n':
+            if ((_count == 0) && (_length == 0)) {
+                _state = STATE_BLANK;
+            } else {
+                close();
+                _state = STATE_COMPLETE;
+            }
+            break;
+        default:
+            if (_length > 0) {
+                _state = STATE_ERROR;
+            } else {
+                _state = STATE_VALUE;
+                parse(c);
+            }
+            break;
+        }
+        break;
+    case STATE_VALUE:
+        switch (c) {
+        case ',':
+        case '\n':
+            _state = STATE_STRUCTURE;
+            parse(c);
+            break;
+        case '"':
+            _state = STATE_ERROR;
+            break;
+        default:
+            if ((c == ' ') || (c == '\t') || (c == '\r'))
+                _trailing++;
+            else
+                _trailing = 0;
+            append(c);
+            break;
+        }
+        break;
+    case STATE_INQUOTES:
+        switch (c) {
+        case '"':
+            _state = STATE_AFTERQUOTE;
+            break;
+        default:
+            append(c);
+            break;
+        }
+        break;
+    case STATE_AFTERQUOTE:
+        switch (c) {
+        case '"':
+            append(c);
+            _state = STATE_INQUOTES;
+            break;
+        default:
+            _state = STATE_STRUCTURE;
+            parse(c);
+            break;
+        }
+        break;
+    }
+}
+
+void Parser::append(char c)
+{
+    *_ptr++ = c;
+    _length++;
+}
+
+void Parser::close()
+{
+    _ptr -= _trailing;
+    *_ptr++ = 0;
+    _trailing = 0;
+    _length = 0;
+    _count++;
+}
+
+void Parser::reset()
+{
+    _state = STATE_BLANK;
+    _ptr = _buffer;
+    _count = 0;
+    _trailing = 0;
+    _length = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Parser.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,94 @@
+/*
+ * Parser.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+/**
+ * @file Parser.h
+ * A CSV parser utilizing an AbstractDataSource instance for reading from
+ * a connection.
+ */
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#include "ParsedRecord.h"
+#include "AbstractDataSource.h"
+
+#ifndef PARSER_BUFFER_SIZE
+#define PARSER_BUFFER_SIZE 81
+#endif
+
+/** Return value indicating that no error occurred. */
+#define PARSER_SUCCESS 0
+/** Return value indicating that a transmission timeout occurred during
+ * the transmission of a record. */
+#define PARSER_TIMEOUT_ERROR 1
+/** Return value indicating the end of response. */
+#define PARSER_END_OF_RESPONSE 2
+/** Return value indicating a parse error. */
+#define PARSER_PARSE_ERROR 3
+
+/*
+ * A CSV parser implementation.
+ * This class parses CSV rows from a stream.
+ */
+class Parser
+{
+public:
+    /*
+     * Creates a new Parser instance.
+     */
+    Parser();
+
+    /*
+     * Parses a row from a stream.
+     * @param source the source to read from
+     * @param row the object written to
+     * @return a non-zero value if and only if an error occured.
+     */
+    uint8_t readFrom(AbstractDataSource&,ParsedRecord&);
+
+private:
+    void parse(char);
+    void append(char);
+    void close();
+    void reset();
+
+private:
+    char _buffer[PARSER_BUFFER_SIZE];
+    uint8_t _state;
+    char *_ptr;
+    size_t _count, _length, _trailing;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Record.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,59 @@
+/*
+ * Record.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "Record.h"
+
+size_t Record::writeTo(AbstractDataSink& sink) const
+{
+    size_t written = 0;
+    for (size_t n = values(), i = 0; i < n; i++) {
+        written += value(i).write(sink);
+        if (i < n-1)
+            written += sink.write(',');
+    }
+    written += sink.write('\r');
+    written += sink.write('\n');
+    return written;
+}
+
+size_t Record::writtenLength() const
+{
+    size_t written = 2;
+    for (size_t n = values(), i = 0; i < n; i++) {
+        written += value(i).length();
+        if (i < n-1)
+            written++;
+    }
+    return written;
+}
+
+Record::operator bool() const
+{
+    return values() > 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Record.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,66 @@
+/*
+ * Record.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef RECORD_H
+#define RECORD_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DataGenerator.h"
+#include "Value.h"
+
+/**
+ * A record which can be read and serialized. 
+ */
+class Record : public DataGenerator
+{
+public:
+    virtual ~Record() { };
+
+    /**
+     * Returns the number of values in this record.
+     * @return number of values in this record
+     */
+    virtual size_t values() const = 0;
+
+    /**
+     * Returns the value object by index
+     * @param index the index of the value
+     * @return a copy of a value object
+     */
+    virtual const Value& value(size_t index) const = 0;
+
+    size_t writeTo(AbstractDataSink&) const;
+    size_t writtenLength() const;
+
+    operator bool() const;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/SmartRest.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,164 @@
+/*
+ * SmartRest.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "SmartRest.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+SmartRest::SmartRest(AbstractClient& client, const char *identifier) : _client(client), _identifier(identifier)
+{
+    _source = NULL;
+    _mogid[0] = 0;
+}
+
+int8_t SmartRest::send(DataGenerator& generator)
+{
+    uint8_t res;
+
+    res = beginRequest();
+    if (res != SMARTREST_SUCCESS)
+        return res;
+
+    _client.sendData(generator);
+    return awaitResponse();
+}
+
+int8_t SmartRest::receive(ParsedRecord& record)
+{
+    uint8_t res;
+    
+    if (_source == NULL)
+        return SMARTREST_INTERNAL_ERROR;
+
+    res = _parser.readFrom(*_source, record);
+
+    switch (res) {
+    case PARSER_SUCCESS:
+        return SMARTREST_SUCCESS;
+    case PARSER_END_OF_RESPONSE:
+        return SMARTREST_END_OF_RESPONSE;
+    case PARSER_TIMEOUT_ERROR:
+        return SMARTREST_TIMEOUT_ERROR;
+    }
+    return SMARTREST_INTERNAL_ERROR;
+}
+
+int8_t SmartRest::bootstrap(DataGenerator& generator)
+{
+    ParsedRecord record;
+    int8_t ret;
+
+    ret = beginRequest();
+    if (ret != SMARTREST_SUCCESS)
+        return ret;
+    ret = awaitResponse();
+    if (ret != SMARTREST_SUCCESS)
+        return ret;
+    ret = receive(record);
+    if (ret != SMARTREST_SUCCESS)
+        return ret;
+    if (!record) {
+        return SMARTREST_INTERNAL_ERROR;
+    }
+    stop();
+
+    if (setMoGid(record))
+        return SMARTREST_SUCCESS;
+
+    if (record.value(0).integerValue() != 40)
+        return SMARTREST_INTERNAL_ERROR;
+
+    ret = send(generator);
+    if (ret != SMARTREST_SUCCESS)
+        return ret;
+    ret = receive(record);
+    if (ret != SMARTREST_SUCCESS)
+        return ret;
+    stop();
+
+    if (!setMoGid(record))
+        return SMARTREST_INTERNAL_ERROR;
+
+    return SMARTREST_SUCCESS;
+}
+
+void SmartRest::stop()
+{
+    _source = NULL;
+    _client.stop();
+}
+
+uint8_t SmartRest::beginRequest()
+{
+    int res;
+
+    res = _client.beginRequest();
+    if (res == CLIENT_CONNECTION_ERROR) {
+        return SMARTREST_CONNECTION_FAILED;
+    } else if (res != CLIENT_OK) {
+        return SMARTREST_INTERNAL_ERROR;
+    }
+    if (strlen(_mogid)) {
+        if (_client.sendIdentifier(_mogid) != CLIENT_OK)
+            return SMARTREST_INTERNAL_ERROR;
+    } else {
+        if (_client.sendIdentifier(_identifier) != CLIENT_OK)
+            return SMARTREST_INTERNAL_ERROR;
+    }
+    return SMARTREST_SUCCESS;
+}
+
+uint8_t SmartRest::awaitResponse()
+{
+    if ((_client.endRequest() != CLIENT_OK) ||
+        (_client.awaitResponse() != CLIENT_OK))
+        return SMARTREST_INTERNAL_ERROR;
+    _source = &_client.receiveData();
+    return SMARTREST_SUCCESS;
+}
+
+bool SmartRest::setMoGid(Record& record)
+{
+    long mogid;
+
+    *_mogid = 0;
+
+    if ((record.values() < 2) || (record.value(0).integerValue() != 20))
+        return false;
+
+    if (record.value(1).integerValue() == 0)
+        return false;
+
+    mogid = record.value(1).integerValue();
+
+    if (!snprintf(_mogid, SMARTREST_MOGID_BUFFER_SIZE, "%ld", mogid))
+        *_mogid = 0;
+
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/SmartRest.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,130 @@
+/*
+ * SmartRest.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+/**
+ * @file SmartRest.h
+ * The main SmartRest facade class. This class is abstract, because the
+ * actual implementation has to supply a client.
+ */
+
+#ifndef SMARTREST_H
+#define SMARTREST_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#include "AbstractClient.h"
+#include "ParsedRecord.h"
+#include "Parser.h"
+
+#ifndef SMARTREST_MOGID_BUFFER_SIZE
+#define SMARTREST_MOGID_BUFFER_SIZE 11
+#endif
+
+/** Return value indicating that no error occurred. */
+#define SMARTREST_SUCCESS 0
+/** Return value indicating that the connection has been closed during
+ * data transmission. */
+#define SMARTREST_CONNECTION_FAILED 1
+/** Return value indicating an internal state error. */
+#define SMARTREST_INTERNAL_ERROR 2
+/** Return value indicating a transmission timeout. */
+#define SMARTREST_TIMEOUT_ERROR 3
+/** Return value indicating an end of response indicated by the
+ * Content-Length header. */
+#define SMARTREST_END_OF_RESPONSE 4
+/** Return value indicating that the connection has been closed. */
+#define SMARTREST_CONNECTION_CLOSED 5
+
+/**
+ * SmartRest Arduino client implementation.
+ * This class provides methods to send a request and receive a response
+ * from the server.
+ */
+class SmartRest
+{
+protected:
+    /**
+     * Creates a new GenericSmartRest object.
+     * @param client the abstract client to use
+     * @param identifier the device identifier
+     */
+    SmartRest(AbstractClient&, const char*);
+
+public:
+    virtual ~SmartRest() { };
+
+    /**
+     * Sends a smart request.
+     * @param generator the generator which will generate the data to be
+     *                  sent.
+     * @return a non-zero value if and only if an error occured
+     */
+    int8_t send(DataGenerator&);
+
+    /**
+     * Tries to receive a parsed response row.
+     * When the function succeeds, but the row pointer is NULL, there are
+     * no more rows to be read.
+     * @param record an instance to where the parsed row is written
+     * @return a non-zero value if and only if an error occured
+     */
+    int8_t receive(ParsedRecord&);
+
+    /*
+     * Initiates the SmartRest bootstrap process.
+     * When successful, the template identifier will be replaced by the
+     * global managed object ID in future requests.
+     * @param generator the generator which will generate the data to be
+     *                  sent as a template.
+     * @return a non-zero value if and only if an error occured
+     */
+    int8_t bootstrap(DataGenerator&);
+
+    /*
+     * Closes the connection.
+     */
+    void stop();
+
+private:
+    uint8_t beginRequest();
+    uint8_t awaitResponse();
+    bool setMoGid(Record&);
+
+private:
+    AbstractClient& _client;
+    AbstractDataSource *_source;
+    Parser _parser;
+    const char *_identifier;
+    char _mogid[SMARTREST_MOGID_BUFFER_SIZE];
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/StaticData.cpp	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,78 @@
+/*
+ * StaticData.cpp
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#include "StaticData.h"
+#include <stdlib.h>
+#include <string.h>
+
+StaticData::StaticData(void* buffer, size_t length, bool copy)
+{
+    _alloc = copy;
+    _len = length;
+    if (copy) {
+        _buf = malloc(length);
+        memcpy(_buf, buffer, length);
+    } else {
+        _buf = buffer;
+    }
+}
+
+StaticData::StaticData(const char* string, bool copy)
+{
+    _alloc = copy;
+    if (copy) {
+        _len = strlen(string)*sizeof(char);
+        _buf = malloc(_len);
+        memcpy(_buf, string, _len);
+    } else {
+        _buf = (void*)string;
+        _len = strlen(string)*sizeof(char);
+    }
+}
+
+StaticData::~StaticData()
+{
+    if (_alloc)
+        free(_buf);
+}
+
+size_t StaticData::writeTo(AbstractDataSink& sink) const
+{
+    return sink.write((void*)_buf, _len*sizeof(char));
+}
+
+size_t StaticData::writtenLength() const
+{
+    return _len;
+}
+
+DataGenerator* StaticData::copy() const
+{
+    return new StaticData(_buf, _len, true);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/StaticData.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,59 @@
+/*
+ * StaticData.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+#ifndef STATICDATA_H
+#define STATICDATA_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include "DataGenerator.h"
+
+/*
+ * The StaticData class provides a way to stream data to a
+ * connection..
+ */
+class StaticData : public DataGenerator
+{
+public:
+    StaticData(void*, size_t, bool=false);
+    StaticData(const char*, bool=false);
+    ~StaticData();
+    size_t writeTo(AbstractDataSink&) const;
+    size_t writtenLength() const;
+    DataGenerator* copy() const;
+
+private:
+    void *_buf;
+    size_t _len;
+    bool _alloc;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartRest/Value.h	Sun Feb 02 14:55:57 2014 +0000
@@ -0,0 +1,110 @@
+/*
+ * Value.h
+ *
+ * Created on: Nov 1, 2013
+ * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
+ *
+ * Copyright (c) 2013 Cumulocity GmbH
+ *
+ * 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.
+ */
+
+/**
+ * @file Value.h
+ * Represents a generic data value.
+ */
+
+#ifndef VALUE_H
+#define VALUE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#include "AbstractDataSink.h"
+
+/** Return value indicating a null value. */
+#define VALUE_NULL 0
+/** Return value indicating an integer value. */
+#define VALUE_INTEGER 1
+/** Return value indicating a floating-point number. */
+#define VALUE_FLOAT 2
+/** Return value indicating a character string. */
+#define VALUE_CHARACTER 3
+
+/**
+ * A generic value offering means to obtain the value type and contents
+ * as well as writing the value to a sink.
+ */
+class Value
+{
+public:
+    virtual ~Value() { };
+
+    /**
+     * Returns the value type which can be VALUE_NULL, VALUE_INTEGER,
+     * VALUE_FLOAT or VALUE_CHARACTER.
+     * @return the value type
+     */
+    virtual uint8_t valueType() const = 0;
+
+    /**
+     * Returns the integer value if an integer type, otherwise zero.
+     * @return integer value
+     */
+    virtual long integerValue() const = 0;
+
+    /**
+     * Returns the float value if a float type, otherwise zero.
+     * @return float value
+     */
+    virtual double floatValue() const = 0;
+
+    /**
+     * Returns the character value if a character type, otherwise zero.
+     * @return character value
+     */
+    virtual const char * characterValue() const = 0;
+
+    /**
+     * Writes the value to a sink.
+     * If necessary, quotes and escape characters may be added.
+     * @param sink the sink to write the value to
+     * @return the number of bytes written
+     */
+    virtual size_t write(AbstractDataSink&) const = 0;
+
+    /**
+     * Returns the number of bytes required to write this value to a sink.
+     * @return number of bytes required to write this value
+     */
+    virtual size_t length() const = 0;
+
+    /**
+     * Copies this value to the heap. Referenced contents must also be
+     * copied.
+     * @return a new value instance allocated on the heap
+     */
+    virtual Value* copy() const = 0;
+};
+
+#endif