/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
 *
 *    Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
 *    Copyright 2018 (c) Fraunhofer IOSB (Author: Lukas Meling)
 */

#include "ua_types_encoding_json.h"

#include <open62541/types_generated.h>
#include <open62541/types_generated_handling.h>

#include "ua_types_encoding_binary.h"

#include <float.h>
#include <math.h>

#ifdef UA_ENABLE_CUSTOM_LIBC
#include "../deps/musl/floatscan.h"
#include "../deps/musl/vfprintf.h"
#endif

#include "../deps/itoa.h"
#include "../deps/atoi.h"
#include "../deps/string_escape.h"
#include "../deps/base64.h"

#include "../deps/libc_time.h"

#if defined(_MSC_VER)
# define strtoll _strtoi64
# define strtoull _strtoui64
#endif

/* vs2008 does not have INFINITY and NAN defined */
#ifndef INFINITY
# define INFINITY ((UA_Double)(DBL_MAX+DBL_MAX))
#endif
#ifndef NAN
# define NAN ((UA_Double)(INFINITY-INFINITY))
#endif

#if defined(_MSC_VER)
# pragma warning(disable: 4756)
# pragma warning(disable: 4056)
#endif

#define UA_NODEIDTYPE_NUMERIC_TWOBYTE 0
#define UA_NODEIDTYPE_NUMERIC_FOURBYTE 1
#define UA_NODEIDTYPE_NUMERIC_COMPLETE 2

#define UA_EXPANDEDNODEID_SERVERINDEX_FLAG 0x40
#define UA_EXPANDEDNODEID_NAMESPACEURI_FLAG 0x80

#define UA_JSON_DATETIME_LENGTH 30

/* Max length of numbers for the allocation of temp buffers. Don't forget that
 * printf adds an additional \0 at the end!
 *
 * Sources:
 * https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/
 *
 * UInt16: 3 + 1
 * SByte: 3 + 1
 * UInt32:
 * Int32:
 * UInt64:
 * Int64:
 * Float: 149 + 1
 * Double: 767 + 1
 */

/************/
/* Encoding */
/************/

#define ENCODE_JSON(TYPE) static status \
    TYPE##_encodeJson(const UA_##TYPE *src, const UA_DataType *type, CtxJson *ctx)

#define ENCODE_DIRECT_JSON(SRC, TYPE) \
    TYPE##_encodeJson((const UA_##TYPE*)SRC, NULL, ctx)

extern const encodeJsonSignature encodeJsonJumpTable[UA_DATATYPEKINDS];
extern const decodeJsonSignature decodeJsonJumpTable[UA_DATATYPEKINDS];

/* Forward declarations */
UA_String UA_DateTime_toJSON(UA_DateTime t);
ENCODE_JSON(ByteString);

static status UA_FUNC_ATTR_WARN_UNUSED_RESULT
writeChar(CtxJson *ctx, char c) {
    if(ctx->pos >= ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
    if(!ctx->calcOnly)
        *ctx->pos = (UA_Byte)c;
    ctx->pos++;
    return UA_STATUSCODE_GOOD;
}

#define WRITE_JSON_ELEMENT(ELEM)                            \
    UA_FUNC_ATTR_WARN_UNUSED_RESULT status                  \
    writeJson##ELEM(CtxJson *ctx)

static WRITE_JSON_ELEMENT(Quote) {
    return writeChar(ctx, '\"');
}

WRITE_JSON_ELEMENT(ObjStart) {
    /* increase depth, save: before first key-value no comma needed. */
    ctx->depth++;
    ctx->commaNeeded[ctx->depth] = false;
    return writeChar(ctx, '{');
}

WRITE_JSON_ELEMENT(ObjEnd) {
    ctx->depth--; //decrease depth
    ctx->commaNeeded[ctx->depth] = true;
    return writeChar(ctx, '}');
}

WRITE_JSON_ELEMENT(ArrStart) {
    /* increase depth, save: before first array entry no comma needed. */
    ctx->commaNeeded[++ctx->depth] = false;
    return writeChar(ctx, '[');
}

WRITE_JSON_ELEMENT(ArrEnd) {
    ctx->depth--; //decrease depth
    ctx->commaNeeded[ctx->depth] = true;
    return writeChar(ctx, ']');
}

WRITE_JSON_ELEMENT(CommaIfNeeded) {
    if(ctx->commaNeeded[ctx->depth])
        return writeChar(ctx, ',');
    return UA_STATUSCODE_GOOD;
}

status
writeJsonArrElm(CtxJson *ctx, const void *value,
                const UA_DataType *type) {
    status ret = writeJsonCommaIfNeeded(ctx);
    ctx->commaNeeded[ctx->depth] = true;
    ret |= encodeJsonInternal(value, type, ctx);
    return ret;
}

status writeJsonObjElm(CtxJson *ctx, const char *key,
                       const void *value, const UA_DataType *type){
    return writeJsonKey(ctx, key) | encodeJsonInternal(value, type, ctx);
}

status writeJsonNull(CtxJson *ctx) {
    if(ctx->pos + 4 > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
    if(ctx->calcOnly) {
        ctx->pos += 4;
    } else {
        *(ctx->pos++) = 'n';
        *(ctx->pos++) = 'u';
        *(ctx->pos++) = 'l';
        *(ctx->pos++) = 'l';
    }
    return UA_STATUSCODE_GOOD;
}

/* Keys for JSON */

/* LocalizedText */
static const char* UA_JSONKEY_LOCALE = "Locale";
static const char* UA_JSONKEY_TEXT = "Text";

/* QualifiedName */
static const char* UA_JSONKEY_NAME = "Name";
static const char* UA_JSONKEY_URI = "Uri";

/* NodeId */
static const char* UA_JSONKEY_ID = "Id";
static const char* UA_JSONKEY_IDTYPE = "IdType";
static const char* UA_JSONKEY_NAMESPACE = "Namespace";

/* ExpandedNodeId */
static const char* UA_JSONKEY_SERVERURI = "ServerUri";

/* Variant */
static const char* UA_JSONKEY_TYPE = "Type";
static const char* UA_JSONKEY_BODY = "Body";
static const char* UA_JSONKEY_DIMENSION = "Dimension";

/* DataValue */
static const char* UA_JSONKEY_VALUE = "Value";
static const char* UA_JSONKEY_STATUS = "Status";
static const char* UA_JSONKEY_SOURCETIMESTAMP = "SourceTimestamp";
static const char* UA_JSONKEY_SOURCEPICOSECONDS = "SourcePicoseconds";
static const char* UA_JSONKEY_SERVERTIMESTAMP = "ServerTimestamp";
static const char* UA_JSONKEY_SERVERPICOSECONDS = "ServerPicoseconds";

/* ExtensionObject */
static const char* UA_JSONKEY_ENCODING = "Encoding";
static const char* UA_JSONKEY_TYPEID = "TypeId";

/* StatusCode */
static const char* UA_JSONKEY_CODE = "Code";
static const char* UA_JSONKEY_SYMBOL = "Symbol";

/* DiagnosticInfo */
static const char* UA_JSONKEY_SYMBOLICID = "SymbolicId";
static const char* UA_JSONKEY_NAMESPACEURI = "NamespaceUri";
static const char* UA_JSONKEY_LOCALIZEDTEXT = "LocalizedText";
static const char* UA_JSONKEY_ADDITIONALINFO = "AdditionalInfo";
static const char* UA_JSONKEY_INNERSTATUSCODE = "InnerStatusCode";
static const char* UA_JSONKEY_INNERDIAGNOSTICINFO = "InnerDiagnosticInfo";

/* Writes null terminated string to output buffer (current ctx->pos). Writes
 * comma in front of key if needed. Encapsulates key in quotes. */
status UA_FUNC_ATTR_WARN_UNUSED_RESULT
writeJsonKey(CtxJson *ctx, const char* key) {
    size_t size = strlen(key);
    if(ctx->pos + size + 4 > ctx->end) /* +4 because of " " : and , */
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
    status ret = writeJsonCommaIfNeeded(ctx);
    ctx->commaNeeded[ctx->depth] = true;
    if(ctx->calcOnly) {
        ctx->commaNeeded[ctx->depth] = true;
        ctx->pos += 3;
        ctx->pos += size;
        return ret;
    }

    ret |= writeChar(ctx, '\"');
    for(size_t i = 0; i < size; i++) {
        *(ctx->pos++) = (u8)key[i];
    }
    ret |= writeChar(ctx, '\"');
    ret |= writeChar(ctx, ':');
    return ret;
}

/* Boolean */
ENCODE_JSON(Boolean) {
    size_t sizeOfJSONBool;
    if(*src == true) {
        sizeOfJSONBool = 4; /*"true"*/
    } else {
        sizeOfJSONBool = 5; /*"false"*/
    }

    if(ctx->calcOnly) {
        ctx->pos += sizeOfJSONBool;
        return UA_STATUSCODE_GOOD;
    }

    if(ctx->pos + sizeOfJSONBool > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(*src) {
        *(ctx->pos++) = 't';
        *(ctx->pos++) = 'r';
        *(ctx->pos++) = 'u';
        *(ctx->pos++) = 'e';
    } else {
        *(ctx->pos++) = 'f';
        *(ctx->pos++) = 'a';
        *(ctx->pos++) = 'l';
        *(ctx->pos++) = 's';
        *(ctx->pos++) = 'e';
    }
    return UA_STATUSCODE_GOOD;
}

/*****************/
/* Integer Types */
/*****************/

/* Byte */
ENCODE_JSON(Byte) {
    char buf[4];
    UA_UInt16 digits = itoaUnsigned(*src, buf, 10);

    /* Ensure destination can hold the data- */
    if(ctx->pos + digits > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    /* Copy digits to the output string/buffer. */
    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, digits);
    ctx->pos += digits;
    return UA_STATUSCODE_GOOD;
}

/* signed Byte */
ENCODE_JSON(SByte) {
    char buf[5];
    UA_UInt16 digits = itoaSigned(*src, buf);
    if(ctx->pos + digits > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, digits);
    ctx->pos += digits;
    return UA_STATUSCODE_GOOD;
}

/* UInt16 */
ENCODE_JSON(UInt16) {
    char buf[6];
    UA_UInt16 digits = itoaUnsigned(*src, buf, 10);

    if(ctx->pos + digits > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, digits);
    ctx->pos += digits;
    return UA_STATUSCODE_GOOD;
}

/* Int16 */
ENCODE_JSON(Int16) {
    char buf[7];
    UA_UInt16 digits = itoaSigned(*src, buf);

    if(ctx->pos + digits > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, digits);
    ctx->pos += digits;
    return UA_STATUSCODE_GOOD;
}

/* UInt32 */
ENCODE_JSON(UInt32) {
    char buf[11];
    UA_UInt16 digits = itoaUnsigned(*src, buf, 10);

    if(ctx->pos + digits > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, digits);
    ctx->pos += digits;
    return UA_STATUSCODE_GOOD;
}

/* Int32 */
ENCODE_JSON(Int32) {
    char buf[12];
    UA_UInt16 digits = itoaSigned(*src, buf);

    if(ctx->pos + digits > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, digits);
    ctx->pos += digits;
    return UA_STATUSCODE_GOOD;
}

/* UInt64 */
ENCODE_JSON(UInt64) {
    char buf[23];
    buf[0] = '\"';
    UA_UInt16 digits = itoaUnsigned(*src, buf + 1, 10);
    buf[digits + 1] = '\"';
    UA_UInt16 length = (UA_UInt16)(digits + 2);

    if(ctx->pos + length > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, length);

    ctx->pos += length;
    return UA_STATUSCODE_GOOD;
}

/* Int64 */
ENCODE_JSON(Int64) {
    char buf[23];
    buf[0] = '\"';
    UA_UInt16 digits = itoaSigned(*src, buf + 1);
    buf[digits + 1] = '\"';
    UA_UInt16 length = (UA_UInt16)(digits + 2);

    if(ctx->pos + length > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buf, length);
    ctx->pos += length;
    return UA_STATUSCODE_GOOD;
}

/************************/
/* Floating Point Types */
/************************/

/* Convert special numbers to string
 * - fmt_fp gives NAN, nan,-NAN, -nan, inf, INF, -inf, -INF
 * - Special floating-point numbers such as positive infinity (INF), negative
 *   infinity (-INF) and not-a-number (NaN) shall be represented by the values
 *   “Infinity”, “-Infinity” and “NaN” encoded as a JSON string. */
static status
checkAndEncodeSpecialFloatingPoint(char *buffer, size_t *len) {
    /*nan and NaN*/
    if(*len == 3 && 
            (buffer[0] == 'n' || buffer[0] == 'N') && 
            (buffer[1] == 'a' || buffer[1] == 'A') && 
            (buffer[2] == 'n' || buffer[2] == 'N')) {
        *len = 5;
        memcpy(buffer, "\"NaN\"", *len);
        return UA_STATUSCODE_GOOD;
    }

    /*-nan and -NaN*/
    if(*len == 4 && buffer[0] == '-' && 
            (buffer[1] == 'n' || buffer[1] == 'N') && 
            (buffer[2] == 'a' || buffer[2] == 'A') && 
            (buffer[3] == 'n' || buffer[3] == 'N')) {
        *len = 6;
        memcpy(buffer, "\"-NaN\"", *len);
        return UA_STATUSCODE_GOOD;
    }

    /*inf*/
    if(*len == 3 && 
            (buffer[0] == 'i' || buffer[0] == 'I') && 
            (buffer[1] == 'n' || buffer[1] == 'N') && 
            (buffer[2] == 'f' || buffer[2] == 'F')) {
        *len = 10;
        memcpy(buffer, "\"Infinity\"", *len);
        return UA_STATUSCODE_GOOD;
    }

    /*-inf*/
    if(*len == 4 && buffer[0] == '-' && 
            (buffer[1] == 'i' || buffer[1] == 'I') && 
            (buffer[2] == 'n' || buffer[2] == 'N') && 
            (buffer[3] == 'f' || buffer[3] == 'F')) {
        *len = 11;
        memcpy(buffer, "\"-Infinity\"", *len);
        return UA_STATUSCODE_GOOD;
    }
    return UA_STATUSCODE_GOOD;
}

ENCODE_JSON(Float) {
    char buffer[200];
    if(*src == *src) {
#ifdef UA_ENABLE_CUSTOM_LIBC
        fmt_fp(buffer, *src, 0, -1, 0, 'g');
#else
        UA_snprintf(buffer, 200, "%.149g", (UA_Double)*src);
#endif
    } else {
        strcpy(buffer, "NaN");
    }

    size_t len = strlen(buffer);
    if(len == 0)
        return UA_STATUSCODE_BADENCODINGERROR;
    
    checkAndEncodeSpecialFloatingPoint(buffer, &len);
    
    if(ctx->pos + len > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buffer, len);

    ctx->pos += len;
    return UA_STATUSCODE_GOOD;
}

ENCODE_JSON(Double) {
    char buffer[2000];
    if(*src == *src) {
#ifdef UA_ENABLE_CUSTOM_LIBC
        fmt_fp(buffer, *src, 0, 17, 0, 'g');
#else
        UA_snprintf(buffer, 2000, "%.1074g", *src);
#endif
    } else {
        strcpy(buffer, "NaN");
    }

    size_t len = strlen(buffer);
    checkAndEncodeSpecialFloatingPoint(buffer, &len);    

    if(ctx->pos + len > ctx->end)
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;

    if(!ctx->calcOnly)
        memcpy(ctx->pos, buffer, len);

    ctx->pos += len;
    return UA_STATUSCODE_GOOD;
}

static status
encodeJsonArray(CtxJson *ctx, const void *ptr, size_t length,
                const UA_DataType *type) {
    encodeJsonSignature encodeType = encodeJsonJumpTable[type->typeKind];
    status ret = writeJsonArrStart(ctx);
    uintptr_t uptr = (uintptr_t)ptr;
    for(size_t i = 0; i < length && ret == UA_STATUSCODE_GOOD; ++i) {
        ret |= writeJsonCommaIfNeeded(ctx);
        ret |= encodeType((const void*)uptr, type, ctx);
        ctx->commaNeeded[ctx->depth] = true;
        uptr += type->memSize;
    }
    ret |= writeJsonArrEnd(ctx);
    return ret;
}

/*****************/
/* Builtin Types */
/*****************/

static const u8 hexmapLower[16] =
    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
static const u8 hexmapUpper[16] =
    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

ENCODE_JSON(String) {
    if(!src->data)
        return writeJsonNull(ctx);

    if(src->length == 0) {
        status retval = writeJsonQuote(ctx);
        retval |= writeJsonQuote(ctx);
        return  retval;
    }

    UA_StatusCode ret = writeJsonQuote(ctx);
    
    /* Escaping adapted from https://github.com/akheron/jansson dump.c */

    const char *str = (char*)src->data;
    const char *pos = str;
    const char *end = str;
    const char *lim = str + src->length;
    UA_UInt32 codepoint = 0;
    while(1) {
        const char *text;
        u8 seq[13];
        size_t length;

        while(end < lim) {
            end = utf8_iterate(pos, (size_t)(lim - pos), (int32_t *)&codepoint);
            if(!end)
                return UA_STATUSCODE_BADENCODINGERROR;

            /* mandatory escape or control char */
            if(codepoint == '\\' || codepoint == '"' || codepoint < 0x20)
                break;

            /* TODO: Why is this commented? */
            /* slash 
            if((flags & JSON_ESCAPE_SLASH) && codepoint == '/')
                break;*/

            /* non-ASCII
            if((flags & JSON_ENSURE_ASCII) && codepoint > 0x7F)
                break;*/

            pos = end;
        }

        if(pos != str) {
            if(ctx->pos + (pos - str) > ctx->end)
                return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
            if(!ctx->calcOnly)
                memcpy(ctx->pos, str, (size_t)(pos - str));
            ctx->pos += pos - str;
        }

        if(end == pos)
            break;

        /* handle \, /, ", and control codes */
        length = 2;
        switch(codepoint) {
        case '\\': text = "\\\\"; break;
        case '\"': text = "\\\""; break;
        case '\b': text = "\\b"; break;
        case '\f': text = "\\f"; break;
        case '\n': text = "\\n"; break;
        case '\r': text = "\\r"; break;
        case '\t': text = "\\t"; break;
        case '/':  text = "\\/"; break;
        default:
            if(codepoint < 0x10000) {
                /* codepoint is in BMP */
                seq[0] = '\\';
                seq[1] = 'u';
                UA_Byte b1 = (UA_Byte)(codepoint >> 8u);
                UA_Byte b2 = (UA_Byte)(codepoint >> 0u);
                seq[2] = hexmapLower[(b1 & 0xF0u) >> 4u];
                seq[3] = hexmapLower[b1 & 0x0Fu];
                seq[4] = hexmapLower[(b2 & 0xF0u) >> 4u];
                seq[5] = hexmapLower[b2 & 0x0Fu];
                length = 6;
            } else {
                /* not in BMP -> construct a UTF-16 surrogate pair */
                codepoint -= 0x10000;
                UA_UInt32 first = 0xD800u | ((codepoint & 0xffc00u) >> 10u);
                UA_UInt32 last = 0xDC00u | (codepoint & 0x003ffu);

                UA_Byte fb1 = (UA_Byte)(first >> 8u);
                UA_Byte fb2 = (UA_Byte)(first >> 0u);
                    
                UA_Byte lb1 = (UA_Byte)(last >> 8u);
                UA_Byte lb2 = (UA_Byte)(last >> 0u);
                    
                seq[0] = '\\';
                seq[1] = 'u';
                seq[2] = hexmapLower[(fb1 & 0xF0u) >> 4u];
                seq[3] = hexmapLower[fb1 & 0x0Fu];
                seq[4] = hexmapLower[(fb2 & 0xF0u) >> 4u];
                seq[5] = hexmapLower[fb2 & 0x0Fu];
                    
                seq[6] = '\\';
                seq[7] = 'u';
                seq[8] = hexmapLower[(lb1 & 0xF0u) >> 4u];
                seq[9] = hexmapLower[lb1 & 0x0Fu];
                seq[10] = hexmapLower[(lb2 & 0xF0u) >> 4u];
                seq[11] = hexmapLower[lb2 & 0x0Fu];
                length = 12;
            }
            text = (char*)seq;
            break;
        }

        if(ctx->pos + length > ctx->end)
            return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
        if(!ctx->calcOnly)
            memcpy(ctx->pos, text, length);
        ctx->pos += length;
        str = pos = end;
    }

    ret |= writeJsonQuote(ctx);
    return ret;
}
    
ENCODE_JSON(ByteString) {
    if(!src->data)
        return writeJsonNull(ctx);

    if(src->length == 0) {
        status retval = writeJsonQuote(ctx);
        retval |= writeJsonQuote(ctx);
        return retval;
    }

    status ret = writeJsonQuote(ctx);
    size_t flen = 0;
    unsigned char *ba64 = UA_base64(src->data, src->length, &flen);
    
    /* Not converted, no mem */
    if(!ba64)
        return UA_STATUSCODE_BADENCODINGERROR;

    if(ctx->pos + flen > ctx->end) {
        UA_free(ba64);
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
    }
    
    /* Copy flen bytes to output stream. */
    if(!ctx->calcOnly)
        memcpy(ctx->pos, ba64, flen);
    ctx->pos += flen;

    /* Base64 result no longer needed */
    UA_free(ba64);
    
    ret |= writeJsonQuote(ctx);
    return ret;
}

/* Converts Guid to a hexadecimal represenation */
static void UA_Guid_to_hex(const UA_Guid *guid, u8* out) {
    /*
                          16 byte
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |   data1   |data2|data3|          data4        |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
       |aa aa aa aa-bb bb-cc cc-dd dd-ee ee ee ee ee ee|
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
                          36 character
    */

#ifdef hexCharlowerCase
    const u8 *hexmap = hexmapLower;
#else
    const u8 *hexmap = hexmapUpper;
#endif
    size_t i = 0, j = 28;
    for(; i<8;i++,j-=4)         /* pos 0-7, 4byte, (a) */
        out[i] = hexmap[(guid->data1 >> j) & 0x0Fu];
    out[i++] = '-';             /* pos 8 */
    for(j=12; i<13;i++,j-=4)    /* pos 9-12, 2byte, (b) */
        out[i] = hexmap[(uint16_t)(guid->data2 >> j) & 0x0Fu];
    out[i++] = '-';             /* pos 13 */
    for(j=12; i<18;i++,j-=4)    /* pos 14-17, 2byte (c) */
        out[i] = hexmap[(uint16_t)(guid->data3 >> j) & 0x0Fu];
    out[i++] = '-';             /* pos 18 */
    for(j=0;i<23;i+=2,j++) {     /* pos 19-22, 2byte (d) */
        out[i] = hexmap[(guid->data4[j] & 0xF0u) >> 4u];
        out[i+1] = hexmap[guid->data4[j] & 0x0Fu];
    }
    out[i++] = '-';             /* pos 23 */
    for(j=2; i<36;i+=2,j++) {    /* pos 24-35, 6byte (e) */
        out[i] = hexmap[(guid->data4[j] & 0xF0u) >> 4u];
        out[i+1] = hexmap[guid->data4[j] & 0x0Fu];
    }
}

/* Guid */
ENCODE_JSON(Guid) {
    if(ctx->pos + 38 > ctx->end) /* 36 + 2 (") */
        return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
    status ret = writeJsonQuote(ctx);
    u8 *buf = ctx->pos;
    if(!ctx->calcOnly)
        UA_Guid_to_hex(src, buf);
    ctx->pos += 36;
    ret |= writeJsonQuote(ctx);
    return ret;
}

static void
printNumber(u16 n, u8 *pos, size_t digits) {
    for(size_t i = digits; i > 0; --i) {
        pos[i - 1] = (u8) ((n % 10) + '0');
        n = n / 10;
    }
}

ENCODE_JSON(DateTime) {
    UA_DateTimeStruct tSt = UA_DateTime_toStruct(*src);

    /* Format: yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z' is used. max 30 bytes.*/
    UA_Byte buffer[UA_JSON_DATETIME_LENGTH];

    printNumber(tSt.year, &buffer[0], 4);
    buffer[4] = '-';
    printNumber(tSt.month, &buffer[5], 2);
    buffer[7] = '-';
    printNumber(tSt.day, &buffer[8], 2);
    buffer[10] = 'T';
    printNumber(tSt.hour, &buffer[11], 2);
    buffer[13] = ':';
    printNumber(tSt.min, &buffer[14], 2);
    buffer[16] = ':';
    printNumber(tSt.sec, &buffer[17], 2);
    buffer[19] = '.';
    printNumber(tSt.milliSec, &buffer[20], 3);
    printNumber(tSt.microSec, &buffer[23], 3);
    printNumber(tSt.nanoSec, &buffer[26], 3);

    size_t length = 28;
    while (buffer[length] == '0')
        length--;
    if (length != 19)
         length++;

    buffer[length] = 'Z';
    UA_String str = {length + 1, buffer};
    return ENCODE_DIRECT_JSON(&str, String);
}

/* NodeId */
static status
NodeId_encodeJsonInternal(UA_NodeId const *src, CtxJson *ctx) {
    status ret = UA_STATUSCODE_GOOD;
    switch (src->identifierType) {
    case UA_NODEIDTYPE_NUMERIC:
        ret |= writeJsonKey(ctx, UA_JSONKEY_ID);
        ret |= ENCODE_DIRECT_JSON(&src->identifier.numeric, UInt32);
        break;
    case UA_NODEIDTYPE_STRING:
        ret |= writeJsonKey(ctx, UA_JSONKEY_IDTYPE);
        ret |= writeChar(ctx, '1');
        ret |= writeJsonKey(ctx, UA_JSONKEY_ID);
        ret |= ENCODE_DIRECT_JSON(&src->identifier.string, String);
        break;
    case UA_NODEIDTYPE_GUID:
        ret |= writeJsonKey(ctx, UA_JSONKEY_IDTYPE);
        ret |= writeChar(ctx, '2');
        ret |= writeJsonKey(ctx, UA_JSONKEY_ID); /* Id */
        ret |= ENCODE_DIRECT_JSON(&src->identifier.guid, Guid);
        break;
    case UA_NODEIDTYPE_BYTESTRING:
        ret |= writeJsonKey(ctx, UA_JSONKEY_IDTYPE);
        ret |= writeChar(ctx, '3');
        ret |= writeJsonKey(ctx, UA_JSONKEY_ID); /* Id */
        ret |= ENCODE_DIRECT_JSON(&src->identifier.byteString, ByteString);
        break;
    default:
        return UA_STATUSCODE_BADINTERNALERROR;
    }
    return ret;
}

ENCODE_JSON(NodeId) {
    UA_StatusCode ret = writeJsonObjStart(ctx);
    ret |= NodeId_encodeJsonInternal(src, ctx);
    if(ctx->useReversible) {
        if(src->namespaceIndex > 0) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
            ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
        }
    } else {
        /* For the non-reversible encoding, the field is the NamespaceUri 
         * associated with the NamespaceIndex, encoded as a JSON string.
         * A NamespaceIndex of 1 is always encoded as a JSON number. */
        if(src->namespaceIndex == 1) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
            ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
        } else {
            ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
            
            /* Check if Namespace given and in range */
            if(src->namespaceIndex < ctx->namespacesSize && ctx->namespaces != NULL) {
                UA_String namespaceEntry = ctx->namespaces[src->namespaceIndex];
                ret |= ENCODE_DIRECT_JSON(&namespaceEntry, String);
            } else {
                return UA_STATUSCODE_BADNOTFOUND;
            }
        }
    }

    ret |= writeJsonObjEnd(ctx);
    return ret;
}

/* ExpandedNodeId */
ENCODE_JSON(ExpandedNodeId) {
    status ret = writeJsonObjStart(ctx);
    /* Encode the NodeId */
    ret |= NodeId_encodeJsonInternal(&src->nodeId, ctx);
    
    if(ctx->useReversible) {
        if(src->namespaceUri.data != NULL && src->namespaceUri.length != 0 && 
           (void*) src->namespaceUri.data > UA_EMPTY_ARRAY_SENTINEL) {
            /* If the NamespaceUri is specified it is encoded as a JSON string in this field. */ 
            ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
            ret |= ENCODE_DIRECT_JSON(&src->namespaceUri, String);
        } else {
            /* If the NamespaceUri is not specified, the NamespaceIndex is encoded with these rules:
             * The field is encoded as a JSON number for the reversible encoding.
             * The field is omitted if the NamespaceIndex equals 0. */
            if(src->nodeId.namespaceIndex > 0) {
                ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
                ret |= ENCODE_DIRECT_JSON(&src->nodeId.namespaceIndex, UInt16);
            }
        }

        /* Encode the serverIndex/Url 
         * This field is encoded as a JSON number for the reversible encoding.
         * This field is omitted if the ServerIndex equals 0. */
        if(src->serverIndex > 0) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_SERVERURI);
            ret |= ENCODE_DIRECT_JSON(&src->serverIndex, UInt32);
        }

        ret |= writeJsonObjEnd(ctx);
        return ret;
    }
    
    
    /* NON-Reversible Case */

    /* If the NamespaceUri is not specified, the NamespaceIndex is encoded with these rules:
     * For the non-reversible encoding the field is the NamespaceUri associated with the
     * NamespaceIndex encoded as a JSON string.
     * A NamespaceIndex of 1 is always encoded as a JSON number. */

    if(src->namespaceUri.data != NULL && src->namespaceUri.length != 0) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
        ret |= ENCODE_DIRECT_JSON(&src->namespaceUri, String);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    } else {
        if(src->nodeId.namespaceIndex == 1) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);
            ret |= ENCODE_DIRECT_JSON(&src->nodeId.namespaceIndex, UInt16);
            if(ret != UA_STATUSCODE_GOOD)
                return ret;
        } else {
            ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACE);

            /* Check if Namespace given and in range */
            if(src->nodeId.namespaceIndex < ctx->namespacesSize 
                    && ctx->namespaces != NULL) {

                UA_String namespaceEntry = ctx->namespaces[src->nodeId.namespaceIndex];
                ret |= ENCODE_DIRECT_JSON(&namespaceEntry, String);
                if(ret != UA_STATUSCODE_GOOD)
                    return ret;
            } else {
                return UA_STATUSCODE_BADNOTFOUND;
            }
        }
    }

    /* For the non-reversible encoding, this field is the ServerUri associated
     * with the ServerIndex portion of the ExpandedNodeId, encoded as a JSON
     * string. */

    /* Check if Namespace given and in range */
    if(src->serverIndex < ctx->serverUrisSize && ctx->serverUris != NULL) {
        UA_String serverUriEntry = ctx->serverUris[src->serverIndex];
        ret |= writeJsonKey(ctx, UA_JSONKEY_SERVERURI);
        ret |= ENCODE_DIRECT_JSON(&serverUriEntry, String);
    } else {
        return UA_STATUSCODE_BADNOTFOUND;
    }
    ret |= writeJsonObjEnd(ctx);
    return ret;
}

/* LocalizedText */
ENCODE_JSON(LocalizedText) {
    if(ctx->useReversible) {
        status ret = writeJsonObjStart(ctx);
        ret |= writeJsonKey(ctx, UA_JSONKEY_LOCALE);
        ret |= ENCODE_DIRECT_JSON(&src->locale, String);
        ret |= writeJsonKey(ctx, UA_JSONKEY_TEXT);
        ret |= ENCODE_DIRECT_JSON(&src->text, String);
        ret |= writeJsonObjEnd(ctx);
        return ret;
    }
    
    /* For the non-reversible form, LocalizedText value shall be encoded as a
     * JSON string containing the Text component.*/
    return ENCODE_DIRECT_JSON(&src->text, String);
}

ENCODE_JSON(QualifiedName) {
    status ret = writeJsonObjStart(ctx);
    ret |= writeJsonKey(ctx, UA_JSONKEY_NAME);
    ret |= ENCODE_DIRECT_JSON(&src->name, String);

    if(ctx->useReversible) {
        if(src->namespaceIndex != 0) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_URI);
            ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
        }
    } else {
        /* For the non-reversible form, the NamespaceUri associated with the
         * NamespaceIndex portion of the QualifiedName is encoded as JSON string
         * unless the NamespaceIndex is 1 or if NamespaceUri is unknown. In
         * these cases, the NamespaceIndex is encoded as a JSON number. */
        if(src->namespaceIndex == 1) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_URI);
            ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
        } else {
            ret |= writeJsonKey(ctx, UA_JSONKEY_URI);

             /* Check if Namespace given and in range */
            if(src->namespaceIndex < ctx->namespacesSize && ctx->namespaces != NULL) {
                UA_String namespaceEntry = ctx->namespaces[src->namespaceIndex];
                ret |= ENCODE_DIRECT_JSON(&namespaceEntry, String);
            } else {
                /* If not encode as number */
                ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
            }
        }
    }

    return ret | writeJsonObjEnd(ctx);
}

ENCODE_JSON(StatusCode) {
    if(!src)
        return writeJsonNull(ctx);

    if(ctx->useReversible)
        return ENCODE_DIRECT_JSON(src, UInt32);

    if(*src == UA_STATUSCODE_GOOD)
        return writeJsonNull(ctx);

    status ret = UA_STATUSCODE_GOOD;
    ret |= writeJsonObjStart(ctx);
    ret |= writeJsonKey(ctx, UA_JSONKEY_CODE);
    ret |= ENCODE_DIRECT_JSON(src, UInt32);
    ret |= writeJsonKey(ctx, UA_JSONKEY_SYMBOL);
    const char *codename = UA_StatusCode_name(*src);
    UA_String statusDescription = UA_STRING((char*)(uintptr_t)codename);
    ret |= ENCODE_DIRECT_JSON(&statusDescription, String);
    ret |= writeJsonObjEnd(ctx);
    return ret;
}

/* ExtensionObject */
ENCODE_JSON(ExtensionObject) {
    u8 encoding = (u8) src->encoding;
    if(encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY)
        return writeJsonNull(ctx);
    
    status ret = UA_STATUSCODE_GOOD;
    /* already encoded content.*/
    if(encoding <= UA_EXTENSIONOBJECT_ENCODED_XML) {
        ret |= writeJsonObjStart(ctx);
        if(ctx->useReversible) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_TYPEID);
            ret |= ENCODE_DIRECT_JSON(&src->content.encoded.typeId, NodeId);
            if(ret != UA_STATUSCODE_GOOD)
                return ret;
        }
        
        switch (src->encoding) {
            case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
            {
                if(ctx->useReversible) {
                    ret |= writeJsonKey(ctx, UA_JSONKEY_ENCODING);
                    ret |= writeChar(ctx, '1');
                }
                ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
                ret |= ENCODE_DIRECT_JSON(&src->content.encoded.body, String);
                break;
            }
            case UA_EXTENSIONOBJECT_ENCODED_XML:
            {
                if(ctx->useReversible) {
                    ret |= writeJsonKey(ctx, UA_JSONKEY_ENCODING);
                    ret |= writeChar(ctx, '2');
                }
                ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
                ret |= ENCODE_DIRECT_JSON(&src->content.encoded.body, String);
                break;
            }
            default:
                ret = UA_STATUSCODE_BADINTERNALERROR;
        }

        ret |= writeJsonObjEnd(ctx);
        return ret;
    } /* encoding <= UA_EXTENSIONOBJECT_ENCODED_XML */
         
    /* Cannot encode with no type description */
    if(!src->content.decoded.type)
        return UA_STATUSCODE_BADENCODINGERROR;

    if(!src->content.decoded.data)
        return writeJsonNull(ctx);

    UA_NodeId typeId = src->content.decoded.type->typeId;
    if(typeId.identifierType != UA_NODEIDTYPE_NUMERIC)
        return UA_STATUSCODE_BADENCODINGERROR;

    ret |= writeJsonObjStart(ctx);
    const UA_DataType *contentType = src->content.decoded.type;
    if(ctx->useReversible) {
        /* REVERSIBLE */
        ret |= writeJsonKey(ctx, UA_JSONKEY_TYPEID);
        ret |= ENCODE_DIRECT_JSON(&typeId, NodeId);

        /* Encode the content */
        ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
        ret |= encodeJsonInternal(src->content.decoded.data, contentType, ctx);
    } else {
        /* NON-REVERSIBLE
         * For the non-reversible form, ExtensionObject values 
         * shall be encoded as a JSON object containing only the 
         * value of the Body field. The TypeId and Encoding fields are dropped.
         * 
         * TODO: UA_JSONKEY_BODY key in the ExtensionObject?
         */
        ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
        ret |= encodeJsonInternal(src->content.decoded.data, contentType, ctx);
    }

    ret |= writeJsonObjEnd(ctx);
    return ret;
}

static status
Variant_encodeJsonWrapExtensionObject(const UA_Variant *src, const bool isArray, CtxJson *ctx) {
    size_t length = 1;

    status ret = UA_STATUSCODE_GOOD;
    if(isArray) {
        if(src->arrayLength > UA_INT32_MAX)
            return UA_STATUSCODE_BADENCODINGERROR;
        
        length = src->arrayLength;
    }

    /* Set up the ExtensionObject */
    UA_ExtensionObject eo;
    UA_ExtensionObject_init(&eo);
    eo.encoding = UA_EXTENSIONOBJECT_DECODED;
    eo.content.decoded.type = src->type;
    const u16 memSize = src->type->memSize;
    uintptr_t ptr = (uintptr_t) src->data;

    if(isArray) {
        ret |= writeJsonArrStart(ctx);
        ctx->commaNeeded[ctx->depth] = false;

        /* Iterate over the array */
        for(size_t i = 0; i <  length && ret == UA_STATUSCODE_GOOD; ++i) {
            eo.content.decoded.data = (void*) ptr;
            ret |= writeJsonArrElm(ctx, &eo, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]);
            ptr += memSize;
        }
    
        ret |= writeJsonArrEnd(ctx);
        return ret;
    }

    eo.content.decoded.data = (void*) ptr;
    return encodeJsonInternal(&eo, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], ctx);
}

static status
addMultiArrayContentJSON(CtxJson *ctx, void* array, const UA_DataType *type, 
                         size_t *index, UA_UInt32 *arrayDimensions, size_t dimensionIndex, 
                         size_t dimensionSize) {
    /* Check the recursion limit */
    if(ctx->depth > UA_JSON_ENCODING_MAX_RECURSION)
        return UA_STATUSCODE_BADENCODINGERROR;
    
    /* Stop recursion: The inner Arrays are written */
    status ret;
    if(dimensionIndex == (dimensionSize - 1)) {
        ret = encodeJsonArray(ctx, ((u8*)array) + (type->memSize * *index),
                              arrayDimensions[dimensionIndex], type);
        (*index) += arrayDimensions[dimensionIndex];
        return ret;
    }

    /* Recurse to the next dimension */
    ret = writeJsonArrStart(ctx);
    for(size_t i = 0; i < arrayDimensions[dimensionIndex]; i++) {
        ret |= writeJsonCommaIfNeeded(ctx);
        ret |= addMultiArrayContentJSON(ctx, array, type, index, arrayDimensions,
                                        dimensionIndex + 1, dimensionSize);
        ctx->commaNeeded[ctx->depth] = true;
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }
    ret |= writeJsonArrEnd(ctx);
    return ret;
}

ENCODE_JSON(Variant) {
    /* If type is 0 (NULL) the Variant contains a NULL value and the containing
     * JSON object shall be omitted or replaced by the JSON literal ‘null’ (when
     * an element of a JSON array). */
    if(!src->type) {
        return writeJsonNull(ctx);
    }
        
    /* Set the content type in the encoding mask */
    const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
    const UA_Boolean isEnum = (src->type->typeKind == UA_DATATYPEKIND_ENUM);
    
    /* Set the array type in the encoding mask */
    const bool isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL;
    const bool hasDimensions = isArray && src->arrayDimensionsSize > 0;
    status ret = UA_STATUSCODE_GOOD;
    
    if(ctx->useReversible) {
        ret |= writeJsonObjStart(ctx);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;

        /* Encode the content */
        if(!isBuiltin && !isEnum) {
            /* REVERSIBLE:  NOT BUILTIN, can it be encoded? Wrap in extension object.*/
            ret |= writeJsonKey(ctx, UA_JSONKEY_TYPE);
            ret |= ENCODE_DIRECT_JSON(&UA_TYPES[UA_TYPES_EXTENSIONOBJECT].typeId.identifier.numeric, UInt32);
            ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
            ret |= Variant_encodeJsonWrapExtensionObject(src, isArray, ctx);
        } else if(!isArray) {
            /*REVERSIBLE:  BUILTIN, single value.*/
            ret |= writeJsonKey(ctx, UA_JSONKEY_TYPE);
            ret |= ENCODE_DIRECT_JSON(&src->type->typeId.identifier.numeric, UInt32);
            ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
            ret |= encodeJsonInternal(src->data, src->type, ctx);
        } else {
            /*REVERSIBLE:   BUILTIN, array.*/
            ret |= writeJsonKey(ctx, UA_JSONKEY_TYPE);
            ret |= ENCODE_DIRECT_JSON(&src->type->typeId.identifier.numeric, UInt32);
            ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
            ret |= encodeJsonArray(ctx, src->data, src->arrayLength, src->type);
        }
        
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
        
        /* REVERSIBLE:  Encode the array dimensions */
        if(hasDimensions && ret == UA_STATUSCODE_GOOD) {
            ret |= writeJsonKey(ctx, UA_JSONKEY_DIMENSION);
            ret |= encodeJsonArray(ctx, src->arrayDimensions, src->arrayDimensionsSize, 
                                   &UA_TYPES[UA_TYPES_INT32]);
            if(ret != UA_STATUSCODE_GOOD)
                return ret;
        }

        ret |= writeJsonObjEnd(ctx);
        return ret;
    } /* reversible */

    
    /* NON-REVERSIBLE
     * For the non-reversible form, Variant values shall be encoded as a JSON object containing only
     * the value of the Body field. The Type and Dimensions fields are dropped. Multi-dimensional
     * arrays are encoded as a multi dimensional JSON array as described in 5.4.5.
     */

    ret |= writeJsonObjStart(ctx);
    if(!isBuiltin && !isEnum) {
        /*NON REVERSIBLE:  NOT BUILTIN, can it be encoded? Wrap in extension object.*/
        if(src->arrayDimensionsSize > 1) {
            return UA_STATUSCODE_BADNOTIMPLEMENTED;
        }

        ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
        ret |= Variant_encodeJsonWrapExtensionObject(src, isArray, ctx);
    } else if(!isArray) {
        /*NON REVERSIBLE:   BUILTIN, single value.*/
        ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);
        ret |= encodeJsonInternal(src->data, src->type, ctx);
    } else {
        /*NON REVERSIBLE:   BUILTIN, array.*/
        ret |= writeJsonKey(ctx, UA_JSONKEY_BODY);

        size_t dimensionSize = src->arrayDimensionsSize;
        if(dimensionSize > 1) {
            /*nonreversible multidimensional array*/
            size_t index = 0;  size_t dimensionIndex = 0;
            void *ptr = src->data;
            const UA_DataType *arraytype = src->type;
            ret |= addMultiArrayContentJSON(ctx, ptr, arraytype, &index, 
                    src->arrayDimensions, dimensionIndex, dimensionSize);
        } else {
            /*nonreversible simple array*/
            ret |= encodeJsonArray(ctx, src->data, src->arrayLength, src->type);
        }
    }

    ret |= writeJsonObjEnd(ctx);
    return ret;
}

/* DataValue */
ENCODE_JSON(DataValue) {
    UA_Boolean hasValue = src->hasValue && src->value.type != NULL;
    UA_Boolean hasStatus = src->hasStatus && src->status;
    UA_Boolean hasSourceTimestamp = src->hasSourceTimestamp && src->sourceTimestamp;
    UA_Boolean hasSourcePicoseconds = src->hasSourcePicoseconds && src->sourcePicoseconds;
    UA_Boolean hasServerTimestamp = src->hasServerTimestamp && src->serverTimestamp;
    UA_Boolean hasServerPicoseconds = src->hasServerPicoseconds && src->serverPicoseconds;

    if(!hasValue && !hasStatus && !hasSourceTimestamp && !hasSourcePicoseconds &&
       !hasServerTimestamp && !hasServerPicoseconds) {
        return writeJsonNull(ctx); /*no element, encode as null*/
    }

    status ret = UA_STATUSCODE_GOOD;
    ret |= writeJsonObjStart(ctx);

    if(hasValue) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_VALUE);
        ret |= ENCODE_DIRECT_JSON(&src->value, Variant);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(hasStatus) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_STATUS);
        ret |= ENCODE_DIRECT_JSON(&src->status, StatusCode);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(hasSourceTimestamp) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_SOURCETIMESTAMP);
        ret |= ENCODE_DIRECT_JSON(&src->sourceTimestamp, DateTime);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(hasSourcePicoseconds) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_SOURCEPICOSECONDS);
        ret |= ENCODE_DIRECT_JSON(&src->sourcePicoseconds, UInt16);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(hasServerTimestamp) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_SERVERTIMESTAMP);
        ret |= ENCODE_DIRECT_JSON(&src->serverTimestamp, DateTime);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(hasServerPicoseconds) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_SERVERPICOSECONDS);
        ret |= ENCODE_DIRECT_JSON(&src->serverPicoseconds, UInt16);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    ret |= writeJsonObjEnd(ctx);
    return ret;
}

/* DiagnosticInfo */
ENCODE_JSON(DiagnosticInfo) {
    status ret = UA_STATUSCODE_GOOD;
    if(!src->hasSymbolicId && !src->hasNamespaceUri && !src->hasLocalizedText &&
       !src->hasLocale && !src->hasAdditionalInfo && !src->hasInnerDiagnosticInfo &&
       !src->hasInnerStatusCode) {
        return writeJsonNull(ctx); /*no element present, encode as null.*/
    }
    
    ret |= writeJsonObjStart(ctx);
    
    if(src->hasSymbolicId) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_SYMBOLICID);
        ret |= ENCODE_DIRECT_JSON(&src->symbolicId, UInt32);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(src->hasNamespaceUri) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_NAMESPACEURI);
        ret |= ENCODE_DIRECT_JSON(&src->namespaceUri, UInt32);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }
    
    if(src->hasLocalizedText) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_LOCALIZEDTEXT);
        ret |= ENCODE_DIRECT_JSON(&src->localizedText, UInt32);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }
    
    if(src->hasLocale) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_LOCALE);
        ret |= ENCODE_DIRECT_JSON(&src->locale, UInt32);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }
    
    if(src->hasAdditionalInfo) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_ADDITIONALINFO);
        ret |= ENCODE_DIRECT_JSON(&src->additionalInfo, String);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(src->hasInnerStatusCode) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_INNERSTATUSCODE);
        ret |= ENCODE_DIRECT_JSON(&src->innerStatusCode, StatusCode);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    if(src->hasInnerDiagnosticInfo && src->innerDiagnosticInfo) {
        ret |= writeJsonKey(ctx, UA_JSONKEY_INNERDIAGNOSTICINFO);
        /* Check recursion depth in encodeJsonInternal */
        ret |= encodeJsonInternal(src->innerDiagnosticInfo, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], ctx);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
    }

    ret |= writeJsonObjEnd(ctx);
    return ret;
}

static status
encodeJsonStructure(const void *src, const UA_DataType *type, CtxJson *ctx) {
    /* Check the recursion limit */
    if(ctx->depth > UA_JSON_ENCODING_MAX_RECURSION)
        return UA_STATUSCODE_BADENCODINGERROR;
    ctx->depth++;

    status ret = writeJsonObjStart(ctx);

    uintptr_t ptr = (uintptr_t) src;
    u8 membersSize = type->membersSize;
    const UA_DataType * typelists[2] = {UA_TYPES, &type[-type->typeIndex]};
    for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) {
        const UA_DataTypeMember *m = &type->members[i];
        const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex];

        if(m->memberName != NULL && *m->memberName != 0)
            ret |= writeJsonKey(ctx, m->memberName);

        if(!m->isArray) {
            ptr += m->padding;
            size_t memSize = mt->memSize;
            ret |= encodeJsonJumpTable[mt->typeKind]((const void*) ptr, mt, ctx);
            ptr += memSize;
        } else {
            ptr += m->padding;
            const size_t length = *((const size_t*) ptr);
            ptr += sizeof (size_t);
            ret |= encodeJsonArray(ctx, *(void * const *)ptr, length, mt);
            ptr += sizeof (void*);
        }
    }

    ret |= writeJsonObjEnd(ctx);

    ctx->depth--;
    return ret;
}

static status
encodeJsonNotImplemented(const void *src, const UA_DataType *type, CtxJson *ctx) {
    (void) src, (void) type, (void)ctx;
    return UA_STATUSCODE_BADNOTIMPLEMENTED;
}

const encodeJsonSignature encodeJsonJumpTable[UA_DATATYPEKINDS] = {
    (encodeJsonSignature)Boolean_encodeJson,
    (encodeJsonSignature)SByte_encodeJson, /* SByte */
    (encodeJsonSignature)Byte_encodeJson,
    (encodeJsonSignature)Int16_encodeJson, /* Int16 */
    (encodeJsonSignature)UInt16_encodeJson,
    (encodeJsonSignature)Int32_encodeJson, /* Int32 */
    (encodeJsonSignature)UInt32_encodeJson,
    (encodeJsonSignature)Int64_encodeJson, /* Int64 */
    (encodeJsonSignature)UInt64_encodeJson,
    (encodeJsonSignature)Float_encodeJson,
    (encodeJsonSignature)Double_encodeJson,
    (encodeJsonSignature)String_encodeJson,
    (encodeJsonSignature)DateTime_encodeJson, /* DateTime */
    (encodeJsonSignature)Guid_encodeJson,
    (encodeJsonSignature)ByteString_encodeJson, /* ByteString */
    (encodeJsonSignature)String_encodeJson, /* XmlElement */
    (encodeJsonSignature)NodeId_encodeJson,
    (encodeJsonSignature)ExpandedNodeId_encodeJson,
    (encodeJsonSignature)StatusCode_encodeJson, /* StatusCode */
    (encodeJsonSignature)QualifiedName_encodeJson, /* QualifiedName */
    (encodeJsonSignature)LocalizedText_encodeJson,
    (encodeJsonSignature)ExtensionObject_encodeJson,
    (encodeJsonSignature)DataValue_encodeJson,
    (encodeJsonSignature)Variant_encodeJson,
    (encodeJsonSignature)DiagnosticInfo_encodeJson,
    (encodeJsonSignature)encodeJsonNotImplemented, /* Decimal */
    (encodeJsonSignature)Int32_encodeJson, /* Enum */
    (encodeJsonSignature)encodeJsonStructure,
    (encodeJsonSignature)encodeJsonNotImplemented, /* Structure with optional fields */
    (encodeJsonSignature)encodeJsonNotImplemented, /* Union */
    (encodeJsonSignature)encodeJsonNotImplemented /* BitfieldCluster */
};

status
encodeJsonInternal(const void *src, const UA_DataType *type, CtxJson *ctx) {
    return encodeJsonJumpTable[type->typeKind](src, type, ctx);
}

status UA_FUNC_ATTR_WARN_UNUSED_RESULT
UA_encodeJson(const void *src, const UA_DataType *type,
              u8 **bufPos, const u8 **bufEnd, UA_String *namespaces, 
              size_t namespaceSize, UA_String *serverUris, 
              size_t serverUriSize, UA_Boolean useReversible) {
    if(!src || !type)
        return UA_STATUSCODE_BADINTERNALERROR;
    
    /* Set up the context */
    CtxJson ctx;
    memset(&ctx, 0, sizeof(ctx));
    ctx.pos = *bufPos;
    ctx.end = *bufEnd;
    ctx.depth = 0;
    ctx.namespaces = namespaces;
    ctx.namespacesSize = namespaceSize;
    ctx.serverUris = serverUris;
    ctx.serverUrisSize = serverUriSize;
    ctx.useReversible = useReversible;
    ctx.calcOnly = false;
    
    /* Encode */
    status ret = encodeJsonJumpTable[type->typeKind](src, type, &ctx);
    
    *bufPos = ctx.pos;
    *bufEnd = ctx.end;
    return ret;
}

/************/
/* CalcSize */
/************/
size_t
UA_calcSizeJson(const void *src, const UA_DataType *type,
                UA_String *namespaces, size_t namespaceSize,
                UA_String *serverUris, size_t serverUriSize,
                UA_Boolean useReversible) {
    if(!src || !type)
        return UA_STATUSCODE_BADINTERNALERROR;

    /* Set up the context */
    CtxJson ctx;
    memset(&ctx, 0, sizeof(ctx));
    ctx.pos = 0;
    ctx.end = (const UA_Byte*)(uintptr_t)SIZE_MAX;
    ctx.depth = 0;
    ctx.namespaces = namespaces;
    ctx.namespacesSize = namespaceSize;
    ctx.serverUris = serverUris;
    ctx.serverUrisSize = serverUriSize;
    ctx.useReversible = useReversible;
    ctx.calcOnly = true;

    /* Encode */
    status ret = encodeJsonJumpTable[type->typeKind](src, type, &ctx);
    if(ret != UA_STATUSCODE_GOOD)
        return 0;
    return (size_t)ctx.pos;
}

/**********/
/* Decode */
/**********/

/* Macro which gets current size and char pointer of current Token. Needs
 * ParseCtx (parseCtx) and CtxJson (ctx). Does NOT increment index of Token. */
#define GET_TOKEN(data, size) do {                                               \
    (size) = (size_t)(parseCtx->tokenArray[parseCtx->index].end - parseCtx->tokenArray[parseCtx->index].start); \
    (data) = (char*)(ctx->pos + parseCtx->tokenArray[parseCtx->index].start); } while(0)

#define ALLOW_NULL do {             \
    if(isJsonNull(ctx, parseCtx)) { \
        parseCtx->index++;          \
        return UA_STATUSCODE_GOOD;  \
    }} while(0)

#define CHECK_TOKEN_BOUNDS do {                   \
    if(parseCtx->index >= parseCtx->tokenCount)   \
        return UA_STATUSCODE_BADDECODINGERROR;    \
    } while(0)

#define CHECK_PRIMITIVE do {                      \
    if(getJsmnType(parseCtx) != JSMN_PRIMITIVE) { \
        return UA_STATUSCODE_BADDECODINGERROR;    \
    }} while(0)

#define CHECK_STRING do {                      \
    if(getJsmnType(parseCtx) != JSMN_STRING) { \
        return UA_STATUSCODE_BADDECODINGERROR; \
    }} while(0)

#define CHECK_OBJECT do {                      \
    if(getJsmnType(parseCtx) != JSMN_OBJECT) { \
        return UA_STATUSCODE_BADDECODINGERROR; \
    }} while(0)

/* Forward declarations*/
#define DECODE_JSON(TYPE) static status                        \
    TYPE##_decodeJson(UA_##TYPE *dst, const UA_DataType *type, \
                      CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken)

/* decode without moving the token index */
#define DECODE_DIRECT_JSON(DST, TYPE) TYPE##_decodeJson((UA_##TYPE*)DST, NULL, ctx, parseCtx, false)

static status
Array_decodeJson(void *dst, const UA_DataType *type, CtxJson *ctx, 
        ParseCtx *parseCtx, UA_Boolean moveToken);

static status
Array_decodeJson_internal(void **dst, const UA_DataType *type, 
        CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken);

static status
Variant_decodeJsonUnwrapExtensionObject(UA_Variant *dst, const UA_DataType *type, 
        CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken);

/* Json decode Helper */
jsmntype_t
getJsmnType(const ParseCtx *parseCtx) {
    if(parseCtx->index >= parseCtx->tokenCount)
        return JSMN_UNDEFINED;
    return parseCtx->tokenArray[parseCtx->index].type;
}

static UA_Boolean
isJsonTokenNull(const CtxJson *ctx, jsmntok_t *token) {
    if(token->type != JSMN_PRIMITIVE)
        return false;
    char* elem = (char*)(ctx->pos + token->start);
    return (elem[0] == 'n' && elem[1] == 'u' && elem[2] == 'l' && elem[3] == 'l');
}

UA_Boolean
isJsonNull(const CtxJson *ctx, const ParseCtx *parseCtx) {
    if(parseCtx->index >= parseCtx->tokenCount)
        return false;

    if(parseCtx->tokenArray[parseCtx->index].type != JSMN_PRIMITIVE) {
        return false;
    }
    char* elem = (char*)(ctx->pos + parseCtx->tokenArray[parseCtx->index].start);
    return (elem[0] == 'n' && elem[1] == 'u' && elem[2] == 'l' && elem[3] == 'l');
}

static UA_SByte jsoneq(const char *json, jsmntok_t *tok, const char *searchKey) {
    /* TODO: necessary?
       if(json == NULL
            || tok == NULL 
            || searchKey == NULL) {
        return -1;
    } */
    
    if(tok->type == JSMN_STRING) {
         if(strlen(searchKey) == (size_t)(tok->end - tok->start) ) {
             if(strncmp(json + tok->start,
                        (const char*)searchKey, (size_t)(tok->end - tok->start)) == 0) {
                 return 0;
             }   
         }
    }
    return -1;
}

DECODE_JSON(Boolean) {
    CHECK_PRIMITIVE;
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    if(tokenSize == 4 &&
       tokenData[0] == 't' && tokenData[1] == 'r' &&
       tokenData[2] == 'u' && tokenData[3] == 'e') {
        *dst = true;
    } else if(tokenSize == 5 &&
              tokenData[0] == 'f' && tokenData[1] == 'a' &&
              tokenData[2] == 'l' && tokenData[3] == 's' &&
              tokenData[4] == 'e') {
        *dst = false;
    } else {
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    if(moveToken)
        parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

#ifdef UA_ENABLE_CUSTOM_LIBC
static UA_StatusCode
parseUnsignedInteger(char* inputBuffer, size_t sizeOfBuffer,
                     UA_UInt64 *destinationOfNumber) {
    UA_UInt64 d = 0;
    atoiUnsigned(inputBuffer, sizeOfBuffer, &d);
    if(!destinationOfNumber)
        return UA_STATUSCODE_BADDECODINGERROR;
    *destinationOfNumber = d;
    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
parseSignedInteger(char* inputBuffer, size_t sizeOfBuffer,
                   UA_Int64 *destinationOfNumber) {
    UA_Int64 d = 0;
    atoiSigned(inputBuffer, sizeOfBuffer, &d);
    if(!destinationOfNumber)
        return UA_STATUSCODE_BADDECODINGERROR;
    *destinationOfNumber = d;
    return UA_STATUSCODE_GOOD;
}
#else
/* Safe strtol variant of unsigned string conversion.
 * Returns UA_STATUSCODE_BADDECODINGERROR in case of overflows.
 * Buffer limit is 20 digits. */
static UA_StatusCode
parseUnsignedInteger(char* inputBuffer, size_t sizeOfBuffer,
                     UA_UInt64 *destinationOfNumber) {
    /* Check size to avoid huge malicious stack allocation.
     * No UInt64 can have more digits than 20. */
    if(sizeOfBuffer > 20) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }

    /* convert to null terminated string  */
    UA_STACKARRAY(char, string, sizeOfBuffer+1);
    memcpy(string, inputBuffer, sizeOfBuffer);
    string[sizeOfBuffer] = 0;

    /* Conversion */
    char *endptr, *str;
    str = string;
    errno = 0;    /* To distinguish success/failure after call */
    UA_UInt64 val = strtoull(str, &endptr, 10);

    /* Check for various possible errors */
    if((errno == ERANGE && (val == LLONG_MAX || val == 0))
          || (errno != 0 )) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }

    /* Check if no digits were found */
    if(endptr == str)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* copy to destination */
    *destinationOfNumber = val;
    return UA_STATUSCODE_GOOD;
}

/* Safe strtol variant of unsigned string conversion.
 * Returns UA_STATUSCODE_BADDECODINGERROR in case of overflows.
 * Buffer limit is 20 digits. */
static UA_StatusCode
parseSignedInteger(char* inputBuffer, size_t sizeOfBuffer,
                   UA_Int64 *destinationOfNumber) {
    /* Check size to avoid huge malicious stack allocation.
     * No UInt64 can have more digits than 20. */
    if(sizeOfBuffer > 20)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* convert to null terminated string  */
    UA_STACKARRAY(char, string, sizeOfBuffer + 1);
    memcpy(string, inputBuffer, sizeOfBuffer);
    string[sizeOfBuffer] = 0;

    /* Conversion */
    char *endptr, *str;
    str = string;
    errno = 0;    /* To distinguish success/failure after call */
    UA_Int64 val = strtoll(str, &endptr, 10);

    /* Check for various possible errors */
    if((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
          || (errno != 0 )) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }

    /* Check if no digits were found */
    if(endptr == str)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* copy to destination */
    *destinationOfNumber = val;
    return UA_STATUSCODE_GOOD;
}
#endif

DECODE_JSON(Byte) {
    CHECK_TOKEN_BOUNDS;
    CHECK_PRIMITIVE;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_UInt64 out = 0;
    UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_Byte)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(UInt16) {
    CHECK_TOKEN_BOUNDS;
    CHECK_PRIMITIVE;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_UInt64 out = 0;
    UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_UInt16)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(UInt32) {
    CHECK_TOKEN_BOUNDS;
    CHECK_PRIMITIVE;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_UInt64 out = 0;
    UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_UInt32)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(UInt64) {
    CHECK_TOKEN_BOUNDS;
    CHECK_STRING;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_UInt64 out = 0;
    UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_UInt64)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(SByte) {
    CHECK_TOKEN_BOUNDS;
    CHECK_PRIMITIVE;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_Int64 out = 0;
    UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_SByte)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(Int16) {
    CHECK_TOKEN_BOUNDS;
    CHECK_PRIMITIVE;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_Int64 out = 0;
    UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_Int16)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(Int32) {
    CHECK_TOKEN_BOUNDS;
    CHECK_PRIMITIVE;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_Int64 out = 0;
    UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_Int32)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

DECODE_JSON(Int64) {
    CHECK_TOKEN_BOUNDS;
    CHECK_STRING;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    UA_Int64 out = 0;
    UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, &out);
    *dst = (UA_Int64)out;

    if(moveToken)
        parseCtx->index++;
    return s;
}

static UA_UInt32 hex2int(char ch) {
    if(ch >= '0' && ch <= '9')
        return (UA_UInt32)(ch - '0');
    if(ch >= 'A' && ch <= 'F')
        return (UA_UInt32)(ch - 'A' + 10);
    if(ch >= 'a' && ch <= 'f')
        return (UA_UInt32)(ch - 'a' + 10);
    return 0;
}

/* Float
* Either a JSMN_STRING or JSMN_PRIMITIVE
*/
DECODE_JSON(Float) {
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);
    
    /* https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/
     * Maximum digit counts for select IEEE floating-point formats: 149
     * Sanity check. */
    if(tokenSize > 150)
        return UA_STATUSCODE_BADDECODINGERROR;

    jsmntype_t tokenType = getJsmnType(parseCtx);
    if(tokenType == JSMN_STRING) {
        /*It could be a String with Nan, Infinity*/
        if(tokenSize == 8 && memcmp(tokenData, "Infinity", 8) == 0) {
            *dst = (UA_Float)INFINITY;
            return UA_STATUSCODE_GOOD;
        }
        
        if(tokenSize == 9 && memcmp(tokenData, "-Infinity", 9) == 0) {
            /* workaround an MSVC 2013 issue */
            *dst = (UA_Float)-INFINITY;
            return UA_STATUSCODE_GOOD;
        }
        
        if(tokenSize == 3 && memcmp(tokenData, "NaN", 3) == 0) {
            *dst = (UA_Float)NAN;
            return UA_STATUSCODE_GOOD;
        }
        
        if(tokenSize == 4 && memcmp(tokenData, "-NaN", 4) == 0) {
            *dst = (UA_Float)NAN;
            return UA_STATUSCODE_GOOD;
        }
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    if(tokenType != JSMN_PRIMITIVE)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* Null-Terminate for sscanf. */
    UA_STACKARRAY(char, string, tokenSize+1);
    memcpy(string, tokenData, tokenSize);
    string[tokenSize] = 0;
    
    UA_Float d = 0;
#ifdef UA_ENABLE_CUSTOM_LIBC
    d = (UA_Float)__floatscan(string, 1, 0);
#else
    char c = 0;
    /* On success, the function returns the number of variables filled.
     * In the case of an input failure before any data could be successfully read, EOF is returned. */
    int ret = sscanf(string, "%f%c", &d, &c);

    /* Exactly one var must be filled. %c acts as a guard for wrong input which is accepted by sscanf.
    E.g. 1.23.45 is not accepted. */
    if(ret == EOF || (ret != 1))
        return UA_STATUSCODE_BADDECODINGERROR;
#endif
    
    *dst = d;

    parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

/* Either a JSMN_STRING or JSMN_PRIMITIVE */
DECODE_JSON(Double) {
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);
    
    /* https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/
     * Maximum digit counts for select IEEE floating-point formats: 1074
     * Sanity check.
     */
    if(tokenSize > 1075)
        return UA_STATUSCODE_BADDECODINGERROR;

    jsmntype_t tokenType = getJsmnType(parseCtx);
    if(tokenType == JSMN_STRING) {
        /*It could be a String with Nan, Infinity*/
        if(tokenSize == 8 && memcmp(tokenData, "Infinity", 8) == 0) {
            *dst = INFINITY;
            return UA_STATUSCODE_GOOD;
        }
        
        if(tokenSize == 9 && memcmp(tokenData, "-Infinity", 9) == 0) {
            /* workaround an MSVC 2013 issue */
            *dst = -INFINITY;
            return UA_STATUSCODE_GOOD;
        }
        
        if(tokenSize == 3 && memcmp(tokenData, "NaN", 3) == 0) {
            *dst = NAN;
            return UA_STATUSCODE_GOOD;
        }
        
        if(tokenSize == 4 && memcmp(tokenData, "-NaN", 4) == 0) {
            *dst = NAN;
            return UA_STATUSCODE_GOOD;
        }
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    if(tokenType != JSMN_PRIMITIVE)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* Null-Terminate for sscanf. Should this better be handled on heap? Max
     * 1075 input chars allowed. Not using heap. */
    UA_STACKARRAY(char, string, tokenSize+1);
    memcpy(string, tokenData, tokenSize);
    string[tokenSize] = 0;
    
    UA_Double d = 0;
#ifdef UA_ENABLE_CUSTOM_LIBC
    d = (UA_Double)__floatscan(string, 2, 0);
#else
    char c = 0;
    /* On success, the function returns the number of variables filled.
     * In the case of an input failure before any data could be successfully read, EOF is returned. */
    int ret = sscanf(string, "%lf%c", &d, &c);

    /* Exactly one var must be filled. %c acts as a guard for wrong input which is accepted by sscanf.
    E.g. 1.23.45 is not accepted. */
    if(ret == EOF || (ret != 1))
        return UA_STATUSCODE_BADDECODINGERROR;
#endif
    
    *dst = d;

    parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

/*
  Expects 36 chars in format    00000003-0009-000A-0807-060504030201
                                | data1| |d2| |d3| |d4| |  data4   |
*/
static UA_Guid UA_Guid_fromChars(const char* chars) {
    UA_Guid dst;
    UA_Guid_init(&dst);
    for(size_t i = 0; i < 8; i++)
        dst.data1 |= (UA_UInt32)(hex2int(chars[i]) << (28 - (i*4)));
    for(size_t i = 0; i < 4; i++) {
        dst.data2 |= (UA_UInt16)(hex2int(chars[9+i]) << (12 - (i*4)));
        dst.data3 |= (UA_UInt16)(hex2int(chars[14+i]) << (12 - (i*4)));
    }
    dst.data4[0] |= (UA_Byte)(hex2int(chars[19]) << 4u);
    dst.data4[0] |= (UA_Byte)(hex2int(chars[20]) << 0u);
    dst.data4[1] |= (UA_Byte)(hex2int(chars[21]) << 4u);
    dst.data4[1] |= (UA_Byte)(hex2int(chars[22]) << 0u);
    for(size_t i = 0; i < 6; i++) {
        dst.data4[2+i] |= (UA_Byte)(hex2int(chars[24 + i*2]) << 4u);
        dst.data4[2+i] |= (UA_Byte)(hex2int(chars[25 + i*2]) << 0u);
    }
    return dst;
}

DECODE_JSON(Guid) {
    CHECK_STRING;
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    if(tokenSize != 36)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* check if incorrect chars are present */
    for(size_t i = 0; i < tokenSize; i++) {
        if(!(tokenData[i] == '-'
                || (tokenData[i] >= '0' && tokenData[i] <= '9')
                || (tokenData[i] >= 'A' && tokenData[i] <= 'F')
                || (tokenData[i] >= 'a' && tokenData[i] <= 'f'))) {
            return UA_STATUSCODE_BADDECODINGERROR;
        }
    }

    *dst = UA_Guid_fromChars(tokenData);

    if(moveToken)
        parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

DECODE_JSON(String) {
    ALLOW_NULL;
    CHECK_STRING;
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    /* Empty string? */
    if(tokenSize == 0) {
        dst->data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
        dst->length = 0;
        if(moveToken)
            parseCtx->index++;
        return UA_STATUSCODE_GOOD;
    }
    
    /* The actual value is at most of the same length as the source string:
     * - Shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
     * - A single \uXXXX escape (length 6) is converted to at most 3 bytes
     * - Two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair are
     *   converted to 4 bytes */
    char *outputBuffer = (char*)UA_malloc(tokenSize);
    if(!outputBuffer)
        return UA_STATUSCODE_BADOUTOFMEMORY;
    
    const char *p = (char*)tokenData;
    const char *end = (char*)&tokenData[tokenSize];
    char *pos = outputBuffer;
    while(p < end) {
        /* No escaping */
        if(*p != '\\') {
            *(pos++) = *(p++);
            continue;
        }

        /* Escape character */
        p++;
        if(p == end)
            goto cleanup;
        
        if(*p != 'u') {
            switch(*p) {
            case '"': case '\\': case '/': *pos = *p; break;
            case 'b': *pos = '\b'; break;
            case 'f': *pos = '\f'; break;
            case 'n': *pos = '\n'; break;
            case 'r': *pos = '\r'; break;
            case 't': *pos = '\t'; break;
            default: goto cleanup;
            }
            pos++;
            p++;
            continue;
        }
            
        /* Unicode */
        if(p + 4 >= end)
            goto cleanup;
        int32_t value_signed = decode_unicode_escape(p);
        if(value_signed < 0)
            goto cleanup;
        uint32_t value = (uint32_t)value_signed;
        p += 5;

        if(0xD800 <= value && value <= 0xDBFF) {
            /* Surrogate pair */
            if(p + 5 >= end)
                goto cleanup;
            if(*p != '\\' || *(p + 1) != 'u')
                goto cleanup;
            int32_t value2 = decode_unicode_escape(p + 1);
            if(value2 < 0xDC00 || value2 > 0xDFFF)
                goto cleanup;
            value = ((value - 0xD800u) << 10u) + (uint32_t)((value2 - 0xDC00) + 0x10000);
            p += 6;
        } else if(0xDC00 <= value && value <= 0xDFFF) {
            /* Invalid Unicode '\\u%04X' */
            goto cleanup;
        }

        size_t length;
        if(utf8_encode((int32_t)value, pos, &length))
            goto cleanup;

        pos += length;
    }

    dst->length = (size_t)(pos - outputBuffer);
    if(dst->length > 0) {
        dst->data = (UA_Byte*)outputBuffer;
    } else {
        dst->data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
        UA_free(outputBuffer);
    }

    if(moveToken)
        parseCtx->index++;
    return UA_STATUSCODE_GOOD;
    
cleanup:
    UA_free(outputBuffer);  
    return UA_STATUSCODE_BADDECODINGERROR;
}

DECODE_JSON(ByteString) {
    ALLOW_NULL;
    CHECK_STRING;
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);

    /* Empty bytestring? */
    if(tokenSize == 0) {
        dst->data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
        dst->length = 0;
        return UA_STATUSCODE_GOOD;
    }

    size_t flen = 0;
    unsigned char* unB64 = UA_unbase64((unsigned char*)tokenData, tokenSize, &flen);
    if(unB64 == 0)
        return UA_STATUSCODE_BADDECODINGERROR;

    dst->data = (u8*)unB64;
    dst->length = flen;
    
    if(moveToken)
        parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

DECODE_JSON(LocalizedText) {
    ALLOW_NULL;
    CHECK_OBJECT;

    DecodeEntry entries[2] = {
        {UA_JSONKEY_LOCALE, &dst->locale, (decodeJsonSignature) String_decodeJson, false, NULL},
        {UA_JSONKEY_TEXT, &dst->text, (decodeJsonSignature) String_decodeJson, false, NULL}
    };

    return decodeFields(ctx, parseCtx, entries, 2, type);
}

DECODE_JSON(QualifiedName) {
    ALLOW_NULL;
    CHECK_OBJECT;

    DecodeEntry entries[2] = {
        {UA_JSONKEY_NAME, &dst->name, (decodeJsonSignature) String_decodeJson, false, NULL},
        {UA_JSONKEY_URI, &dst->namespaceIndex, (decodeJsonSignature) UInt16_decodeJson, false, NULL}
    };

    return decodeFields(ctx, parseCtx, entries, 2, type);
}

/* Function for searching ahead of the current token. Used for retrieving the
 * OPC UA type of a token */
static status
searchObjectForKeyRec(const char *searchKey, CtxJson *ctx, 
                      ParseCtx *parseCtx, size_t *resultIndex, UA_UInt16 depth) {
    UA_StatusCode ret = UA_STATUSCODE_BADNOTFOUND;
    
    CHECK_TOKEN_BOUNDS;
    
    if(parseCtx->tokenArray[parseCtx->index].type == JSMN_OBJECT) {
        size_t objectCount = (size_t)parseCtx->tokenArray[parseCtx->index].size;
        parseCtx->index++; /*Object to first Key*/
        
        for(size_t i = 0; i < objectCount; i++) {
            CHECK_TOKEN_BOUNDS;
            if(depth == 0) { /* we search only on first layer */
                if(jsoneq((char*)ctx->pos, &parseCtx->tokenArray[parseCtx->index], searchKey) == 0) {
                    /*found*/
                    parseCtx->index++; /*We give back a pointer to the value of the searched key!*/
                    *resultIndex = parseCtx->index;
                    return UA_STATUSCODE_GOOD;
                }
            }
               
            parseCtx->index++; /* value */
            CHECK_TOKEN_BOUNDS;
            
            if(parseCtx->tokenArray[parseCtx->index].type == JSMN_OBJECT) {
               ret = searchObjectForKeyRec(searchKey, ctx, parseCtx, resultIndex,
                                           (UA_UInt16)(depth + 1));
            } else if(parseCtx->tokenArray[parseCtx->index].type == JSMN_ARRAY) {
               ret = searchObjectForKeyRec(searchKey, ctx, parseCtx, resultIndex,
                                           (UA_UInt16)(depth + 1));
            } else {
                /* Only Primitive or string */
                parseCtx->index++;
            }
        }
    } else if(parseCtx->tokenArray[parseCtx->index].type == JSMN_ARRAY) {
        size_t arraySize = (size_t)parseCtx->tokenArray[parseCtx->index].size;
        parseCtx->index++; /*Object to first element*/
        
        for(size_t i = 0; i < arraySize; i++) {
            CHECK_TOKEN_BOUNDS;
            if(parseCtx->tokenArray[parseCtx->index].type == JSMN_OBJECT) {
               ret = searchObjectForKeyRec(searchKey, ctx, parseCtx, resultIndex,
                                           (UA_UInt16)(depth + 1));
            } else if(parseCtx->tokenArray[parseCtx->index].type == JSMN_ARRAY) {
               ret = searchObjectForKeyRec(searchKey, ctx, parseCtx, resultIndex,
                                           (UA_UInt16)(depth + 1));
            } else {
                /* Only Primitive or string */
                parseCtx->index++;
            }
        }
    }
    return ret;
}

UA_FUNC_ATTR_WARN_UNUSED_RESULT status
lookAheadForKey(const char* search, CtxJson *ctx,
                ParseCtx *parseCtx, size_t *resultIndex) {
    UA_UInt16 oldIndex = parseCtx->index; /* Save index for later restore */
    
    UA_UInt16 depth = 0;
    UA_StatusCode ret  = searchObjectForKeyRec(search, ctx, parseCtx, resultIndex, depth);

    parseCtx->index = oldIndex; /* Restore index */
    return ret;
}

/* Function used to jump over an object which cannot be parsed */
static status
jumpOverRec(CtxJson *ctx, ParseCtx *parseCtx,
            size_t *resultIndex, UA_UInt16 depth) {
    UA_StatusCode ret = UA_STATUSCODE_BADDECODINGERROR;
    CHECK_TOKEN_BOUNDS;
    
    if(parseCtx->tokenArray[parseCtx->index].type == JSMN_OBJECT) {
        size_t objectCount = (size_t)(parseCtx->tokenArray[parseCtx->index].size);
        
        parseCtx->index++; /*Object to first Key*/
        CHECK_TOKEN_BOUNDS;
        
        size_t i;
        for(i = 0; i < objectCount; i++) {
            CHECK_TOKEN_BOUNDS;
             
            parseCtx->index++; /*value*/
            CHECK_TOKEN_BOUNDS;
            
            if(parseCtx->tokenArray[parseCtx->index].type == JSMN_OBJECT) {
               jumpOverRec(ctx, parseCtx, resultIndex, (UA_UInt16)(depth + 1));
            } else if(parseCtx->tokenArray[parseCtx->index].type == JSMN_ARRAY) {
               jumpOverRec(ctx, parseCtx, resultIndex, (UA_UInt16)(depth + 1));
            } else {
                /*Only Primitive or string*/
                parseCtx->index++;
            }
        }
    } else if(parseCtx->tokenArray[parseCtx->index].type == JSMN_ARRAY) {
        size_t arraySize = (size_t)(parseCtx->tokenArray[parseCtx->index].size);
        
        parseCtx->index++; /*Object to first element*/
        CHECK_TOKEN_BOUNDS;
        
        size_t i;
        for(i = 0; i < arraySize; i++) {
            if(parseCtx->tokenArray[parseCtx->index].type == JSMN_OBJECT) {
               jumpOverRec(ctx, parseCtx, resultIndex, (UA_UInt16)(depth + 1));
            } else if(parseCtx->tokenArray[parseCtx->index].type == JSMN_ARRAY) {
               jumpOverRec(ctx, parseCtx, resultIndex, (UA_UInt16)(depth + 1));
            } else {
                /*Only Primitive or string*/
                parseCtx->index++;
            }
        }
    }
    return ret;
}

static status
jumpOverObject(CtxJson *ctx, ParseCtx *parseCtx, size_t *resultIndex) {
    UA_UInt16 oldIndex = parseCtx->index; /* Save index for later restore */
    UA_UInt16 depth = 0;
    jumpOverRec(ctx, parseCtx, resultIndex, depth);
    *resultIndex = parseCtx->index;
    parseCtx->index = oldIndex; /* Restore index */
    return UA_STATUSCODE_GOOD;
}

static status
prepareDecodeNodeIdJson(UA_NodeId *dst, CtxJson *ctx, ParseCtx *parseCtx, 
                        u8 *fieldCount, DecodeEntry *entries) {
    /* possible keys: Id, IdType*/
    /* Id must always be present */
    entries[*fieldCount].fieldName = UA_JSONKEY_ID;
    entries[*fieldCount].found = false;
    entries[*fieldCount].type = NULL;
    
    /* IdType */
    UA_Boolean hasIdType = false;
    size_t searchResult = 0; 
    status ret = lookAheadForKey(UA_JSONKEY_IDTYPE, ctx, parseCtx, &searchResult);
    if(ret == UA_STATUSCODE_GOOD) { /*found*/
         hasIdType = true;
    }
    
    if(hasIdType) {
        size_t size = (size_t)(parseCtx->tokenArray[searchResult].end -
                               parseCtx->tokenArray[searchResult].start);
        if(size < 1) {
            return UA_STATUSCODE_BADDECODINGERROR;
        }

        char *idType = (char*)(ctx->pos + parseCtx->tokenArray[searchResult].start);
      
        if(idType[0] == '2') {
            dst->identifierType = UA_NODEIDTYPE_GUID;
            entries[*fieldCount].fieldPointer = &dst->identifier.guid;
            entries[*fieldCount].function = (decodeJsonSignature) Guid_decodeJson;
        } else if(idType[0] == '1') {
            dst->identifierType = UA_NODEIDTYPE_STRING;
            entries[*fieldCount].fieldPointer = &dst->identifier.string;
            entries[*fieldCount].function = (decodeJsonSignature) String_decodeJson;
        } else if(idType[0] == '3') {
            dst->identifierType = UA_NODEIDTYPE_BYTESTRING;
            entries[*fieldCount].fieldPointer = &dst->identifier.byteString;
            entries[*fieldCount].function = (decodeJsonSignature) ByteString_decodeJson;
        } else {
            return UA_STATUSCODE_BADDECODINGERROR;
        }
        
        /* Id always present */
        (*fieldCount)++;
        
        entries[*fieldCount].fieldName = UA_JSONKEY_IDTYPE;
        entries[*fieldCount].fieldPointer = NULL;
        entries[*fieldCount].function = NULL;
        entries[*fieldCount].found = false;
        entries[*fieldCount].type = NULL;
        
        /* IdType */
        (*fieldCount)++;
    } else {
        dst->identifierType = UA_NODEIDTYPE_NUMERIC;
        entries[*fieldCount].fieldPointer = &dst->identifier.numeric;
        entries[*fieldCount].function = (decodeJsonSignature) UInt32_decodeJson;
        entries[*fieldCount].type = NULL;
        (*fieldCount)++;
    }
    
    return UA_STATUSCODE_GOOD;
}

DECODE_JSON(NodeId) {
    ALLOW_NULL;
    CHECK_OBJECT;

    /* NameSpace */
    UA_Boolean hasNamespace = false;
    size_t searchResultNamespace = 0;
    status ret = lookAheadForKey(UA_JSONKEY_NAMESPACE, ctx, parseCtx, &searchResultNamespace);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->namespaceIndex = 0;
    } else {
        hasNamespace = true;
    }
    
    /* Keep track over number of keys present, incremented if key found */
    u8 fieldCount = 0;
    DecodeEntry entries[3];
    ret = prepareDecodeNodeIdJson(dst, ctx, parseCtx, &fieldCount, entries);
    if(ret != UA_STATUSCODE_GOOD)
        return ret;

    if(hasNamespace) {
        entries[fieldCount].fieldName = UA_JSONKEY_NAMESPACE;
        entries[fieldCount].fieldPointer = &dst->namespaceIndex;
        entries[fieldCount].function = (decodeJsonSignature) UInt16_decodeJson;
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++;
    } else {
        dst->namespaceIndex = 0;
    }
    ret = decodeFields(ctx, parseCtx, entries, fieldCount, type);
    return ret;
}

DECODE_JSON(ExpandedNodeId) {
    ALLOW_NULL;
    CHECK_OBJECT;

    /* Keep track over number of keys present, incremented if key found */
    u8 fieldCount = 0;
    
    /* ServerUri */
    UA_Boolean hasServerUri = false;
    size_t searchResultServerUri = 0;
    status ret = lookAheadForKey(UA_JSONKEY_SERVERURI, ctx, parseCtx, &searchResultServerUri);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->serverIndex = 0; 
    } else {
        hasServerUri = true;
    }
    
    /* NameSpace */
    UA_Boolean hasNamespace = false;
    UA_Boolean isNamespaceString = false;
    size_t searchResultNamespace = 0;
    ret = lookAheadForKey(UA_JSONKEY_NAMESPACE, ctx, parseCtx, &searchResultNamespace);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->namespaceUri = UA_STRING_NULL;
    } else {
        hasNamespace = true;
        jsmntok_t nsToken = parseCtx->tokenArray[searchResultNamespace];
        if(nsToken.type == JSMN_STRING)
            isNamespaceString = true;
    }

    DecodeEntry entries[4];
    ret = prepareDecodeNodeIdJson(&dst->nodeId, ctx, parseCtx, &fieldCount, entries);
    if(ret != UA_STATUSCODE_GOOD)
        return ret;

    if(hasNamespace) {
        entries[fieldCount].fieldName = UA_JSONKEY_NAMESPACE;
        if(isNamespaceString) {
            entries[fieldCount].fieldPointer = &dst->namespaceUri;
            entries[fieldCount].function = (decodeJsonSignature) String_decodeJson;
        } else {
            entries[fieldCount].fieldPointer = &dst->nodeId.namespaceIndex;
            entries[fieldCount].function = (decodeJsonSignature) UInt16_decodeJson;
        }
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++; 
    }
    
    if(hasServerUri) {
        entries[fieldCount].fieldName = UA_JSONKEY_SERVERURI;
        entries[fieldCount].fieldPointer = &dst->serverIndex;
        entries[fieldCount].function = (decodeJsonSignature) UInt32_decodeJson;
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++;  
    } else {
        dst->serverIndex = 0;
    }
    
    return decodeFields(ctx, parseCtx, entries, fieldCount, type);
}

DECODE_JSON(DateTime) {
    CHECK_STRING;
    CHECK_TOKEN_BOUNDS;
    size_t tokenSize;
    char* tokenData;
    GET_TOKEN(tokenData, tokenSize);
    
    /* TODO: proper ISO 8601:2004 parsing, musl strptime!*/
    /* DateTime  ISO 8601:2004 without milli is 20 Characters, with millis 24 */
    if(tokenSize != 20 && tokenSize != 24) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    /* sanity check */
    if(tokenData[4] != '-' || tokenData[7] != '-' || tokenData[10] != 'T' ||
       tokenData[13] != ':' || tokenData[16] != ':' ||
       !(tokenData[19] == 'Z' || tokenData[19] == '.')) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    struct mytm dts;
    memset(&dts, 0, sizeof(dts));
    
    UA_UInt64 year = 0;
    atoiUnsigned(&tokenData[0], 4, &year);
    dts.tm_year = (UA_UInt16)year - 1900;
    UA_UInt64 month = 0;
    atoiUnsigned(&tokenData[5], 2, &month);
    dts.tm_mon = (UA_UInt16)month - 1;
    UA_UInt64 day = 0;
    atoiUnsigned(&tokenData[8], 2, &day);
    dts.tm_mday = (UA_UInt16)day;
    UA_UInt64 hour = 0;
    atoiUnsigned(&tokenData[11], 2, &hour);
    dts.tm_hour = (UA_UInt16)hour;
    UA_UInt64 min = 0;
    atoiUnsigned(&tokenData[14], 2, &min);
    dts.tm_min = (UA_UInt16)min;
    UA_UInt64 sec = 0;
    atoiUnsigned(&tokenData[17], 2, &sec);
    dts.tm_sec = (UA_UInt16)sec;
    
    UA_UInt64 msec = 0;
    if(tokenSize == 24) {
        atoiUnsigned(&tokenData[20], 3, &msec);
    }
    
    long long sinceunix = __tm_to_secs(&dts);
    UA_DateTime dt = (UA_DateTime)((UA_UInt64)(sinceunix*UA_DATETIME_SEC +
                                               UA_DATETIME_UNIX_EPOCH) +
                                   (UA_UInt64)(UA_DATETIME_MSEC * msec)); 
    *dst = dt;
  
    if(moveToken)
        parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

DECODE_JSON(StatusCode) {
    status ret = DECODE_DIRECT_JSON(dst, UInt32);
    if(ret != UA_STATUSCODE_GOOD)
        return ret;

    if(moveToken)
        parseCtx->index++;
    return UA_STATUSCODE_GOOD;
}

static status
VariantDimension_decodeJson(void * dst, const UA_DataType *type, 
                            CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken) {
    (void) type;
    const UA_DataType *dimType = &UA_TYPES[UA_TYPES_UINT32];
    return Array_decodeJson_internal((void**)dst, dimType, ctx, parseCtx, moveToken);
}

DECODE_JSON(Variant) {
    ALLOW_NULL;
    CHECK_OBJECT;

    /* First search for the variant type in the json object. */
    size_t searchResultType = 0;
    status ret = lookAheadForKey(UA_JSONKEY_TYPE, ctx, parseCtx, &searchResultType);
    if(ret != UA_STATUSCODE_GOOD)
        return UA_STATUSCODE_BADDECODINGERROR;

    size_t size = (size_t)(parseCtx->tokenArray[searchResultType].end - parseCtx->tokenArray[searchResultType].start);

    /* check if size is zero or the type is not a number */
    if(size < 1 || parseCtx->tokenArray[searchResultType].type != JSMN_PRIMITIVE) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    /*Parse the type*/
    UA_UInt64 idTypeDecoded = 0;
    char *idTypeEncoded = (char*)(ctx->pos + parseCtx->tokenArray[searchResultType].start);
    status typeDecodeStatus = atoiUnsigned(idTypeEncoded, size, &idTypeDecoded);
    
    /* value is not a valid number */
    if(typeDecodeStatus != UA_STATUSCODE_GOOD) {
        return typeDecodeStatus;
    }

    /*Set the type, Get the Type by nodeID!*/
    UA_NodeId typeNodeId = UA_NODEID_NUMERIC(0, (UA_UInt32)idTypeDecoded);
    const UA_DataType *bodyType = UA_findDataType(&typeNodeId);
    if(bodyType == NULL) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    /*Set the type*/
    dst->type = bodyType;
    
    /* LookAhead BODY */
    /* Does the variant contain an array? */
    UA_Boolean isArray = false;
    UA_Boolean isBodyNull = false;
    
    /* Search for body */
    size_t searchResultBody = 0;
    ret = lookAheadForKey(UA_JSONKEY_BODY, ctx, parseCtx, &searchResultBody);
    if(ret == UA_STATUSCODE_GOOD) { /* body found */
        /* get body token */
        jsmntok_t bodyToken = parseCtx->tokenArray[searchResultBody];
        
        /*BODY is null?*/
        if(isJsonTokenNull(ctx, &bodyToken)) {
            dst->data = NULL;
            isBodyNull = true;
        }
        
        if(bodyToken.type == JSMN_ARRAY) {
            isArray = true;
            
            size_t arraySize = 0;
            arraySize = (size_t)parseCtx->tokenArray[searchResultBody].size;
            dst->arrayLength = arraySize;
        }
    } else {
        /*TODO: no body? set value NULL?*/
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    /* LookAhead DIMENSION */
    UA_Boolean hasDimension = false;

    /* Has the variant dimension? */
    size_t searchResultDim = 0;
    ret = lookAheadForKey(UA_JSONKEY_DIMENSION, ctx, parseCtx, &searchResultDim);
    if(ret == UA_STATUSCODE_GOOD) {
        hasDimension = true;
        size_t dimensionSize = 0;
        dimensionSize = (size_t)parseCtx->tokenArray[searchResultDim].size;
        dst->arrayDimensionsSize = dimensionSize;
    }
    
    /* no array but has dimension. error? */
    if(!isArray && hasDimension)
        return UA_STATUSCODE_BADDECODINGERROR;
    
    /* Get the datatype of the content. The type must be a builtin data type.
    * All not-builtin types are wrapped in an ExtensionObject. */
    if(bodyType->typeKind > UA_TYPES_DIAGNOSTICINFO)
        return UA_STATUSCODE_BADDECODINGERROR;

    /* A variant cannot contain a variant. But it can contain an array of
        * variants */
    if(bodyType->typeKind == UA_DATATYPEKIND_VARIANT && !isArray)
        return UA_STATUSCODE_BADDECODINGERROR;
    
    if(isArray) {
        DecodeEntry entries[3] = {
            {UA_JSONKEY_TYPE, NULL, NULL, false, NULL},
            {UA_JSONKEY_BODY, &dst->data, (decodeJsonSignature) Array_decodeJson, false, NULL},
            {UA_JSONKEY_DIMENSION, &dst->arrayDimensions,
             (decodeJsonSignature) VariantDimension_decodeJson, false, NULL}};

        if(!hasDimension) {
            ret = decodeFields(ctx, parseCtx, entries, 2, bodyType); /*use first 2 fields*/
        } else {
            ret = decodeFields(ctx, parseCtx, entries, 3, bodyType); /*use all fields*/
        }      
    } else if(bodyType->typeKind != UA_DATATYPEKIND_EXTENSIONOBJECT) {
        /* Allocate Memory for Body */
        if(!isBodyNull) {
            dst->data = UA_new(bodyType);
            if(!dst->data)
                return UA_STATUSCODE_BADOUTOFMEMORY;
        }
        
        DecodeEntry entries[2] = {{UA_JSONKEY_TYPE, NULL, NULL, false, NULL},
            {UA_JSONKEY_BODY, dst->data, (decodeJsonSignature) decodeJsonInternal, false, NULL}};
        ret = decodeFields(ctx, parseCtx, entries, 2, bodyType);
    } else { /* extensionObject */
        DecodeEntry entries[2] = {{UA_JSONKEY_TYPE, NULL, NULL, false, NULL},
            {UA_JSONKEY_BODY, dst,
             (decodeJsonSignature) Variant_decodeJsonUnwrapExtensionObject, false, NULL}};
        ret = decodeFields(ctx, parseCtx, entries, 2, bodyType);
    }
    return ret;
}

DECODE_JSON(DataValue) {
    ALLOW_NULL;
    CHECK_OBJECT;

    DecodeEntry entries[6] = {
       {UA_JSONKEY_VALUE, &dst->value, (decodeJsonSignature) Variant_decodeJson, false, NULL},
       {UA_JSONKEY_STATUS, &dst->status, (decodeJsonSignature) StatusCode_decodeJson, false, NULL},
       {UA_JSONKEY_SOURCETIMESTAMP, &dst->sourceTimestamp, (decodeJsonSignature) DateTime_decodeJson, false, NULL},
       {UA_JSONKEY_SOURCEPICOSECONDS, &dst->sourcePicoseconds, (decodeJsonSignature) UInt16_decodeJson, false, NULL},
       {UA_JSONKEY_SERVERTIMESTAMP, &dst->serverTimestamp, (decodeJsonSignature) DateTime_decodeJson, false, NULL},
       {UA_JSONKEY_SERVERPICOSECONDS, &dst->serverPicoseconds, (decodeJsonSignature) UInt16_decodeJson, false, NULL}};

    status ret = decodeFields(ctx, parseCtx, entries, 6, type);
    dst->hasValue = entries[0].found; dst->hasStatus = entries[1].found;
    dst->hasSourceTimestamp = entries[2].found; dst->hasSourcePicoseconds = entries[3].found;
    dst->hasServerTimestamp = entries[4].found; dst->hasServerPicoseconds = entries[5].found;
    return ret;
}

DECODE_JSON(ExtensionObject) {
    ALLOW_NULL;
    CHECK_OBJECT;

    /* Search for Encoding */
    size_t searchEncodingResult = 0;
    status ret = lookAheadForKey(UA_JSONKEY_ENCODING, ctx, parseCtx, &searchEncodingResult);
    
    /* If no encoding found it is structure encoding */
    if(ret != UA_STATUSCODE_GOOD) {
        UA_NodeId typeId;
        UA_NodeId_init(&typeId);

        size_t searchTypeIdResult = 0;
        ret = lookAheadForKey(UA_JSONKEY_TYPEID, ctx, parseCtx, &searchTypeIdResult);
        if(ret != UA_STATUSCODE_GOOD) {
            /* TYPEID not found, abort */
            return UA_STATUSCODE_BADENCODINGERROR;
        }

        /* parse the nodeid */
        /*for restore*/
        UA_UInt16 index = parseCtx->index;
        parseCtx->index = (UA_UInt16)searchTypeIdResult;
        ret = NodeId_decodeJson(&typeId, &UA_TYPES[UA_TYPES_NODEID], ctx, parseCtx, true);
        if(ret != UA_STATUSCODE_GOOD)
            return ret;
        
        /*restore*/
        parseCtx->index = index;
        const UA_DataType *typeOfBody = UA_findDataType(&typeId);
        if(!typeOfBody) {
            /*dont decode body: 1. save as bytestring, 2. jump over*/
            dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
            UA_NodeId_copy(&typeId, &dst->content.encoded.typeId);
            
            /*Check if Object in Extentionobject*/
            if(getJsmnType(parseCtx) != JSMN_OBJECT) {
                UA_NodeId_deleteMembers(&typeId);
                return UA_STATUSCODE_BADDECODINGERROR;
            }
            
            /*Search for Body to save*/
            size_t searchBodyResult = 0;
            ret = lookAheadForKey(UA_JSONKEY_BODY, ctx, parseCtx, &searchBodyResult);
            if(ret != UA_STATUSCODE_GOOD) {
                /*No Body*/
                UA_NodeId_deleteMembers(&typeId);
                return UA_STATUSCODE_BADDECODINGERROR;
            }
            
            if(searchBodyResult >= (size_t)parseCtx->tokenCount) {
                /*index not in Tokenarray*/
                UA_NodeId_deleteMembers(&typeId);
                return UA_STATUSCODE_BADDECODINGERROR;
            }

            /* Get the size of the Object as a string, not the Object key count! */
            UA_Int64 sizeOfJsonString =(parseCtx->tokenArray[searchBodyResult].end -
                    parseCtx->tokenArray[searchBodyResult].start);
            
            char* bodyJsonString = (char*)(ctx->pos + parseCtx->tokenArray[searchBodyResult].start);
            
            if(sizeOfJsonString <= 0) {
                UA_NodeId_deleteMembers(&typeId);
                return UA_STATUSCODE_BADDECODINGERROR;
            }
            
            /* Save encoded as bytestring. */
            ret = UA_ByteString_allocBuffer(&dst->content.encoded.body, (size_t)sizeOfJsonString);
            if(ret != UA_STATUSCODE_GOOD) {
                UA_NodeId_deleteMembers(&typeId);
                return ret;
            }

            memcpy(dst->content.encoded.body.data, bodyJsonString, (size_t)sizeOfJsonString);
            
            size_t tokenAfteExtensionObject = 0;
            jumpOverObject(ctx, parseCtx, &tokenAfteExtensionObject);
            
            if(tokenAfteExtensionObject == 0) {
                /*next object token not found*/
                UA_NodeId_deleteMembers(&typeId);
                UA_ByteString_deleteMembers(&dst->content.encoded.body);
                return UA_STATUSCODE_BADDECODINGERROR;
            }
            
            parseCtx->index = (UA_UInt16)tokenAfteExtensionObject;
            
            return UA_STATUSCODE_GOOD;
        }
        
        /*Type id not used anymore, typeOfBody has type*/
        UA_NodeId_deleteMembers(&typeId);
        
        /*Set Found Type*/
        dst->content.decoded.type = typeOfBody;
        dst->encoding = UA_EXTENSIONOBJECT_DECODED;
        
        if(searchTypeIdResult != 0) {
            dst->content.decoded.data = UA_new(typeOfBody);
            if(!dst->content.decoded.data)
                return UA_STATUSCODE_BADOUTOFMEMORY;

            UA_NodeId typeId_dummy;
            DecodeEntry entries[2] = {
                {UA_JSONKEY_TYPEID, &typeId_dummy, (decodeJsonSignature) NodeId_decodeJson, false, NULL},
                {UA_JSONKEY_BODY, dst->content.decoded.data,
                 (decodeJsonSignature) decodeJsonJumpTable[typeOfBody->typeKind], false, NULL}
            };

            return decodeFields(ctx, parseCtx, entries, 2, typeOfBody);
        } else {
           return UA_STATUSCODE_BADDECODINGERROR;
        }
    } else { /* UA_JSONKEY_ENCODING found */
        /*Parse the encoding*/
        UA_UInt64 encoding = 0;
        char *extObjEncoding = (char*)(ctx->pos + parseCtx->tokenArray[searchEncodingResult].start);
        size_t size = (size_t)(parseCtx->tokenArray[searchEncodingResult].end - parseCtx->tokenArray[searchEncodingResult].start);
        atoiUnsigned(extObjEncoding, size, &encoding);

        if(encoding == 1) {
            /* BYTESTRING in Json Body */
            dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
            UA_UInt16 encodingTypeJson;
            DecodeEntry entries[3] = {
                {UA_JSONKEY_ENCODING, &encodingTypeJson, (decodeJsonSignature) UInt16_decodeJson, false, NULL},
                {UA_JSONKEY_BODY, &dst->content.encoded.body, (decodeJsonSignature) String_decodeJson, false, NULL},
                {UA_JSONKEY_TYPEID, &dst->content.encoded.typeId, (decodeJsonSignature) NodeId_decodeJson, false, NULL}
            };

            return decodeFields(ctx, parseCtx, entries, 3, type);
        } else if(encoding == 2) {
            /* XmlElement in Json Body */
            dst->encoding = UA_EXTENSIONOBJECT_ENCODED_XML;
            UA_UInt16 encodingTypeJson;
            DecodeEntry entries[3] = {
                {UA_JSONKEY_ENCODING, &encodingTypeJson, (decodeJsonSignature) UInt16_decodeJson, false, NULL},
                {UA_JSONKEY_BODY, &dst->content.encoded.body, (decodeJsonSignature) String_decodeJson, false, NULL},
                {UA_JSONKEY_TYPEID, &dst->content.encoded.typeId, (decodeJsonSignature) NodeId_decodeJson, false, NULL}
            };
            return decodeFields(ctx, parseCtx, entries, 3, type);
        } else {
            return UA_STATUSCODE_BADDECODINGERROR;
        }
    }
    return UA_STATUSCODE_BADNOTIMPLEMENTED;
}

static status
Variant_decodeJsonUnwrapExtensionObject(UA_Variant *dst, const UA_DataType *type, 
                                        CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken) {
    (void) type, (void) moveToken;
    /*EXTENSIONOBJECT POSITION!*/
    UA_UInt16 old_index = parseCtx->index;
    UA_Boolean typeIdFound;
    
    /* Decode the DataType */
    UA_NodeId typeId;
    UA_NodeId_init(&typeId);

    size_t searchTypeIdResult = 0;
    status ret = lookAheadForKey(UA_JSONKEY_TYPEID, ctx, parseCtx, &searchTypeIdResult);

    if(ret != UA_STATUSCODE_GOOD) {
        /*No Typeid found*/
        typeIdFound = false;
        /*return UA_STATUSCODE_BADDECODINGERROR;*/
    } else {
        typeIdFound = true;
        /* parse the nodeid */
        parseCtx->index = (UA_UInt16)searchTypeIdResult;
        ret = NodeId_decodeJson(&typeId, &UA_TYPES[UA_TYPES_NODEID], ctx, parseCtx, true);
        if(ret != UA_STATUSCODE_GOOD) {
            UA_NodeId_deleteMembers(&typeId);
            return ret;
        }

        /*restore index, ExtensionObject position*/
        parseCtx->index = old_index;
    }

    /* ---Decode the EncodingByte--- */
    if(!typeIdFound)
        return UA_STATUSCODE_BADDECODINGERROR;

    UA_Boolean encodingFound = false;
    /*Search for Encoding*/
    size_t searchEncodingResult = 0;
    ret = lookAheadForKey(UA_JSONKEY_ENCODING, ctx, parseCtx, &searchEncodingResult);

    UA_UInt64 encoding = 0;
    /*If no encoding found it is Structure encoding*/
    if(ret == UA_STATUSCODE_GOOD) { /*FOUND*/
        encodingFound = true;
        char *extObjEncoding = (char*)(ctx->pos + parseCtx->tokenArray[searchEncodingResult].start);
        size_t size = (size_t)(parseCtx->tokenArray[searchEncodingResult].end 
                               - parseCtx->tokenArray[searchEncodingResult].start);
        atoiUnsigned(extObjEncoding, size, &encoding);
    }
        
    const UA_DataType *typeOfBody = UA_findDataType(&typeId);
        
    if(encoding == 0 || typeOfBody != NULL) {
        /*This value is 0 if the body is Structure encoded as a JSON object (see 5.4.6).*/
        /* Found a valid type and it is structure encoded so it can be unwrapped */
        dst->type = typeOfBody;

        /* Allocate memory for type*/
        dst->data = UA_new(dst->type);
        if(!dst->data) {
            UA_NodeId_deleteMembers(&typeId);
            return UA_STATUSCODE_BADOUTOFMEMORY;
        }

        /* Decode the content */
        UA_NodeId nodeIddummy;
        DecodeEntry entries[3] =
            {
             {UA_JSONKEY_TYPEID, &nodeIddummy, (decodeJsonSignature) NodeId_decodeJson, false, NULL},
             {UA_JSONKEY_BODY, dst->data,
              (decodeJsonSignature) decodeJsonJumpTable[dst->type->typeKind], false, NULL},
             {UA_JSONKEY_ENCODING, NULL, NULL, false, NULL}};

        ret = decodeFields(ctx, parseCtx, entries, encodingFound ? 3:2, typeOfBody);
        if(ret != UA_STATUSCODE_GOOD) {
            UA_free(dst->data);
        }
    } else if(encoding == 1 || encoding == 2 || typeOfBody == NULL) {
        UA_NodeId_deleteMembers(&typeId);
            
        /* decode as ExtensionObject */
        dst->type = &UA_TYPES[UA_TYPES_EXTENSIONOBJECT];

        /* Allocate memory for extensionobject*/
        dst->data = UA_new(dst->type);
        if(!dst->data)
            return UA_STATUSCODE_BADOUTOFMEMORY;

        /* decode: Does not move tokenindex. */
        ret = DECODE_DIRECT_JSON(dst->data, ExtensionObject);
        if(ret != UA_STATUSCODE_GOOD)
            UA_free(dst->data);
    } else {
        /*no recognized encoding type*/
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    return ret;
}
status DiagnosticInfoInner_decodeJson(void* dst, const UA_DataType* type, 
        CtxJson* ctx, ParseCtx* parseCtx, UA_Boolean moveToken);

DECODE_JSON(DiagnosticInfo) {
    ALLOW_NULL;
    CHECK_OBJECT;

    DecodeEntry entries[7] = {
       {UA_JSONKEY_SYMBOLICID, &dst->symbolicId, (decodeJsonSignature) Int32_decodeJson, false, NULL},
       {UA_JSONKEY_NAMESPACEURI, &dst->namespaceUri, (decodeJsonSignature) Int32_decodeJson, false, NULL},
       {UA_JSONKEY_LOCALIZEDTEXT, &dst->localizedText, (decodeJsonSignature) Int32_decodeJson, false, NULL},
       {UA_JSONKEY_LOCALE, &dst->locale, (decodeJsonSignature) Int32_decodeJson, false, NULL},
       {UA_JSONKEY_ADDITIONALINFO, &dst->additionalInfo, (decodeJsonSignature) String_decodeJson, false, NULL},
       {UA_JSONKEY_INNERSTATUSCODE, &dst->innerStatusCode, (decodeJsonSignature) StatusCode_decodeJson, false, NULL},
       {UA_JSONKEY_INNERDIAGNOSTICINFO, &dst->innerDiagnosticInfo, (decodeJsonSignature) DiagnosticInfoInner_decodeJson, false, NULL}};
    status ret = decodeFields(ctx, parseCtx, entries, 7, type);

    dst->hasSymbolicId = entries[0].found; dst->hasNamespaceUri = entries[1].found;
    dst->hasLocalizedText = entries[2].found; dst->hasLocale = entries[3].found;
    dst->hasAdditionalInfo = entries[4].found; dst->hasInnerStatusCode = entries[5].found;
    dst->hasInnerDiagnosticInfo = entries[6].found;
    return ret;
}

status
DiagnosticInfoInner_decodeJson(void* dst, const UA_DataType* type, 
                               CtxJson* ctx, ParseCtx* parseCtx, UA_Boolean moveToken) {
    UA_DiagnosticInfo *inner = (UA_DiagnosticInfo*)UA_calloc(1, sizeof(UA_DiagnosticInfo));
    if(inner == NULL) {
        return UA_STATUSCODE_BADOUTOFMEMORY;
    }
    memcpy(dst, &inner, sizeof(UA_DiagnosticInfo*)); /* Copy new Pointer do dest */
    return DiagnosticInfo_decodeJson(inner, type, ctx, parseCtx, moveToken);
}

status 
decodeFields(CtxJson *ctx, ParseCtx *parseCtx, DecodeEntry *entries,
             size_t entryCount, const UA_DataType *type) {
    CHECK_TOKEN_BOUNDS;
    size_t objectCount = (size_t)(parseCtx->tokenArray[parseCtx->index].size);
    status ret = UA_STATUSCODE_GOOD;

    if(entryCount == 1) {
        if(*(entries[0].fieldName) == 0) { /*No MemberName*/
            return entries[0].function(entries[0].fieldPointer, type,
                                       ctx, parseCtx, true); /*ENCODE DIRECT*/
        }
    } else if(entryCount == 0) {
        return UA_STATUSCODE_BADDECODINGERROR;
    }

    parseCtx->index++; /*go to first key*/
    CHECK_TOKEN_BOUNDS;
    
    for (size_t currentObjectCount = 0; currentObjectCount < objectCount &&
             parseCtx->index < parseCtx->tokenCount; currentObjectCount++) {

        /* start searching at the index of currentObjectCount */
        for (size_t i = currentObjectCount; i < entryCount + currentObjectCount; i++) {
            /* Search for KEY, if found outer loop will be one less. Best case
             * is objectCount if in order! */
            size_t index = i % entryCount;
            
            CHECK_TOKEN_BOUNDS;
            if(jsoneq((char*) ctx->pos, &parseCtx->tokenArray[parseCtx->index], 
                       entries[index].fieldName) != 0)
                continue;

            if(entries[index].found) {
                /*Duplicate Key found, abort.*/
                return UA_STATUSCODE_BADDECODINGERROR;
            }

            entries[index].found = true;

            parseCtx->index++; /*goto value*/
            CHECK_TOKEN_BOUNDS;
            
            /* Find the data type.
             * TODO: get rid of parameter type. Only forward via DecodeEntry.
             */
            const UA_DataType *membertype = type;
            if(entries[index].type)
                membertype = entries[index].type;

            if(entries[index].function != NULL) {
                ret = entries[index].function(entries[index].fieldPointer,
                                              membertype, ctx, parseCtx, true); /*Move Token True*/
                if(ret != UA_STATUSCODE_GOOD)
                    return ret;
            } else {
                /*overstep single value, this will not work if object or array
                 Only used not to double parse pre looked up type, but it has to be overstepped*/
                parseCtx->index++;
            }
            break;
        }
    }
    return ret;
}

static status
Array_decodeJson_internal(void **dst, const UA_DataType *type, 
        CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken) {
    (void) moveToken;
    status ret;
    
    if(parseCtx->tokenArray[parseCtx->index].type != JSMN_ARRAY)
        return UA_STATUSCODE_BADDECODINGERROR;
    
    size_t length = (size_t)parseCtx->tokenArray[parseCtx->index].size;

    /* Save the length of the array */
    size_t *p = (size_t*) dst - 1;
    *p = length;

    /* Return early for empty arrays */
    if(length == 0) {
        *dst = UA_EMPTY_ARRAY_SENTINEL;
        return UA_STATUSCODE_GOOD;
    }

    /* Allocate memory */
    *dst = UA_calloc(length, type->memSize);
    if(*dst == NULL)
        return UA_STATUSCODE_BADOUTOFMEMORY;
    
    parseCtx->index++; /* We go to first Array member!*/
    
    /* Decode array members */
    uintptr_t ptr = (uintptr_t)*dst;
    for(size_t i = 0; i < length; ++i) {
        ret = decodeJsonJumpTable[type->typeKind]((void*)ptr, type, ctx, parseCtx, true);
        if(ret != UA_STATUSCODE_GOOD) {
            UA_Array_delete(*dst, i+1, type);
            *dst = NULL;
            return ret;
        }
        ptr += type->memSize;
    }
    return UA_STATUSCODE_GOOD;
}

/*Wrapper for array with valid decodingStructure.*/
static status
Array_decodeJson(void * dst, const UA_DataType *type, CtxJson *ctx, 
        ParseCtx *parseCtx, UA_Boolean moveToken) {
    return Array_decodeJson_internal((void **)dst, type, ctx, parseCtx, moveToken);
}

static status
decodeJsonStructure(void *dst, const UA_DataType *type, CtxJson *ctx, 
                    ParseCtx *parseCtx, UA_Boolean moveToken) {
    (void) moveToken;
    /* Check the recursion limit */
    if(ctx->depth > UA_JSON_ENCODING_MAX_RECURSION)
        return UA_STATUSCODE_BADENCODINGERROR;
    ctx->depth++;

    uintptr_t ptr = (uintptr_t)dst;
    status ret = UA_STATUSCODE_GOOD;
    u8 membersSize = type->membersSize;
    const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] };
    
    UA_STACKARRAY(DecodeEntry, entries, membersSize);

    for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) {
        const UA_DataTypeMember *m = &type->members[i];
        const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex];

        entries[i].type = mt;
        if(!m->isArray) {
            ptr += m->padding;
            entries[i].fieldName = m->memberName;
            entries[i].fieldPointer = (void*)ptr;
            entries[i].function = decodeJsonJumpTable[mt->typeKind];
            entries[i].found = false;
            ptr += mt->memSize;
        } else {
            ptr += m->padding;
            ptr += sizeof(size_t);
            entries[i].fieldName = m->memberName;
            entries[i].fieldPointer = (void*)ptr;
            entries[i].function = (decodeJsonSignature)Array_decodeJson;
            entries[i].found = false;
            ptr += sizeof(void*);
        }
    }
    
    ret = decodeFields(ctx, parseCtx, entries, membersSize, type);

    ctx->depth--;
    return ret;
}

static status
decodeJsonNotImplemented(void *dst, const UA_DataType *type, CtxJson *ctx, 
                         ParseCtx *parseCtx, UA_Boolean moveToken) {
    (void)dst, (void)type, (void)ctx, (void)parseCtx, (void)moveToken;
    return UA_STATUSCODE_BADNOTIMPLEMENTED;
}

const decodeJsonSignature decodeJsonJumpTable[UA_DATATYPEKINDS] = {
    (decodeJsonSignature)Boolean_decodeJson,
    (decodeJsonSignature)SByte_decodeJson, /* SByte */
    (decodeJsonSignature)Byte_decodeJson,
    (decodeJsonSignature)Int16_decodeJson, /* Int16 */
    (decodeJsonSignature)UInt16_decodeJson,
    (decodeJsonSignature)Int32_decodeJson, /* Int32 */
    (decodeJsonSignature)UInt32_decodeJson,
    (decodeJsonSignature)Int64_decodeJson, /* Int64 */
    (decodeJsonSignature)UInt64_decodeJson,
    (decodeJsonSignature)Float_decodeJson,
    (decodeJsonSignature)Double_decodeJson,
    (decodeJsonSignature)String_decodeJson,
    (decodeJsonSignature)DateTime_decodeJson, /* DateTime */
    (decodeJsonSignature)Guid_decodeJson,
    (decodeJsonSignature)ByteString_decodeJson, /* ByteString */
    (decodeJsonSignature)String_decodeJson, /* XmlElement */
    (decodeJsonSignature)NodeId_decodeJson,
    (decodeJsonSignature)ExpandedNodeId_decodeJson,
    (decodeJsonSignature)StatusCode_decodeJson, /* StatusCode */
    (decodeJsonSignature)QualifiedName_decodeJson, /* QualifiedName */
    (decodeJsonSignature)LocalizedText_decodeJson,
    (decodeJsonSignature)ExtensionObject_decodeJson,
    (decodeJsonSignature)DataValue_decodeJson,
    (decodeJsonSignature)Variant_decodeJson,
    (decodeJsonSignature)DiagnosticInfo_decodeJson,
    (decodeJsonSignature)decodeJsonNotImplemented, /* Decimal */
    (decodeJsonSignature)Int32_decodeJson, /* Enum */
    (decodeJsonSignature)decodeJsonStructure,
    (decodeJsonSignature)decodeJsonNotImplemented, /* Structure with optional fields */
    (decodeJsonSignature)decodeJsonNotImplemented, /* Union */
    (decodeJsonSignature)decodeJsonNotImplemented /* BitfieldCluster */
};

decodeJsonSignature getDecodeSignature(u8 index) {
    return decodeJsonJumpTable[index];
}

status
tokenize(ParseCtx *parseCtx, CtxJson *ctx, const UA_ByteString *src) {
    /* Set up the context */
    ctx->pos = &src->data[0];
    ctx->end = &src->data[src->length];
    ctx->depth = 0;
    parseCtx->tokenCount = 0;
    parseCtx->index = 0;

    /*Set up tokenizer jsmn*/
    jsmn_parser p;
    jsmn_init(&p);
    parseCtx->tokenCount = (UA_Int32)
        jsmn_parse(&p, (char*)src->data, src->length,
                   parseCtx->tokenArray, UA_JSON_MAXTOKENCOUNT);
    
    if(parseCtx->tokenCount < 0) {
        if(parseCtx->tokenCount == JSMN_ERROR_NOMEM)
            return UA_STATUSCODE_BADOUTOFMEMORY;
        return UA_STATUSCODE_BADDECODINGERROR;
    }
    
    return UA_STATUSCODE_GOOD;
}

UA_StatusCode
decodeJsonInternal(void *dst, const UA_DataType *type,
                   CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken) {

    return decodeJsonJumpTable[type->typeKind](dst, type, ctx, parseCtx, moveToken);
}

status UA_FUNC_ATTR_WARN_UNUSED_RESULT
UA_decodeJson(const UA_ByteString *src, void *dst, const UA_DataType *type) {
    
#ifndef UA_ENABLE_TYPEDESCRIPTION
    return UA_STATUSCODE_BADNOTSUPPORTED;
#endif
    
    if(dst == NULL || src == NULL || type == NULL) {
        return UA_STATUSCODE_BADARGUMENTSMISSING;
    }
    
    /* Set up the context */
    CtxJson ctx;
    ParseCtx parseCtx;
    parseCtx.tokenArray = (jsmntok_t*)UA_malloc(sizeof(jsmntok_t) * UA_JSON_MAXTOKENCOUNT);
    if(!parseCtx.tokenArray)
        return UA_STATUSCODE_BADOUTOFMEMORY;
    
    status ret = tokenize(&parseCtx, &ctx, src);
    if(ret != UA_STATUSCODE_GOOD)
        goto cleanup;

    /* Assume the top-level element is an object */
    if(parseCtx.tokenCount < 1 || parseCtx.tokenArray[0].type != JSMN_OBJECT) {
        if(parseCtx.tokenCount == 1) {
            if(parseCtx.tokenArray[0].type == JSMN_PRIMITIVE ||
               parseCtx.tokenArray[0].type == JSMN_STRING) {
               /* Only a primitive to parse. Do it directly. */
               memset(dst, 0, type->memSize); /* Initialize the value */
               ret = decodeJsonJumpTable[type->typeKind](dst, type, &ctx, &parseCtx, true);
               goto cleanup;
            }
        }
        ret = UA_STATUSCODE_BADDECODINGERROR;
        goto cleanup;
    }

    /* Decode */
    memset(dst, 0, type->memSize); /* Initialize the value */
    ret = decodeJsonJumpTable[type->typeKind](dst, type, &ctx, &parseCtx, true);

    cleanup:
    UA_free(parseCtx.tokenArray);
    
    /* sanity check if all Tokens were processed */
    if(!(parseCtx.index == parseCtx.tokenCount ||
         parseCtx.index == parseCtx.tokenCount-1)) {
        ret = UA_STATUSCODE_BADDECODINGERROR;
    }
    
    if(ret != UA_STATUSCODE_GOOD)
        UA_deleteMembers(dst, type); /* Clean up */
    return ret;
}
