mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/ubjson: remove module.
The ubjson module has a number of quality defects and is unsafe. Considering CBOR is popular, standarized and supported in RIOT and that the ubjson implementation is a home-grown one whose API will likely be unfamiliar to new users, I propose to delete it. This removal, of course, dows not have to be NOW. We can deprecate it for one or two releases before. What's wrong with this module? - Unsafe: the parsing is done recursively. This is embedded in the API, so it is not possible to fix it without changing the API. A document with too much nesting can cause a stack overflow. - Does not validate writing: it is possible to produce invalid output. From the docs: > The library won't complain if you write multiple values that are not > inside an array or object. The result will just not be properly serialized. - Poorly tested. As shown by #11702, #11703 the tests were not even detecting that a False was stored as True. - In line with the previous remark, see68dc5b0d6e/tests/unittests/tests-ubjson/tests-ubjson.c (L66-L77)
Why is the following code in the unit tests?? ```c irq_disable(); sched_set_status(data->main_thread, STATUS_PENDING); ``` - #2175 is still unfixed after 3.5 years. - Code quality. The code has multiline macros that assign variables and return. Seec332514875/sys/ubjson/ubjson-write.c (L34-L41)
Can we mark it as deprecated this release and sweep it in the following one?
This commit is contained in:
parent
df7c42460f
commit
bea30c3f89
@ -1,594 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sys_ubjson Universal Binary JSON library
|
||||
* @ingroup sys_serialization
|
||||
* @brief Provides a library to read and write UBJSON serialized data
|
||||
*
|
||||
* @deprecated This module is deprecated and will be removed in release 2020.01.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Headers for the UBJSON module
|
||||
*
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* @deprecated This module is deprecated and will be removed in release 2020.01.
|
||||
*/
|
||||
|
||||
#ifndef UBJSON_H
|
||||
#define UBJSON_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ***************************************************************************
|
||||
* READ FUNCTIONS / DEFINITIONS
|
||||
*************************************************************************** */
|
||||
|
||||
/**
|
||||
* @brief Status code of ubjson_read(), ubjson_read_array() and ubjson_read_object() callback
|
||||
*
|
||||
* When ubjson_read(), ubjson_read_array() and ubjson_read_object() iteratively invokes the gives callback function.
|
||||
* The callback function then has to invoke another function such as ubjson_get_i32(), depending on the parameter `type`.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief There is no such value.
|
||||
*
|
||||
* Only used in the callback of ubjson_read() for parameter `type2`.
|
||||
*/
|
||||
UBJSON_ABSENT,
|
||||
|
||||
/**
|
||||
* @brief The next datum is a null value.
|
||||
*
|
||||
* As you might have already guessed: you cannot read a null value.
|
||||
*/
|
||||
UBJSON_TYPE_NULL,
|
||||
|
||||
/**
|
||||
* @brief The next datum is a no-op value.
|
||||
*
|
||||
* As you might have already guessed: you cannot read a no-op value.
|
||||
*/
|
||||
UBJSON_TYPE_NOOP,
|
||||
|
||||
/**
|
||||
* @brief The next datum is a boolean.
|
||||
*
|
||||
* The `content` is the boolean value.
|
||||
* Use ubjson_get_bool() or use `content` verbatim.
|
||||
*/
|
||||
UBJSON_TYPE_BOOL,
|
||||
|
||||
/**
|
||||
* @brief The next datum is an integer that fits into an int32_t.
|
||||
*
|
||||
* Use ubjson_get_i32() to read the value.
|
||||
* `content` is one of ::ubjson_int32_type_t.
|
||||
*/
|
||||
UBJSON_TYPE_INT32,
|
||||
|
||||
/**
|
||||
* @brief The next datum is an integer that fits into an int64_t.
|
||||
*
|
||||
* Use ubjson_get_i64() to read the value.
|
||||
*/
|
||||
UBJSON_TYPE_INT64,
|
||||
|
||||
/**
|
||||
* @brief The next datum is a 32 bit floating point value.
|
||||
*
|
||||
* Use ubjson_get_float() to read the value.
|
||||
*/
|
||||
UBJSON_TYPE_FLOAT,
|
||||
|
||||
/**
|
||||
* @brief The next datum is a 64 bit floating point value.
|
||||
*
|
||||
* Use ubjson_get_double() to read the value.
|
||||
*/
|
||||
UBJSON_TYPE_DOUBLE,
|
||||
|
||||
/* NOTE: High-precision numbers are not implemented, yet. Implement if needed. */
|
||||
/* UBJSON_TYPE_HP_NUMBER, */
|
||||
|
||||
/**
|
||||
* @brief The next datum is a string (blob).
|
||||
*
|
||||
* Use ubjson_get_string() to read the value.
|
||||
* `content` is the length of the blob.
|
||||
*/
|
||||
UBJSON_TYPE_STRING,
|
||||
|
||||
/**
|
||||
* @brief The next datum is an array.
|
||||
*
|
||||
* Use ubjson_read_array() to read its contents.
|
||||
*/
|
||||
UBJSON_ENTER_ARRAY,
|
||||
|
||||
/**
|
||||
* @brief The next datum is an object.
|
||||
*
|
||||
* Use ubjson_read_object() to read its contents.
|
||||
*/
|
||||
UBJSON_ENTER_OBJECT,
|
||||
|
||||
/**
|
||||
* @brief The next datum is an array index.
|
||||
*
|
||||
* This value is emitted for every index in a call to ubjson_read_array().
|
||||
*
|
||||
* `content1` is the array index.
|
||||
* `type2` and `content2` describe the value of the index.
|
||||
*
|
||||
* Arrays can be nested.
|
||||
*/
|
||||
UBJSON_INDEX,
|
||||
|
||||
/**
|
||||
* @brief The next datum is an object key.
|
||||
*
|
||||
* This value is emitted for every index in a call to ubjson_read_object().
|
||||
*
|
||||
* `content1` is the length of the key, invoke ubjson_get_string().
|
||||
* `type2` and `content2` describe the value.
|
||||
*
|
||||
* Objects can be nested.
|
||||
*/
|
||||
UBJSON_KEY,
|
||||
} ubjson_type_t;
|
||||
|
||||
/**
|
||||
* @brief Length of the UBJSON_TYPE_INT32 datum.
|
||||
*/
|
||||
typedef enum {
|
||||
UBJSON_INT32_INT8, /**< The stream contains an int8_t. */
|
||||
UBJSON_INT32_UINT8, /**< The stream contains an uint8_t. */
|
||||
UBJSON_INT32_INT16, /**< The stream contains an int16_t. */
|
||||
UBJSON_INT32_INT32, /**< The stream contains an int32_t. */
|
||||
} ubjson_int32_type_t;
|
||||
|
||||
/**
|
||||
* @brief Return value of ::ubjson_read_callback_t and ubjson_read()
|
||||
*
|
||||
* The callback invoked by ubjson_read(), ubjson_read_array() or ubjson_read_object() can return an error value.
|
||||
* The error value is then returned by the read function.
|
||||
*
|
||||
* The values UBJSON_INVALID_DATA, UBJSON_PREMATURELY_ENDED, and UBJSON_SIZE_ERROR are returned on encoding errors, too.
|
||||
*/
|
||||
typedef enum {
|
||||
UBJSON_OKAY, /**< success / do continue */
|
||||
UBJSON_ABORTED, /**< aborted / do abort */
|
||||
UBJSON_INVALID_DATA, /**< invalid marker or type*/
|
||||
UBJSON_PREMATURELY_ENDED, /**< the stream abruptly ended */
|
||||
UBJSON_SIZE_ERROR, /**< the length of a field exceeded SSIZE_MAX */
|
||||
} ubjson_read_callback_result_t;
|
||||
|
||||
struct __attribute__ ((deprecated("The UBJSON module will be removed in release 2020.01"))) ubjson_cookie;
|
||||
|
||||
/**
|
||||
* @brief A cookie passed between the read and write functions.
|
||||
* @details You probably want to wrap the cookie in some other data structure,
|
||||
* which you retrieve with container_of() in the callback.
|
||||
*/
|
||||
typedef struct ubjson_cookie ubjson_cookie_t
|
||||
__attribute__ ((deprecated("The UBJSON module will be removed in release 2020.01")));
|
||||
|
||||
/**
|
||||
* @brief Method called by ubjson_read() to get more data.
|
||||
* @param[in] cookie The cookie that was passed to ubjson_read().
|
||||
* @param[out] buf The buffer that should be written to.
|
||||
* @param[in] max_len The length of the buffer. Always `>= 1`.
|
||||
* @return @arg `< 0` on error. UBJSON_PREMATURELY_ENDED will be return by ubjson_read().
|
||||
* @arg `> 0` the amount of read data, which must not exceed max_len.
|
||||
*/
|
||||
typedef ssize_t (*ubjson_read_t)(ubjson_cookie_t *__restrict cookie, void *buf, size_t max_len);
|
||||
|
||||
/**
|
||||
* @brief Method called by ubjson_read() to denote the next element in the structure.
|
||||
* @details Depending on the value of type1 a different function, such as ubjson_get_i32(),
|
||||
* must be invoked by the callback function.
|
||||
*
|
||||
* With ubjson_read_array() or ubjson_read_object() the value of type1 is
|
||||
* UBJSON_INDEX or UBJSON_KEY, resp.
|
||||
* @param[in] cookie The cookie that was passed to ubjson_read().
|
||||
* @param[in] type1 The type of the next datum.
|
||||
* @param[in] content1 The sub-type of the next datum.
|
||||
* @param[in] type2 The type of the value that belongs to the next key/index, or UBJSON_ABSENT.
|
||||
* @param[in] content2 The sub-type of the value that belongs to the next key/index.
|
||||
* @returns Either UBJSON_OKAY or UBJSON_ABORTED.
|
||||
*/
|
||||
typedef ubjson_read_callback_result_t (*ubjson_read_callback_t)(ubjson_cookie_t *__restrict cookie,
|
||||
ubjson_type_t type1, ssize_t content1,
|
||||
ubjson_type_t type2, ssize_t content2);
|
||||
|
||||
/**
|
||||
* @brief Method called by ubjson_write_null() and friends.
|
||||
* @details The function in invoked multiple times per written value.
|
||||
* You should use some kind of buffer if you send the data over a stream.
|
||||
*
|
||||
* The function must write the whole buffer before returning.
|
||||
* @param[in] cookie The cookie that was passed to ubjson_write_init().
|
||||
* @param[in] buf Data to write, never NULL.
|
||||
* @param[in] len Data to write, always >= 0.
|
||||
* @returns @arg `< 0` to indicate an error.
|
||||
* @arg `> 0` to indicate success.
|
||||
*/
|
||||
typedef ssize_t (*ubjson_write_t)(ubjson_cookie_t *__restrict cookie, const void *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief See @ref ubjson_cookie_t.
|
||||
*/
|
||||
struct ubjson_cookie {
|
||||
/**
|
||||
* @brief Read/write function
|
||||
* @internal
|
||||
*/
|
||||
union {
|
||||
ubjson_read_t read; /**< read function */
|
||||
ubjson_write_t write; /**< write function */
|
||||
} rw;
|
||||
|
||||
/**
|
||||
* @brief Callback function
|
||||
* @internal
|
||||
*/
|
||||
union {
|
||||
ubjson_read_callback_t read; /**< Callback when a datum was read. */
|
||||
} callback; /**< @internal */
|
||||
|
||||
/**
|
||||
* @brief One byte push-back buffer.
|
||||
* @internal
|
||||
*/
|
||||
char marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Used to read with a setup cookie.
|
||||
* @details You need to use this function instead of ubjson_read() only if
|
||||
* your UBJSON data contains further UBJSON serialized data in a string.
|
||||
*
|
||||
* UBJSON data in a typed array may or may not work.
|
||||
* @param[in] cookie The cookie that is passed to the callback function.
|
||||
* @returns The same as ubjson_read().
|
||||
*/
|
||||
ubjson_read_callback_result_t ubjson_read_next(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/**
|
||||
* @brief The entry function to read UBJSON serialized data.
|
||||
* @details This function invokes the callback function.
|
||||
* The value of type1 in the callback indicates which function
|
||||
* to call inside the callback function, e.g. ubjson_get_i32().
|
||||
*
|
||||
* Nested calls to ubjson_read_array(), ubjson_read_object() or ubjson_read_next()
|
||||
* invoke the same callback function, possibly multiple times.
|
||||
*
|
||||
* You probably want to wrap the cookie in some other data structure,
|
||||
* which you retrieve with container_of() in the callback.
|
||||
*
|
||||
* @deprecated This function and its containing module are deprecated and
|
||||
* will be removed in release 2020.01.
|
||||
*
|
||||
* @param[in] cookie The cookie that is passed to the callback function.
|
||||
* @param[in] read The function that is called to receive more data.
|
||||
* @param[in] callback The callback function.
|
||||
* @returns See \ref ubjson_read_callback_result_t
|
||||
*/
|
||||
static inline ubjson_read_callback_result_t ubjson_read(ubjson_cookie_t *__restrict cookie,
|
||||
ubjson_read_t read,
|
||||
ubjson_read_callback_t callback)
|
||||
{
|
||||
cookie->rw.read = read;
|
||||
cookie->callback.read = callback;
|
||||
cookie->marker = 0;
|
||||
return ubjson_read_next(cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Use in a callback if type1 is UBJSON_KEY or UBJSON_INDEX.
|
||||
* @details Call like ``ubjson_peek_value(cookie, &type2, &content2)``.
|
||||
* @param[in] cookie The cookie that was passed to the callback.
|
||||
* @param[in,out] type Pointer to a variable that was initialized with the value of type2, returns the new type1.
|
||||
* @param[in,out] content Pointer to a variable that was initialized with the value of content2, returns the new content1.
|
||||
* @returns The same as ubjson_read().
|
||||
*/
|
||||
ubjson_read_callback_result_t ubjson_peek_value(ubjson_cookie_t *__restrict cookie,
|
||||
ubjson_type_t *type, ssize_t *content);
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_TYPE_INT32.
|
||||
* @details The value of content1 is one of ubjson_int32_type_t.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @param[in] content The content1 that was passed to the callback function.
|
||||
* @param[out] dest The read datum.
|
||||
* @returns The result of the read callback, probably the amount of read bytes.
|
||||
*/
|
||||
ssize_t ubjson_get_i32(ubjson_cookie_t *__restrict cookie, ssize_t content, int32_t *dest);
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_TYPE_INT64.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @param[in] content The content1 that was passed to the callback function.
|
||||
* @param[out] dest The read datum.
|
||||
* @returns The result of the read callback, probably the amount of read bytes.
|
||||
*/
|
||||
ssize_t ubjson_get_i64(ubjson_cookie_t *__restrict cookie, ssize_t content, int64_t *dest);
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_TYPE_STRING.
|
||||
* @details content1 is the length of the string/blob.
|
||||
* The result is not null-terminated!
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @param[in] content The content1 that was passed to the callback function.
|
||||
* @param[out] dest Buffer to read the string into.
|
||||
* @returns The result of the read callback, probably the amount of read bytes.
|
||||
*/
|
||||
ssize_t ubjson_get_string(ubjson_cookie_t *__restrict cookie, ssize_t content, void *dest);
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_TYPE_BOOL.
|
||||
* @details content1 is the value of the bool. The function only exists for symmetry.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @param[in] content The content1 that was passed to the callback function.
|
||||
* @param[out] dest The read datum.
|
||||
* @returns `1`, the invocation cannot fail.
|
||||
*/
|
||||
static inline ssize_t ubjson_get_bool(ubjson_cookie_t *__restrict cookie, ssize_t content, bool *dest)
|
||||
{
|
||||
(void) cookie;
|
||||
*dest = content;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_TYPE_FLOAT.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @param[in] content The content1 that was passed to the callback function.
|
||||
* @param[out] dest The read datum.
|
||||
* @returns The result of the read callback, probably the amount of read bytes.
|
||||
*/
|
||||
static inline ssize_t ubjson_get_float(ubjson_cookie_t *__restrict cookie, ssize_t content, float *dest)
|
||||
{
|
||||
(void) content;
|
||||
union {
|
||||
float f;
|
||||
int32_t i;
|
||||
} value;
|
||||
ubjson_read_callback_result_t result = ubjson_get_i32(cookie, UBJSON_INT32_INT32, &value.i);
|
||||
*dest = value.f;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_TYPE_DOUBLE.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @param[in] content The content1 that was passed to the callback function.
|
||||
* @param[out] dest The read datum.
|
||||
* @returns The result of the read callback, probably the amount of read bytes.
|
||||
*/
|
||||
static inline ssize_t ubjson_get_double(ubjson_cookie_t *__restrict cookie, ssize_t content, double *dest)
|
||||
{
|
||||
(void) content;
|
||||
union {
|
||||
double f;
|
||||
int64_t i;
|
||||
} value;
|
||||
ubjson_read_callback_result_t result = ubjson_get_i64(cookie, -1, &value.i);
|
||||
*dest = value.f;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_ENTER_ARRAY.
|
||||
* @details Inside this call the callback function will be invoked multiple times,
|
||||
* once per array element, with type1=UBJSON_INDEX,
|
||||
* and content1=running index in the array.
|
||||
*
|
||||
* Use ubjson_peek_value() to determine the type of the element.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @returns The same as ubjson_read().
|
||||
*/
|
||||
ubjson_read_callback_result_t ubjson_read_array(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Call if type1 of the callback was UBJSON_ENTER_OBJECT.
|
||||
* @details Inside this call the callback function will be invoked multiple times,
|
||||
* once per object element, with type1=UBJSON_KEY,
|
||||
* and content1=length of the key string.
|
||||
*
|
||||
* First read the key with ubjson_get_string(), then
|
||||
* use ubjson_peek_value() to determine the type of the element.
|
||||
* @param[in] cookie The cookie that was passed to the callback function.
|
||||
* @returns The same as ubjson_read().
|
||||
*/
|
||||
ubjson_read_callback_result_t ubjson_read_object(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/* ***************************************************************************
|
||||
* WRITE FUNCTIONS / DEFINITIONS
|
||||
*************************************************************************** */
|
||||
|
||||
/**
|
||||
* @brief The first call when you serialize data to UBJSON.
|
||||
* @details There is no corresponding "ubjson_write_finish" function.
|
||||
* The programmer needs to ensure that the API is used correctly.
|
||||
* The library won't complain if you write multiple values that are not
|
||||
* inside an array or object. The result will just not be properly serialized.
|
||||
*
|
||||
* @deprecated This function and its containing module are deprecated and
|
||||
* will be removed in release 2020.01
|
||||
*
|
||||
* @param[out] cookie The cookie that will be passed to ubjson_write_null() and friends.
|
||||
* @param[in] write_fun The function that will be called to write data.
|
||||
*/
|
||||
static inline void ubjson_write_init(ubjson_cookie_t *__restrict cookie, ubjson_write_t write_fun)
|
||||
{
|
||||
cookie->rw.write = write_fun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a null value.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
*/
|
||||
ssize_t ubjson_write_null(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/**
|
||||
* @brief Write a no-operation value.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_noop(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/**
|
||||
* @brief Write a boolean value.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The boolean value to write.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_bool(ubjson_cookie_t *__restrict cookie, bool value);
|
||||
|
||||
/**
|
||||
* @brief Write an integer value.
|
||||
* @details The library will determine the smallest serialization for the value itself.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The integer value to write.
|
||||
*/
|
||||
ssize_t ubjson_write_i32(ubjson_cookie_t *__restrict cookie, int32_t value);
|
||||
|
||||
/**
|
||||
* @brief Write an integer value.
|
||||
* @details The library will determine the smallest serialization for the value itself.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The integer value to write.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_i64(ubjson_cookie_t *__restrict cookie, int64_t value);
|
||||
|
||||
/**
|
||||
* @brief Write a floating point value.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The integer value to write.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_float(ubjson_cookie_t *__restrict cookie, float value);
|
||||
|
||||
/**
|
||||
* @brief Write a floating point value.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The integer value to write.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_double(ubjson_cookie_t *__restrict cookie, double value);
|
||||
|
||||
/**
|
||||
* @brief Write a string or blob.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The string or blob to write.
|
||||
* @param[in] len The length of the string or blob.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_string(ubjson_cookie_t *__restrict cookie, const void *value, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Open an array.
|
||||
* @details Write multiple elements inside this array.
|
||||
* Call ubjson_close_array() after the whole content was written.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_open_array(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/**
|
||||
* @brief Open an array with a known length.
|
||||
* @details Do not call ubjson_close_array().
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] len Length of the array.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_open_array_len(ubjson_cookie_t *__restrict cookie, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Close an array that was opened with ubjson_open_array().
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_close_array(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/**
|
||||
* @brief Open an object.
|
||||
* @details Write multiple keys inside this object.
|
||||
* Call ubjson_close_object() after the whole content was written.
|
||||
*
|
||||
* For each element first write the key with ubjson_write_key(),
|
||||
* then invoke the function to write the value.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_open_object(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
/**
|
||||
* @brief Open an object with a known length.
|
||||
* @details For each element first write the key with ubjson_write_key(),
|
||||
* then invoke the function to write the value.
|
||||
*
|
||||
* Do not call ubjson_close_object().
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] len Number of keys inside the object.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_open_object_len(ubjson_cookie_t *__restrict cookie, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Write a key inside an object.
|
||||
* @details For each element first write the key,
|
||||
* then invoke the function to write the value.
|
||||
*
|
||||
* It is up to the programmer to ensure that there are no duplicated keys.
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @param[in] value The key, should be a UTF-8 string.
|
||||
* @param[in] len The length of the key.
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_write_key(ubjson_cookie_t *__restrict cookie, const void *value, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Close an array that was opened with ubjson_open_object().
|
||||
* @param[in] cookie The cookie that was initialized with ubjson_write_init().
|
||||
* @returns The result of the supplied @ref ubjson_write_t function.
|
||||
*/
|
||||
ssize_t ubjson_close_object(ubjson_cookie_t *__restrict cookie);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UBJSON_H */
|
||||
/** @} */
|
@ -1 +0,0 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef UBJSON_INTERNAL_H
|
||||
#define UBJSON_INTERNAL_H
|
||||
|
||||
/* compare http://ubjson.org/type-reference/ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UBJSON_MARKER_NULL = 'Z',
|
||||
UBJSON_MARKER_NOOP = 'N',
|
||||
|
||||
UBJSON_MARKER_TRUE = 'T',
|
||||
UBJSON_MARKER_FALSE = 'F',
|
||||
|
||||
UBJSON_MARKER_INT8 = 'i',
|
||||
UBJSON_MARKER_UINT8 = 'U',
|
||||
UBJSON_MARKER_INT16 = 'I',
|
||||
UBJSON_MARKER_INT32 = 'l',
|
||||
UBJSON_MARKER_INT64 = 'L',
|
||||
|
||||
UBJSON_MARKER_FLOAT32 = 'd',
|
||||
UBJSON_MARKER_FLOAT64 = 'D',
|
||||
UBJSON_MARKER_HP_NUMBER = 'H',
|
||||
|
||||
UBJSON_MARKER_CHAR = 'C',
|
||||
UBJSON_MARKER_STRING = 'S',
|
||||
|
||||
UBJSON_MARKER_ARRAY_START = '[',
|
||||
UBJSON_MARKER_ARRAY_END = ']',
|
||||
|
||||
UBJSON_MARKER_OBJECT_START = '{',
|
||||
UBJSON_MARKER_OBJECT_END = '}',
|
||||
|
||||
UBJSON_MARKER_COUNT = '#',
|
||||
UBJSON_MARKER_TYPE = '$',
|
||||
} ubjson_marker_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UBJSON_INTERNAL_H */
|
@ -1,392 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_ubjson
|
||||
* @{
|
||||
* @file
|
||||
* @brief Universal Binary JSON deserializer
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "ubjson-internal.h"
|
||||
#include "ubjson.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
#define READ_MARKER() \
|
||||
do { \
|
||||
result = _ubjson_read_marker(cookie, &marker); \
|
||||
if (result != UBJSON_OKAY) { \
|
||||
return result; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static ubjson_read_callback_result_t _ubjson_read_marker(ubjson_cookie_t *restrict cookie,
|
||||
char *marker)
|
||||
{
|
||||
while (1) {
|
||||
ssize_t bytes_read;
|
||||
|
||||
*marker = cookie->marker;
|
||||
if (!*marker) {
|
||||
bytes_read = cookie->rw.read(cookie, marker, 1);
|
||||
}
|
||||
else {
|
||||
cookie->marker = 0;
|
||||
bytes_read = 1;
|
||||
}
|
||||
|
||||
if (bytes_read == 1) {
|
||||
return UBJSON_OKAY;
|
||||
}
|
||||
else if (bytes_read != 0) {
|
||||
return UBJSON_PREMATURELY_ENDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t ubjson_get_string(ubjson_cookie_t *restrict cookie, ssize_t length, void *dest_)
|
||||
{
|
||||
ssize_t total = 0;
|
||||
char *dest = dest_;
|
||||
while (total < length) {
|
||||
ssize_t read = cookie->rw.read(cookie, dest, length - total);
|
||||
if (read < 0) {
|
||||
return read;
|
||||
}
|
||||
total += read;
|
||||
dest += read;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
ssize_t ubjson_get_i32(ubjson_cookie_t *restrict cookie, ssize_t content, int32_t *dest)
|
||||
{
|
||||
static const int8_t LENGTHS[] = { 1, 1, 2, 4 };
|
||||
|
||||
union {
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
network_uint16_t i16;
|
||||
network_uint32_t i32;
|
||||
} value;
|
||||
|
||||
int type = content;
|
||||
|
||||
ssize_t result = ubjson_get_string(cookie, LENGTHS[type], &value);
|
||||
if (result > 0) {
|
||||
switch (type) {
|
||||
case UBJSON_INT32_INT8:
|
||||
*dest = value.i8;
|
||||
break;
|
||||
case UBJSON_INT32_UINT8:
|
||||
*dest = value.u8;
|
||||
break;
|
||||
case UBJSON_INT32_INT16:
|
||||
*dest = (int16_t) byteorder_ntohs(value.i16);
|
||||
break;
|
||||
case UBJSON_INT32_INT32:
|
||||
*dest = (int32_t) byteorder_ntohl(value.i32);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_get_i64(ubjson_cookie_t *restrict cookie, ssize_t content, int64_t *dest)
|
||||
{
|
||||
(void) content;
|
||||
|
||||
network_uint64_t buf;
|
||||
ssize_t result = ubjson_get_string(cookie, 8, &buf);
|
||||
*dest = byteorder_ntohll(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
static ubjson_read_callback_result_t _ubjson_read_length(ubjson_cookie_t *restrict cookie,
|
||||
ssize_t *len)
|
||||
{
|
||||
ubjson_type_t type;
|
||||
ssize_t content = 0;
|
||||
ubjson_read_callback_result_t result = ubjson_peek_value(cookie, &type, &content);
|
||||
if (result != UBJSON_OKAY) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t len64 = -1;
|
||||
ssize_t read;
|
||||
if (type == UBJSON_TYPE_INT32) {
|
||||
int32_t len32;
|
||||
read = ubjson_get_i32(cookie, content, &len32);
|
||||
if (read > 0) {
|
||||
len64 = len32;
|
||||
}
|
||||
}
|
||||
else if (type == UBJSON_TYPE_INT64) {
|
||||
read = ubjson_get_i64(cookie, content, &len64);
|
||||
}
|
||||
else {
|
||||
return UBJSON_INVALID_DATA;
|
||||
}
|
||||
|
||||
if (read <= 0) {
|
||||
return UBJSON_PREMATURELY_ENDED;
|
||||
}
|
||||
else if ((ssize_t) len64 < 0) {
|
||||
return UBJSON_SIZE_ERROR;
|
||||
}
|
||||
else if (len64 < 0) {
|
||||
return UBJSON_INVALID_DATA;
|
||||
}
|
||||
|
||||
*len = len64;
|
||||
return UBJSON_OKAY;
|
||||
}
|
||||
|
||||
static ubjson_read_callback_result_t _ubjson_get_call(ubjson_cookie_t *restrict cookie,
|
||||
char marker,
|
||||
ubjson_type_t *type, ssize_t *content)
|
||||
{
|
||||
*content = -1;
|
||||
|
||||
switch (marker) {
|
||||
case UBJSON_MARKER_NULL:
|
||||
*type = UBJSON_TYPE_NULL;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_NOOP:
|
||||
*type = UBJSON_TYPE_NOOP;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_TRUE:
|
||||
case UBJSON_MARKER_FALSE:
|
||||
*type = UBJSON_TYPE_BOOL,
|
||||
*content = (marker == UBJSON_MARKER_TRUE);
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_INT8:
|
||||
*content = UBJSON_INT32_INT8;
|
||||
*type = UBJSON_TYPE_INT32;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_UINT8:
|
||||
*content = UBJSON_INT32_UINT8;
|
||||
*type = UBJSON_TYPE_INT32;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_INT16:
|
||||
*content = UBJSON_INT32_INT16;
|
||||
*type = UBJSON_TYPE_INT32;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_INT32:
|
||||
*content = UBJSON_INT32_INT32;
|
||||
*type = UBJSON_TYPE_INT32;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_INT64:
|
||||
*type = UBJSON_TYPE_INT64;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_CHAR:
|
||||
*type = UBJSON_TYPE_STRING;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_FLOAT32:
|
||||
*type = UBJSON_TYPE_FLOAT;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_FLOAT64:
|
||||
*type = UBJSON_TYPE_DOUBLE;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_STRING: {
|
||||
ubjson_read_callback_result_t result = _ubjson_read_length(cookie, content);
|
||||
if (result != UBJSON_OKAY) {
|
||||
return result;
|
||||
}
|
||||
*type = UBJSON_TYPE_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
case UBJSON_MARKER_ARRAY_START:
|
||||
*type = UBJSON_ENTER_ARRAY;
|
||||
break;
|
||||
|
||||
case UBJSON_MARKER_OBJECT_START:
|
||||
*type = UBJSON_ENTER_OBJECT;
|
||||
break;
|
||||
|
||||
/* NOTE: High-precision numbers are not implemented, yet. Implement if needed.
|
||||
*
|
||||
* case UBJSON_MARKER_HP_NUMBER:
|
||||
* ...
|
||||
* break;
|
||||
*/
|
||||
|
||||
case UBJSON_MARKER_ARRAY_END:
|
||||
case UBJSON_MARKER_OBJECT_END:
|
||||
case UBJSON_MARKER_COUNT:
|
||||
case UBJSON_MARKER_TYPE:
|
||||
default:
|
||||
return UBJSON_INVALID_DATA;
|
||||
}
|
||||
|
||||
return UBJSON_OKAY;
|
||||
}
|
||||
|
||||
typedef bool (*_ubjson_read_struct_continue)(ubjson_cookie_t *restrict cookie, char marker,
|
||||
ubjson_read_callback_result_t *result,
|
||||
ssize_t count, ssize_t index,
|
||||
ubjson_type_t *type1, ssize_t *content1);
|
||||
|
||||
static ubjson_read_callback_result_t _ubjson_read_struct(ubjson_cookie_t *restrict cookie,
|
||||
_ubjson_read_struct_continue get_continue)
|
||||
{
|
||||
ubjson_read_callback_result_t result;
|
||||
ssize_t count = -1;
|
||||
char marker, type_marker = 0;
|
||||
|
||||
READ_MARKER();
|
||||
|
||||
if (marker == UBJSON_MARKER_TYPE) {
|
||||
READ_MARKER();
|
||||
if (marker == 0) {
|
||||
return UBJSON_INVALID_DATA;
|
||||
}
|
||||
type_marker = marker;
|
||||
READ_MARKER();
|
||||
}
|
||||
|
||||
if (marker == UBJSON_MARKER_COUNT) {
|
||||
result = _ubjson_read_length(cookie, &count);
|
||||
if (result != UBJSON_OKAY) {
|
||||
return result;
|
||||
}
|
||||
READ_MARKER();
|
||||
}
|
||||
|
||||
cookie->marker = marker;
|
||||
|
||||
if ((type_marker != 0) && (count < 0)) {
|
||||
/* If a type is specified, a count must be specified as well.
|
||||
* Otherwise a ']' could either be data (e.g. the character ']'),
|
||||
* or be meant to close the array.
|
||||
*/
|
||||
return UBJSON_INVALID_DATA;
|
||||
}
|
||||
|
||||
for (ssize_t index = 0; (count < 0) || (index < count); ++index) {
|
||||
ubjson_type_t type1;
|
||||
ssize_t content1;
|
||||
|
||||
READ_MARKER();
|
||||
if (!get_continue(cookie, marker, &result, count, index, &type1, &content1)
|
||||
|| (result != UBJSON_OKAY)) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = cookie->callback.read(cookie, type1, content1,
|
||||
UBJSON_ABSENT, (unsigned char) type_marker);
|
||||
if (result != UBJSON_OKAY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool _ubjson_read_array_continue(ubjson_cookie_t *restrict cookie, char marker,
|
||||
ubjson_read_callback_result_t *result,
|
||||
ssize_t count, ssize_t index,
|
||||
ubjson_type_t *type1, ssize_t *content1)
|
||||
{
|
||||
if (marker == UBJSON_MARKER_ARRAY_END) {
|
||||
if (count >= 0) {
|
||||
*result = UBJSON_INVALID_DATA;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cookie->marker = marker;
|
||||
|
||||
*type1 = UBJSON_INDEX;
|
||||
*content1 = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _ubjson_read_object_continue(ubjson_cookie_t *restrict cookie, char marker,
|
||||
ubjson_read_callback_result_t *result,
|
||||
ssize_t count, ssize_t index,
|
||||
ubjson_type_t *type1, ssize_t *content1)
|
||||
{
|
||||
(void) index;
|
||||
|
||||
if (marker == UBJSON_MARKER_OBJECT_END) {
|
||||
if (count >= 0) {
|
||||
*result = UBJSON_INVALID_DATA;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cookie->marker = marker;
|
||||
|
||||
*type1 = UBJSON_KEY;
|
||||
*result = _ubjson_read_length(cookie, content1);
|
||||
return true;
|
||||
}
|
||||
|
||||
ubjson_read_callback_result_t ubjson_read_array(ubjson_cookie_t *restrict cookie)
|
||||
{
|
||||
return _ubjson_read_struct(cookie, _ubjson_read_array_continue);
|
||||
}
|
||||
|
||||
ubjson_read_callback_result_t ubjson_read_object(ubjson_cookie_t *restrict cookie)
|
||||
{
|
||||
return _ubjson_read_struct(cookie, _ubjson_read_object_continue);
|
||||
}
|
||||
|
||||
ubjson_read_callback_result_t ubjson_read_next(ubjson_cookie_t *restrict cookie)
|
||||
{
|
||||
char marker;
|
||||
ubjson_read_callback_result_t result;
|
||||
READ_MARKER();
|
||||
|
||||
ubjson_type_t type;
|
||||
ssize_t content;
|
||||
result = _ubjson_get_call(cookie, marker, &type, &content);
|
||||
if (result != UBJSON_OKAY) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return cookie->callback.read(cookie, type, content, UBJSON_ABSENT, 0);
|
||||
}
|
||||
|
||||
ubjson_read_callback_result_t ubjson_peek_value(ubjson_cookie_t *restrict cookie,
|
||||
ubjson_type_t *type, ssize_t *content)
|
||||
{
|
||||
char marker = (char) *content;
|
||||
if (marker == 0) {
|
||||
ubjson_read_callback_result_t result;
|
||||
READ_MARKER();
|
||||
}
|
||||
return _ubjson_get_call(cookie, marker, type, content);
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_ubjson
|
||||
* @{
|
||||
* @file
|
||||
* @brief Universal Binary JSON deserializer
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "ubjson-internal.h"
|
||||
#include "ubjson.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define WRITE_CALL(FUN, ...) \
|
||||
do { \
|
||||
ssize_t wrote = (FUN)(__VA_ARGS__); \
|
||||
if (wrote < 0) { \
|
||||
return wrote; \
|
||||
} \
|
||||
result += wrote; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_BUF(BUF, COUNT) \
|
||||
WRITE_CALL(cookie->rw.write, cookie, (BUF), (COUNT))
|
||||
|
||||
#define WRITE_MARKER(MARKER) \
|
||||
do { \
|
||||
char marker_buf[] = { (char) (MARKER) }; \
|
||||
WRITE_BUF(marker_buf, 1); \
|
||||
} while (0)
|
||||
|
||||
#define MARKER_FUN(NAME, MARKER) \
|
||||
ssize_t NAME(ubjson_cookie_t *restrict cookie) \
|
||||
{ \
|
||||
ssize_t result = 0; \
|
||||
WRITE_MARKER((MARKER)); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
MARKER_FUN(ubjson_write_null, UBJSON_MARKER_NULL)
|
||||
MARKER_FUN(ubjson_write_noop, UBJSON_MARKER_NOOP)
|
||||
|
||||
MARKER_FUN(ubjson_open_array, UBJSON_MARKER_ARRAY_START)
|
||||
MARKER_FUN(ubjson_close_array, UBJSON_MARKER_ARRAY_END)
|
||||
|
||||
MARKER_FUN(ubjson_open_object, UBJSON_MARKER_OBJECT_START)
|
||||
MARKER_FUN(ubjson_close_object, UBJSON_MARKER_OBJECT_END)
|
||||
|
||||
ssize_t ubjson_write_bool(ubjson_cookie_t *restrict cookie, bool value)
|
||||
{
|
||||
static const char marker_false[] = { UBJSON_MARKER_FALSE };
|
||||
static const char marker_true[] = { UBJSON_MARKER_TRUE };
|
||||
return cookie->rw.write(cookie, value ? &marker_true : &marker_false, 1);
|
||||
}
|
||||
|
||||
ssize_t ubjson_write_i32(ubjson_cookie_t *restrict cookie, int32_t value)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
if ((INT8_MIN <= value) && (value <= INT8_MAX)) {
|
||||
WRITE_MARKER(UBJSON_MARKER_INT8);
|
||||
WRITE_MARKER((uint8_t) value);
|
||||
}
|
||||
else if ((0 <= value) && (value <= UINT8_MAX)) {
|
||||
WRITE_MARKER(UBJSON_MARKER_UINT8);
|
||||
WRITE_MARKER((uint8_t) value);
|
||||
}
|
||||
else if ((INT16_MIN <= value) && (value <= UINT16_MAX)) {
|
||||
WRITE_MARKER(UBJSON_MARKER_INT16);
|
||||
network_uint16_t buf = byteorder_htons((uint16_t) value);
|
||||
WRITE_BUF(&buf, sizeof(buf));
|
||||
}
|
||||
else {
|
||||
WRITE_MARKER(UBJSON_MARKER_INT32);
|
||||
network_uint32_t buf = byteorder_htonl((uint32_t) value);
|
||||
WRITE_BUF(&buf, sizeof(buf));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_write_i64(ubjson_cookie_t *restrict cookie, int64_t value)
|
||||
{
|
||||
if ((INT32_MIN <= value) && (value <= INT32_MAX)) {
|
||||
return ubjson_write_i32(cookie, (int32_t) value);
|
||||
}
|
||||
|
||||
ssize_t result = 0;
|
||||
WRITE_MARKER(UBJSON_MARKER_INT64);
|
||||
network_uint64_t buf = byteorder_htonll((uint64_t) value);
|
||||
WRITE_BUF(&buf, sizeof(buf));
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_write_float(ubjson_cookie_t *restrict cookie, float value)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
} v = { .f = value };
|
||||
|
||||
ssize_t result = 0;
|
||||
WRITE_MARKER(UBJSON_MARKER_FLOAT32);
|
||||
network_uint32_t buf = byteorder_htonl(v.i);
|
||||
WRITE_BUF(&buf, sizeof(buf));
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_write_double(ubjson_cookie_t *restrict cookie, double value)
|
||||
{
|
||||
union {
|
||||
double f;
|
||||
uint64_t i;
|
||||
} v = { .f = value };
|
||||
|
||||
ssize_t result = 0;
|
||||
WRITE_MARKER(UBJSON_MARKER_FLOAT64);
|
||||
network_uint64_t buf = byteorder_htonll(v.i);
|
||||
WRITE_BUF(&buf, sizeof(buf));
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_write_string(ubjson_cookie_t *restrict cookie, const void *value, size_t len)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
WRITE_MARKER(UBJSON_MARKER_STRING);
|
||||
WRITE_CALL(ubjson_write_key, cookie, value, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t _ubjson_write_length(ubjson_cookie_t *restrict cookie, size_t len)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
WRITE_MARKER(UBJSON_MARKER_COUNT);
|
||||
WRITE_CALL(ubjson_write_i64, cookie, (int64_t) len);
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_open_array_len(ubjson_cookie_t *restrict cookie, size_t len)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
WRITE_CALL(ubjson_open_array, cookie);
|
||||
if (len > 0) {
|
||||
WRITE_CALL(_ubjson_write_length, cookie, len);
|
||||
}
|
||||
else {
|
||||
WRITE_CALL(ubjson_close_array, cookie);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_open_object_len(ubjson_cookie_t *restrict cookie, size_t len)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
WRITE_CALL(ubjson_open_object, cookie);
|
||||
if (len > 0) {
|
||||
WRITE_CALL(_ubjson_write_length, cookie, len);
|
||||
}
|
||||
else {
|
||||
WRITE_CALL(ubjson_close_object, cookie);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t ubjson_write_key(ubjson_cookie_t *restrict cookie, const void *value, size_t len)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
WRITE_CALL(ubjson_write_i64, cookie, (int64_t) len);
|
||||
WRITE_BUF(value, len);
|
||||
return result;
|
||||
}
|
@ -1 +0,0 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1,4 +0,0 @@
|
||||
USEMODULE += ubjson
|
||||
USEMODULE += pipe
|
||||
|
||||
CFLAGS += -Wno-error=deprecated-declarations
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "tests-ubjson.h"
|
||||
|
||||
typedef enum {
|
||||
BEFORE_ARRAY_1 = __LINE__,
|
||||
IN_ARRAY_1 = __LINE__,
|
||||
|
||||
BEFORE_ARRAY_2 = __LINE__,
|
||||
IN_ARRAY_2 = __LINE__,
|
||||
|
||||
BEFORE_END = __LINE__,
|
||||
} test_ubjson_empty_array_state_t;
|
||||
|
||||
typedef struct {
|
||||
ubjson_cookie_t cookie;
|
||||
test_ubjson_empty_array_state_t state;
|
||||
} test_ubjson_empty_array_receiver_cookie_t;
|
||||
|
||||
static void test_ubjson_empty_array_receiver_callback_sub(
|
||||
ubjson_cookie_t *restrict cookie,
|
||||
ubjson_type_t type1, ssize_t content1,
|
||||
ubjson_type_t type2, ssize_t content2,
|
||||
ubjson_read_callback_result_t *result)
|
||||
{
|
||||
*result = UBJSON_ABORTED;
|
||||
|
||||
(void) content1, (void) type2, (void) content2;
|
||||
|
||||
test_ubjson_empty_array_receiver_cookie_t *state;
|
||||
state = container_of(cookie, test_ubjson_empty_array_receiver_cookie_t, cookie);
|
||||
|
||||
switch (state->state) {
|
||||
case BEFORE_ARRAY_1:
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_ENTER_ARRAY, type1);
|
||||
state->state = IN_ARRAY_1;
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY, ubjson_read_array(cookie));
|
||||
state->state = BEFORE_ARRAY_2;
|
||||
break;
|
||||
|
||||
case IN_ARRAY_1:
|
||||
TEST_FAIL("The empty array was not empty (1)");
|
||||
break;
|
||||
|
||||
case BEFORE_ARRAY_2:
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_ENTER_ARRAY, type1);
|
||||
state->state = IN_ARRAY_2;
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY, ubjson_read_array(cookie));
|
||||
state->state = BEFORE_END;
|
||||
break;
|
||||
|
||||
case IN_ARRAY_2:
|
||||
TEST_FAIL("The empty array was not empty (2)");
|
||||
break;
|
||||
|
||||
case BEFORE_END:
|
||||
TEST_FAIL("Content after the end");
|
||||
break;
|
||||
|
||||
default:
|
||||
TEST_FAIL("The cookie was corrupted");
|
||||
break;
|
||||
}
|
||||
|
||||
*result = UBJSON_OKAY;
|
||||
}
|
||||
|
||||
static ubjson_read_callback_result_t test_ubjson_empty_array_receiver_callback(
|
||||
ubjson_cookie_t *restrict cookie,
|
||||
ubjson_type_t type1, ssize_t content1,
|
||||
ubjson_type_t type2, ssize_t content2)
|
||||
{
|
||||
ubjson_read_callback_result_t result;
|
||||
test_ubjson_empty_array_receiver_callback_sub(cookie, type1, content1, type2, content2, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void test_ubjson_empty_array_receiver(void)
|
||||
{
|
||||
test_ubjson_empty_array_receiver_cookie_t state;
|
||||
state.state = BEFORE_ARRAY_1;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY,
|
||||
ubjson_read(&state.cookie, test_ubjson_read_fun,
|
||||
test_ubjson_empty_array_receiver_callback));
|
||||
TEST_ASSERT_EQUAL_INT(BEFORE_ARRAY_2, state.state);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY,
|
||||
ubjson_read(&state.cookie, test_ubjson_read_fun,
|
||||
test_ubjson_empty_array_receiver_callback));
|
||||
TEST_ASSERT_EQUAL_INT(BEFORE_END, state.state);
|
||||
}
|
||||
|
||||
#undef EMBUNIT_ERROR_RETURN
|
||||
#define EMBUNIT_ERROR_RETURN
|
||||
|
||||
static void test_ubjson_empty_array_sender(void)
|
||||
{
|
||||
ubjson_cookie_t cookie;
|
||||
ubjson_write_init(&cookie, test_ubjson_write_fun);
|
||||
|
||||
TEST_ASSERT(ubjson_open_array(&cookie) > 0);
|
||||
TEST_ASSERT(ubjson_close_array(&cookie) > 0);
|
||||
TEST_ASSERT(ubjson_open_array_len(&cookie, 0) > 0);
|
||||
}
|
||||
|
||||
void test_ubjson_empty_array(void)
|
||||
{
|
||||
test_ubjson_test(test_ubjson_empty_array_sender,
|
||||
test_ubjson_empty_array_receiver);
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "tests-ubjson.h"
|
||||
|
||||
typedef enum {
|
||||
BEFORE_ARRAY_1 = __LINE__,
|
||||
IN_ARRAY_1 = __LINE__,
|
||||
|
||||
BEFORE_ARRAY_2 = __LINE__,
|
||||
IN_ARRAY_2 = __LINE__,
|
||||
|
||||
BEFORE_END = __LINE__,
|
||||
} test_ubjson_empty_object_state_t;
|
||||
|
||||
typedef struct {
|
||||
ubjson_cookie_t cookie;
|
||||
test_ubjson_empty_object_state_t state;
|
||||
} test_ubjson_empty_object_receiver_cookie_t;
|
||||
|
||||
static void test_ubjson_empty_object_receiver_callback_sub(
|
||||
ubjson_cookie_t *restrict cookie,
|
||||
ubjson_type_t type1, ssize_t content1,
|
||||
ubjson_type_t type2, ssize_t content2,
|
||||
ubjson_read_callback_result_t *result)
|
||||
{
|
||||
*result = UBJSON_ABORTED;
|
||||
|
||||
(void) content1, (void) type2, (void) content2;
|
||||
|
||||
test_ubjson_empty_object_receiver_cookie_t *state;
|
||||
state = container_of(cookie, test_ubjson_empty_object_receiver_cookie_t, cookie);
|
||||
|
||||
switch (state->state) {
|
||||
case BEFORE_ARRAY_1:
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_ENTER_OBJECT, type1);
|
||||
state->state = IN_ARRAY_1;
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY, ubjson_read_object(cookie));
|
||||
state->state = BEFORE_ARRAY_2;
|
||||
break;
|
||||
|
||||
case IN_ARRAY_1:
|
||||
TEST_FAIL("The empty object was not empty (1)");
|
||||
break;
|
||||
|
||||
case BEFORE_ARRAY_2:
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_ENTER_OBJECT, type1);
|
||||
state->state = IN_ARRAY_2;
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY, ubjson_read_object(cookie));
|
||||
state->state = BEFORE_END;
|
||||
break;
|
||||
|
||||
case IN_ARRAY_2:
|
||||
TEST_FAIL("The empty object was not empty (2)");
|
||||
break;
|
||||
|
||||
case BEFORE_END:
|
||||
TEST_FAIL("Content after the end");
|
||||
break;
|
||||
|
||||
default:
|
||||
TEST_FAIL("The cookie was corrupted");
|
||||
break;
|
||||
}
|
||||
|
||||
*result = UBJSON_OKAY;
|
||||
}
|
||||
|
||||
static ubjson_read_callback_result_t test_ubjson_empty_object_receiver_callback(
|
||||
ubjson_cookie_t *restrict cookie,
|
||||
ubjson_type_t type1, ssize_t content1,
|
||||
ubjson_type_t type2, ssize_t content2)
|
||||
{
|
||||
ubjson_read_callback_result_t result;
|
||||
test_ubjson_empty_object_receiver_callback_sub(cookie, type1, content1, type2, content2, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef EMBUNIT_ERROR_RETURN
|
||||
#define EMBUNIT_ERROR_RETURN
|
||||
|
||||
static void test_ubjson_empty_object_receiver(void)
|
||||
{
|
||||
test_ubjson_empty_object_receiver_cookie_t state;
|
||||
state.state = BEFORE_ARRAY_1;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY,
|
||||
ubjson_read(&state.cookie, test_ubjson_read_fun,
|
||||
test_ubjson_empty_object_receiver_callback));
|
||||
TEST_ASSERT_EQUAL_INT(BEFORE_ARRAY_2, state.state);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(UBJSON_OKAY,
|
||||
ubjson_read(&state.cookie, test_ubjson_read_fun,
|
||||
test_ubjson_empty_object_receiver_callback));
|
||||
TEST_ASSERT_EQUAL_INT(BEFORE_END, state.state);
|
||||
}
|
||||
|
||||
#undef EMBUNIT_ERROR_RETURN
|
||||
#define EMBUNIT_ERROR_RETURN
|
||||
|
||||
static void test_ubjson_empty_object_sender(void)
|
||||
{
|
||||
ubjson_cookie_t cookie;
|
||||
ubjson_write_init(&cookie, test_ubjson_write_fun);
|
||||
|
||||
TEST_ASSERT(ubjson_open_object(&cookie) > 0);
|
||||
TEST_ASSERT(ubjson_close_object(&cookie) > 0);
|
||||
TEST_ASSERT(ubjson_open_object_len(&cookie, 0) > 0);
|
||||
}
|
||||
|
||||
void test_ubjson_empty_object(void)
|
||||
{
|
||||
test_ubjson_test(test_ubjson_empty_object_sender,
|
||||
test_ubjson_empty_object_receiver);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "tests-ubjson.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "sched.h"
|
||||
#include "msg.h"
|
||||
#include "mutex.h"
|
||||
#include "pipe.h"
|
||||
#include "irq.h"
|
||||
|
||||
static pipe_t communication_pipe;
|
||||
static ringbuffer_t pipe_rb;
|
||||
static char pipe_buffer[16];
|
||||
|
||||
static char receiver_stack[THREAD_STACKSIZE_DEFAULT];
|
||||
|
||||
typedef struct {
|
||||
void (*run)(void);
|
||||
thread_t *main_thread;
|
||||
mutex_t mutexes[2];
|
||||
} test_ubjson_receiver_data_t;
|
||||
|
||||
static void ubjson_set_up(void)
|
||||
{
|
||||
ringbuffer_init(&pipe_rb, pipe_buffer, sizeof(pipe_buffer));
|
||||
pipe_init(&communication_pipe, &pipe_rb, NULL);
|
||||
}
|
||||
|
||||
ssize_t test_ubjson_write_fun(ubjson_cookie_t *restrict cookie, const void *buf, size_t len)
|
||||
{
|
||||
(void) cookie;
|
||||
ssize_t total = 0;
|
||||
while (total < (ssize_t) len) {
|
||||
ssize_t subtotal = pipe_write(&communication_pipe, buf, len);
|
||||
if (subtotal < 0) {
|
||||
return subtotal;
|
||||
}
|
||||
total += subtotal;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
ssize_t test_ubjson_read_fun(ubjson_cookie_t *restrict cookie, void *buf, size_t len)
|
||||
{
|
||||
(void) cookie;
|
||||
return pipe_read(&communication_pipe, buf, len);
|
||||
}
|
||||
|
||||
static void *test_ubjson_receiver_trampoline(void *arg)
|
||||
{
|
||||
test_ubjson_receiver_data_t *data = arg;
|
||||
data->run();
|
||||
|
||||
mutex_unlock(&data->mutexes[0]);
|
||||
mutex_lock(&data->mutexes[1]);
|
||||
|
||||
irq_disable();
|
||||
sched_set_status(data->main_thread, STATUS_PENDING);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void test_ubjson_test(void (*sender_fun)(void), void (*receiver_fun)(void))
|
||||
{
|
||||
test_ubjson_receiver_data_t data = {
|
||||
.run = receiver_fun,
|
||||
.main_thread = (thread_t *) sched_active_thread,
|
||||
.mutexes = { MUTEX_INIT, MUTEX_INIT },
|
||||
};
|
||||
mutex_lock(&data.mutexes[0]);
|
||||
mutex_lock(&data.mutexes[1]);
|
||||
|
||||
kernel_pid_t receiver_pid = thread_create(receiver_stack, sizeof(receiver_stack),
|
||||
THREAD_PRIORITY_MAIN,
|
||||
THREAD_CREATE_WOUT_YIELD,
|
||||
test_ubjson_receiver_trampoline, &data, "receiver");
|
||||
TEST_ASSERT(pid_is_valid(receiver_pid));
|
||||
|
||||
sender_fun();
|
||||
|
||||
mutex_lock(&data.mutexes[0]);
|
||||
mutex_unlock_and_sleep(&data.mutexes[1]);
|
||||
}
|
||||
|
||||
static Test *tests_ubjson_tests(void)
|
||||
{
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_ubjson_empty_array),
|
||||
new_TestFixture(test_ubjson_empty_object),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(ubjson_tests, ubjson_set_up, NULL, fixtures);
|
||||
|
||||
return (Test *) &ubjson_tests;
|
||||
}
|
||||
|
||||
void tests_ubjson(void)
|
||||
{
|
||||
TESTS_RUN(tests_ubjson_tests());
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup unittests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Unittests for the ``ubjson`` module
|
||||
*
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef TESTS_UBJSON_H
|
||||
#define TESTS_UBJSON_H
|
||||
|
||||
#include "embUnit.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#include "ubjson.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ssize_t test_ubjson_write_fun(ubjson_cookie_t *__restrict cookie, const void *buf, size_t len);
|
||||
ssize_t test_ubjson_read_fun(ubjson_cookie_t *__restrict cookie, void *buf, size_t len);
|
||||
|
||||
void test_ubjson_test(void (*sender_fun)(void), void (*receiver_fun)(void));
|
||||
|
||||
void test_ubjson_empty_array(void);
|
||||
void test_ubjson_empty_object(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TESTS_UBJSON_H */
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user