29#include "plugins_internal.h"
43static const char b64_etable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
58binary_base64_encode(
const struct ly_ctx *ctx,
const char *data,
size_t size,
char **str,
size_t *str_len)
63 *str_len = (size + 2) / 3 * 4;
64 *str = malloc(*str_len + 1);
72 for (i = 0; i + 2 < size; i += 3) {
73 *ptr++ = b64_etable[(data[i] >> 2) & 0x3F];
74 *ptr++ = b64_etable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
75 *ptr++ = b64_etable[((data[i + 1] & 0xF) << 2) | ((int)(data[i + 2] & 0xC0) >> 6)];
76 *ptr++ = b64_etable[data[i + 2] & 0x3F];
79 *ptr++ = b64_etable[(data[i] >> 2) & 0x3F];
80 if (i == (size - 1)) {
81 *ptr++ = b64_etable[((data[i] & 0x3) << 4)];
84 *ptr++ = b64_etable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
85 *ptr++ = b64_etable[((data[i + 1] & 0xF) << 2)];
97static const int b64_dtable[256] = {
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55,
101 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
102 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0,
103 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
104 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
119binary_base64_decode(
const char *value,
size_t value_len,
void **data,
size_t *size)
121 unsigned char *ptr = (
unsigned char *)value;
122 uint32_t pad_chars, octet_count;
125 if (!value_len || (ptr[value_len - 1] !=
'=')) {
127 }
else if (ptr[value_len - 2] ==
'=') {
133 octet_count = ((value_len + 3) / 4 - (pad_chars ? 1 : 0)) * 4;
134 *size = octet_count / 4 * 3 + pad_chars;
136 str = malloc(*size + 1);
140 for (uint32_t i = 0, j = 0; i < octet_count; i += 4) {
141 int n = b64_dtable[ptr[i]] << 18 | b64_dtable[ptr[i + 1]] << 12 | b64_dtable[ptr[i + 2]] << 6 | b64_dtable[ptr[i + 3]];
144 str[j++] = n >> 8 & 0xFF;
148 int n = b64_dtable[ptr[octet_count]] << 18 | b64_dtable[ptr[octet_count + 1]] << 12;
150 str[*size - pad_chars] = n >> 16;
152 if (pad_chars == 2) {
153 n |= b64_dtable[ptr[octet_count + 2]] << 6;
155 str[*size - pad_chars + 1] = n;
172binary_base64_validate(
const char *value,
size_t value_len,
struct ly_err_item **err)
178 while ((idx < value_len) &&
179 (((
'A' <= value[idx]) && (value[idx] <=
'Z')) ||
180 ((
'a' <= value[idx]) && (value[idx] <=
'z')) ||
181 ((
'0' <= value[idx]) && (value[idx] <=
'9')) ||
182 (
'+' == value[idx]) || (
'/' == value[idx]))) {
188 while ((idx + pad < value_len) && (pad < 2) && (value[idx + pad] ==
'=')) {
193 if (value_len != idx + pad) {
194 if (isprint(value[idx + pad])) {
219binary_base64_newlines(
char **value,
size_t *value_len, uint32_t *options,
struct ly_err_item **err)
224 if ((*value_len < 65) || ((*value)[64] !=
'\n')) {
231 *value = strndup(*value, *value_len);
232 LY_CHECK_RET(!*value,
LY_EMEM);
239 if (val[64] !=
'\n') {
245 memmove(val + 64, val + 65, len - 64);
256 uint32_t options,
LY_VALUE_FORMAT format,
void *UNUSED(prefix_data), uint32_t hints,
257 const struct lysc_node *UNUSED(ctx_node),
struct lyd_value *storage,
struct lys_glob_unres *UNUSED(unres),
265 memset(storage, 0,
sizeof *storage);
267 LY_CHECK_ERR_GOTO(!val, ret =
LY_EMEM, cleanup);
273 val->
data = (
void *)value;
274 options &= ~LYPLG_TYPE_STORE_DYNAMIC;
275 }
else if (value_len) {
276 val->
data = malloc(value_len);
277 LY_CHECK_ERR_GOTO(!val->
data, ret =
LY_EMEM, cleanup);
278 memcpy(val->
data, value, value_len);
280 val->
data = strdup(
"");
281 LY_CHECK_ERR_GOTO(!val->
data, ret =
LY_EMEM, cleanup);
285 val->
size = value_len;
293 LY_CHECK_GOTO(ret, cleanup);
297 ret = binary_base64_newlines((
char **)&value, &value_len, &options, err);
298 LY_CHECK_GOTO(ret, cleanup);
301 ret = binary_base64_validate(value, value_len, err);
302 LY_CHECK_GOTO(ret, cleanup);
306 ret = binary_base64_decode(value, value_len, &val->
data, &val->
size);
307 LY_CHECK_GOTO(ret, cleanup);
312 options &= ~LYPLG_TYPE_STORE_DYNAMIC;
313 LY_CHECK_GOTO(ret, cleanup);
319 LY_CHECK_GOTO(ret, cleanup);
326 LY_CHECK_GOTO(ret, cleanup);
375LIBYANG_API_DEF
const void *
377 void *UNUSED(prefix_data),
ly_bool *dynamic,
size_t *value_len)
388 *value_len = val->
size;
396 if (binary_base64_encode(ctx, val->
data, val->
size, &ret, &ret_len)) {
412 *value_len = ret_len ? ret_len : strlen(value->
_canonical);
423 memset(dup, 0,
sizeof *dup);
426 LY_CHECK_GOTO(ret, error);
429 LY_CHECK_ERR_GOTO(!dup_val, ret =
LY_EMEM, error);
433 dup_val->
data = orig_val->
size ? malloc(orig_val->
size) : strdup(
"");
434 LY_CHECK_ERR_GOTO(!dup_val->
data, ret =
LY_EMEM, error);
472 .name = LY_TYPE_BINARY_STR,
474 .plugin.id =
"libyang 2 - binary, version 1",
476 .plugin.validate = NULL,
482 .plugin.lyb_data_len = -1,
const struct lyplg_type_record plugins_binary[]
Plugin information for binray type implementation.
LIBYANG_API_DEF LY_ERR lyplg_type_store_binary(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, size_t value_len, uint32_t options, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), uint32_t hints, const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
LIBYANG_API_DEF int lyplg_type_sort_binary(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
LIBYANG_API_DEF const void * lyplg_type_print_binary(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format, void *UNUSED(prefix_data), ly_bool *dynamic, size_t *value_len)
LIBYANG_API_DEF LY_ERR lyplg_type_compare_binary(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
LIBYANG_API_DECL LY_ERR lydict_insert(const struct ly_ctx *ctx, const char *value, size_t len, const char **str_p)
Insert string into dictionary. If the string is already present, only a reference counter is incremen...
LIBYANG_API_DECL LY_ERR lydict_remove(const struct ly_ctx *ctx, const char *value)
Remove specified string from the dictionary. It decrement reference counter for the string and if it ...
LIBYANG_API_DECL LY_ERR lydict_insert_zc(const struct ly_ctx *ctx, char *value, const char **str_p)
Insert string into dictionary - zerocopy version. If the string is already present,...
LY_ERR
libyang's error codes returned by the libyang functions.
Libyang full error structure.
LIBYANG_API_DEF void lyplg_type_free_binary(const struct ly_ctx *ctx, struct lyd_value *value)
Implementation of lyplg_type_free_clb for the built-in binary type.
LIBYANG_API_DEF LY_ERR lyplg_type_dup_binary(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
Implementation of lyplg_type_dup_clb for the built-in binary type.
const char *const char * revision
#define LYPLG_TYPE_VAL_INLINE_PREPARE(storage, type_val)
Prepare value memory for storing a specific type value, may be allocated dynamically.
#define LYPLG_TYPE_VAL_INLINE_DESTROY(type_val)
Destroy a prepared value.
LIBYANG_API_DECL LY_ERR lyplg_type_validate_range(LY_DATA_TYPE basetype, struct lysc_range *range, int64_t value, const char *strval, size_t strval_len, struct ly_err_item **err)
Data type validator for a range/length-restricted values.
LIBYANG_API_DECL LY_ERR lyplg_type_check_hints(uint32_t hints, const char *value, size_t value_len, LY_DATA_TYPE type, int *base, struct ly_err_item **err)
Check that the type is suitable for the parser's hints (if any) in the specified format.
LIBYANG_API_DECL LY_ERR ly_err_new(struct ly_err_item **err, LY_ERR ecode, LY_VECODE vecode, char *data_path, char *apptag, const char *err_format,...) _FORMAT_PRINTF(6
Create and fill error structure.
#define LYPLG_TYPE_STORE_DYNAMIC
#define LYPLG_TYPE_STORE_ONLY
struct lysc_range * length
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
The main libyang public header.
uint8_t ly_bool
Type to indicate boolean value.
API for (user) types plugins.
const struct lysc_type * realtype
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
YANG data representation.
Special lyd_value structure for built-in binary values.