Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CYAML_BINARY type #237

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ endif
BUILDDIR_SHARED = $(BUILDDIR)/shared
BUILDDIR_STATIC = $(BUILDDIR)/static

LIB_SRC_FILES = mem.c free.c load.c save.c copy.c util.c utf8.c
LIB_SRC_FILES = base64.c mem.c free.c load.c save.c copy.c util.c utf8.c
LIB_SRC := $(addprefix src/,$(LIB_SRC_FILES))
LIB_OBJ = $(patsubst %.c,%.o, $(addprefix $(BUILDDIR)/,$(LIB_SRC)))
LIB_DEP = $(patsubst %.c,%.d, $(addprefix $(BUILDDIR)/,$(LIB_SRC)))
Expand All @@ -117,7 +117,7 @@ endif

TEST_SRC_FILES = units/free.c units/load.c units/test.c units/util.c \
units/errs.c units/file.c units/save.c units/copy.c \
units/utf8.c
units/utf8.c units/base64.c
TEST_SRC := $(addprefix test/,$(TEST_SRC_FILES))
TEST_OBJ = $(patsubst %.c,%.o, $(addprefix $(BUILDDIR)/,$(TEST_SRC)))
TEST_DEP = $(patsubst %.c,%.d, $(addprefix $(BUILDDIR)/,$(TEST_SRC)))
Expand Down
156 changes: 156 additions & 0 deletions include/cyaml/cyaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ typedef enum cyaml_type {
CYAML_FLAGS,
CYAML_FLOAT, /**< Value is floating point. */
CYAML_STRING, /**< Value is a string. */
/**
* Value is binary data, encoded in the YAML as a Base64 string.
*
* Values of this type must be the direct children of a mapping.
* They require:
*
* - Offset to the array entry count member in the mapping structure.
* - Size in bytes of the count member in the mapping structure.
* - The minimum and maximum number allowed size.
* Use \ref CYAML_UNLIMITED to have no maximum limit.
*/
CYAML_BINARY,
/**
* Value is a mapping. Values of this type require mapping schema
* array in the schema entry.
Expand Down Expand Up @@ -424,6 +436,25 @@ typedef bool (*cyaml_validate_string_fn_t)(
const cyaml_schema_value_t *schema,
const char *value);

/**
* Value validation callback function for \ref CYAML_BINARY.
*
* Clients may provide this for values of type \ref CYAML_BINARY.
* When called, return `false` to reject the value as invalid or `true` to
* accept it as valid.
*
* \param[in] ctx Client's private validation context.
* \param[in] schema The schema for the value.
* \param[in] value The binary data value to be validated.
* \param[in] len The length of the binary data.
* \return `true` if values is valid, `false` otherwise.
*/
typedef bool (*cyaml_validate_binary_fn_t)(
void *ctx,
const cyaml_schema_value_t *schema,
const uint8_t *value,
size_t len);

/**
* Value validation callback function for \ref CYAML_MAPPING.
*
Expand Down Expand Up @@ -635,6 +666,44 @@ typedef struct cyaml_schema_value {
*/
const char *missing;
} string;
/** \ref CYAML_BINARY type-specific schema data. */
struct {
/**
* Minimum string length (bytes).
*
* \note Excludes trailing NUL.
*/
uint32_t min;
/**
* Maximum string length (bytes).
*
* \note Excludes trailing NULL, so for character array
* strings (rather than pointer strings), this
* must be no more than `data_size - 1`.
*/
uint32_t max;
/**
* Optional client value validation callback.
*
* May be NULL.
*/
cyaml_validate_binary_fn_t validation_cb;
/**
* Value to use for missing YAML field.
*
* This is only used when the value is used for a
* mapping field with the \ref CYAML_FLAG_OPTIONAL flag
* set.
*
* \note This is may be NULL, if no default sequence is
* wanted for a missing field in the YAML.
*/
const void *missing;
/**
* Number of entries in missing array.
*/
size_t missing_len;
} binary;
/** \ref CYAML_MAPPING type-specific schema data. */
struct {
/**
Expand Down Expand Up @@ -893,6 +962,9 @@ typedef enum cyaml_err {
CYAML_ERR_INVALID_VALUE, /**< Value rejected by schema. */
CYAML_ERR_INVALID_ALIAS, /**< No anchor found for alias. */
CYAML_ERR_INTERNAL_ERROR, /**< Internal error in LibCYAML. */
CYAML_ERR_INVALID_BASE64, /**< Invalid Base64 string. */
CYAML_ERR_BASE64_MAX_LEN, /**< Too much base64 data. */
CYAML_ERR_MAPPING_REQUIRED, /**< Value requires parent mapping. */
CYAML_ERR_UNEXPECTED_EVENT, /**< YAML event rejected by schema. */
CYAML_ERR_STRING_LENGTH_MIN, /**< String length too short. */
CYAML_ERR_STRING_LENGTH_MAX, /**< String length too long. */
Expand Down Expand Up @@ -1499,6 +1571,90 @@ typedef enum cyaml_err {
} \
)

/**
* Mapping schema helper macro for keys with \ref CYAML_BINARY type.
*
* To use this, there must be a member in {_structure} called "{_member}_len",
* for storing the byte length of the data.
*
* For example, for the following structure:
*
* ```
* struct my_structure {
* uint8_t *my_data;
* size_t my_data_len;
* };
* ```
*
* Pass the following as parameters:
*
* | Parameter | Value |
* | ---------- | --------------------- |
* | _structure | `struct my_structure` |
* | _member | `my_data` |
*
* If you want to call the structure member for storing the sequence entry
* count something else, then use \ref CYAML_FIELD_BINARY_LENGTH instead.
*
* \param[in] _key String defining the YAML mapping key for this value.
* \param[in] _flags Any behavioural flags relevant to this value.
* \param[in] _structure The structure containing the binary value.
* \param[in] _member The member in _structure for this binary value.
* \param[in] _min Minimum binary data length in bytes.
* \param[in] _max Maximum binary data length in bytes.
*/
#define CYAML_FIELD_BINARY( \
_key, _flags, _structure, _member, _min, _max) \
CYAML_FIELD_PTR(BINARY, _key, _flags, _structure, _member, \
{ \
.min = _min, \
.max = _max, \
} \
)

/**
* Mapping schema helper macro for keys with \ref CYAML_BINARY type.
*
* Compared to .\ref CYAML_FIELD_BINARY, this macro takes an extra `_length`
* parameter, allowing the structure member name for storing the byte length
* of the data to be provided explicitly.
*
* For example, for the following structure:
*
* ```
* struct my_structure {
* uint8_t *my_data;
* size_t length;
* };
* ```
*
* Pass the following as parameters:
*
* | Parameter | Value |
* | ---------- | --------------------- |
* | _structure | `struct my_structure` |
* | _member | `my_data` |
* | _length | `length` |
*
* \param[in] _key String defining the YAML mapping key for this value.
* \param[in] _flags Any behavioural flags relevant to this value.
* \param[in] _structure The structure containing the binary value.
* \param[in] _member The member in _structure for this binary value.
* \param[in] _length The member in _structure for this data's byte length.
* \param[in] _min Minimum binary data length in bytes.
* \param[in] _max Maximum binary data length in bytes.
*/
#define CYAML_FIELD_BINARY_LENGTH( \
_key, _flags, _structure, _member, _length, _min, _max) \
CYAML_FIELD_PTR_COUNT(BINARY, \
_key, _flags, _structure, _member, _length, \
{ \
.min = _min, \
.max = _max, \
} \
)


/**
* Mapping schema helper macro for keys with \ref CYAML_MAPPING type.
*
Expand Down
6 changes: 6 additions & 0 deletions include/cyaml/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ extern "C"
#define CYAML__UNION_MEMBER_FLOAT .floating_point
/** Type to \ref cyaml_schema_value union member for STRING. */
#define CYAML__UNION_MEMBER_STRING .string
/** Type to \ref cyaml_schema_value union member for BINARY. */
#define CYAML__UNION_MEMBER_BINARY .binary
/** Type to \ref cyaml_schema_value union member for MAPPING. */
#define CYAML__UNION_MEMBER_MAPPING .mapping
/** Type to \ref cyaml_schema_value union member for BITFIELD. */
Expand All @@ -75,6 +77,8 @@ extern "C"
#define CYAML__SEQUENCE_COUNT_FLOAT(_member, _count) _member
/** Fake a valid sequence count member for STRING. */
#define CYAML__SEQUENCE_COUNT_STRING(_member, _count) _member
/** Fake a valid sequence count member for BINARY. */
#define CYAML__SEQUENCE_COUNT_BINARY(_member, _count) _member ## _len
/** Fake a valid sequence count member for MAPPING. */
#define CYAML__SEQUENCE_COUNT_MAPPING(_member, _count) _member
/** Fake a valid sequence count member for BITFIELD. */
Expand All @@ -98,6 +102,8 @@ extern "C"
#define CYAML__HANDLE_PTR_FLOAT(_flags) CYAML__POINTER_ADD(_flags)
/** Adapt flags for mapping schema building macro for STRING. */
#define CYAML__HANDLE_PTR_STRING(_flags) CYAML__POINTER_ADD(_flags)
/** Adapt flags for mapping schema building macro for BINARY. */
#define CYAML__HANDLE_PTR_BINARY(_flags) _flags
/** Adapt flags for mapping schema building macro for MAPPING. */
#define CYAML__HANDLE_PTR_MAPPING(_flags) CYAML__POINTER_ADD(_flags)
/** Adapt flags for mapping schema building macro for BITFIELD. */
Expand Down
Loading
Loading