blob: 558c24e57960861b62e0551969dbab6c50a3e3fc [file] [log] [blame]
/* 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-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
* Copyright 2018 (c) Fraunhofer IOSB (Author: Lukas Meling)
*/
#ifndef UA_TYPES_ENCODING_JSON_H_
#define UA_TYPES_ENCODING_JSON_H_
#include <open62541/types.h>
#include "ua_types_encoding_binary.h"
#include "ua_types_encoding_json.h"
#include "ua_util_internal.h"
#include "../deps/jsmn/jsmn.h"
_UA_BEGIN_DECLS
#define UA_JSON_MAXTOKENCOUNT 1000
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) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
UA_StatusCode
UA_encodeJson(const void *src, const UA_DataType *type,
uint8_t **bufPos, const uint8_t **bufEnd,
UA_String *namespaces, size_t namespaceSize,
UA_String *serverUris, size_t serverUriSize,
UA_Boolean useReversible) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
UA_StatusCode
UA_decodeJson(const UA_ByteString *src, void *dst,
const UA_DataType *type) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
/* Interal Definitions
*
* For future by the PubSub encoding */
#define UA_JSON_ENCODING_MAX_RECURSION 100
typedef struct {
uint8_t *pos;
const uint8_t *end;
uint16_t depth; /* How often did we en-/decoding recurse? */
UA_Boolean commaNeeded[UA_JSON_ENCODING_MAX_RECURSION];
UA_Boolean useReversible;
UA_Boolean calcOnly; /* Only compute the length of the decoding */
size_t namespacesSize;
UA_String *namespaces;
size_t serverUrisSize;
UA_String *serverUris;
} CtxJson;
UA_StatusCode writeJsonObjStart(CtxJson *ctx);
UA_StatusCode writeJsonObjElm(CtxJson *ctx, const char *key,
const void *value, const UA_DataType *type);
UA_StatusCode writeJsonObjEnd(CtxJson *ctx);
UA_StatusCode writeJsonArrStart(CtxJson *ctx);
UA_StatusCode writeJsonArrElm(CtxJson *ctx, const void *value,
const UA_DataType *type);
UA_StatusCode writeJsonArrEnd(CtxJson *ctx);
UA_StatusCode writeJsonKey(CtxJson *ctx, const char* key);
UA_StatusCode writeJsonCommaIfNeeded(CtxJson *ctx);
UA_StatusCode writeJsonNull(CtxJson *ctx);
/* The encoding length is returned in ctx->pos */
static UA_INLINE UA_StatusCode
calcJsonObjStart(CtxJson *ctx) {
UA_assert(ctx->calcOnly);
return writeJsonObjStart(ctx);
}
static UA_INLINE UA_StatusCode
calcJsonObjElm(CtxJson *ctx, const char *key,
const void *value, const UA_DataType *type) {
UA_assert(ctx->calcOnly);
return writeJsonObjElm(ctx, key, value, type);
}
static UA_INLINE UA_StatusCode
calcJsonObjEnd(CtxJson *ctx) {
UA_assert(ctx->calcOnly);
return writeJsonObjEnd(ctx);
}
static UA_INLINE UA_StatusCode
calcJsonArrStart(CtxJson *ctx) {
UA_assert(ctx->calcOnly);
return writeJsonArrStart(ctx);
}
static UA_INLINE UA_StatusCode
calcJsonArrElm(CtxJson *ctx, const void *value,
const UA_DataType *type) {
UA_assert(ctx->calcOnly);
return writeJsonArrElm(ctx, value, type);
}
static UA_INLINE UA_StatusCode
calcJsonArrEnd(CtxJson *ctx) {
UA_assert(ctx->calcOnly);
return writeJsonArrEnd(ctx);
}
status
encodeJsonInternal(const void *src, const UA_DataType *type, CtxJson *ctx);
typedef struct {
jsmntok_t *tokenArray;
UA_Int32 tokenCount;
UA_UInt16 index;
/* Additonal data for special cases such as networkmessage/datasetmessage
* Currently only used for dataSetWriterIds */
size_t numCustom;
void * custom;
size_t* currentCustomIndex;
} ParseCtx;
typedef UA_StatusCode
(*encodeJsonSignature)(const void *src, const UA_DataType *type, CtxJson *ctx);
typedef UA_StatusCode
(*decodeJsonSignature)(void *dst, const UA_DataType *type, CtxJson *ctx,
ParseCtx *parseCtx, UA_Boolean moveToken);
/* Map for decoding a Json Object. An array of this is passed to the
* decodeFields function. If the key "fieldName" is found in the json object
* (mark as found and) decode the value with the "function" and write result
* into "fieldPointer" (destination). */
typedef struct {
const char * fieldName;
void * fieldPointer;
decodeJsonSignature function;
UA_Boolean found;
const UA_DataType *type;
} DecodeEntry;
UA_StatusCode
decodeFields(CtxJson *ctx, ParseCtx *parseCtx,
DecodeEntry *entries, size_t entryCount,
const UA_DataType *type);
UA_StatusCode
decodeJsonInternal(void *dst, const UA_DataType *type,
CtxJson *ctx, ParseCtx *parseCtx, UA_Boolean moveToken);
/* workaround: TODO generate functions for UA_xxx_decodeJson */
decodeJsonSignature getDecodeSignature(u8 index);
UA_StatusCode lookAheadForKey(const char* search, CtxJson *ctx, ParseCtx *parseCtx, size_t *resultIndex);
jsmntype_t getJsmnType(const ParseCtx *parseCtx);
UA_StatusCode tokenize(ParseCtx *parseCtx, CtxJson *ctx, const UA_ByteString *src);
UA_Boolean isJsonNull(const CtxJson *ctx, const ParseCtx *parseCtx);
_UA_END_DECLS
#endif /* UA_TYPES_ENCODING_JSON_H_ */