27 #include "plugins_internal.h"
41 static const char b64_etable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
56 binary_base64_encode(
const struct ly_ctx *ctx,
const char *data,
size_t size,
char **str,
size_t *str_len)
61 *str_len = (size + 2) / 3 * 4;
62 *str = malloc(*str_len + 1);
66 for (i = 0; i < size - 2; i += 3) {
67 *ptr++ = b64_etable[(data[i] >> 2) & 0x3F];
68 *ptr++ = b64_etable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
69 *ptr++ = b64_etable[((data[i + 1] & 0xF) << 2) | ((int)(data[i + 2] & 0xC0) >> 6)];
70 *ptr++ = b64_etable[data[i + 2] & 0x3F];
73 *ptr++ = b64_etable[(data[i] >> 2) & 0x3F];
74 if (i == (size - 1)) {
75 *ptr++ = b64_etable[((data[i] & 0x3) << 4)];
78 *ptr++ = b64_etable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
79 *ptr++ = b64_etable[((data[i + 1] & 0xF) << 2)];
91 static const int b64_dtable[256] = {
92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55,
95 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
96 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0,
97 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
98 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
113 binary_base64_decode(
const char *value,
size_t value_len,
void **data,
size_t *size)
115 unsigned char *ptr = (
unsigned char *)value;
116 uint32_t pad_chars, octet_count;
119 if (!value_len || (ptr[value_len - 1] !=
'=')) {
121 }
else if (ptr[value_len - 2] ==
'=') {
127 octet_count = ((value_len + 3) / 4 - (pad_chars ? 1 : 0)) * 4;
128 *size = octet_count / 4 * 3 + pad_chars;
130 str = malloc(*size + 1);
134 for (uint32_t i = 0, j = 0; i < octet_count; i += 4) {
135 int n = b64_dtable[ptr[i]] << 18 | b64_dtable[ptr[i + 1]] << 12 | b64_dtable[ptr[i + 2]] << 6 | b64_dtable[ptr[i + 3]];
137 str[j++] = n >> 8 & 0xFF;
141 int n = b64_dtable[ptr[octet_count]] << 18 | b64_dtable[ptr[octet_count + 1]] << 12;
142 str[*size - pad_chars] = n >> 16;
144 if (pad_chars == 2) {
145 n |= b64_dtable[ptr[octet_count + 2]] << 6;
147 str[*size - pad_chars + 1] = n;
165 binary_base64_validate(
const char *value,
size_t value_len,
const struct lysc_type_bin *type,
struct ly_err_item **err)
171 while ((idx < value_len) &&
172 (((
'A' <= value[idx]) && (value[idx] <=
'Z')) ||
173 ((
'a' <= value[idx]) && (value[idx] <=
'z')) ||
174 ((
'0' <= value[idx]) && (value[idx] <=
'9')) ||
175 (
'+' == value[idx]) || (
'/' == value[idx]))) {
181 while ((idx + pad < value_len) && (pad < 2) && (value[idx + pad] ==
'=')) {
186 if (value_len != idx + pad) {
187 if (isprint(value[idx + pad])) {
201 const uint32_t octet_count = ((idx + pad) / 4) * 3 - pad;
210 uint32_t options,
LY_VALUE_FORMAT format,
void *UNUSED(prefix_data), uint32_t hints,
211 const struct lysc_node *UNUSED(ctx_node),
struct lyd_value *storage,
struct lys_glob_unres *UNUSED(unres),
219 memset(storage, 0,
sizeof *storage);
221 LY_CHECK_ERR_GOTO(!val, ret =
LY_EMEM, cleanup);
227 val->
data = (
void *)value;
230 val->
data = malloc(value_len);
231 LY_CHECK_ERR_GOTO(!val->
data, ret =
LY_EMEM, cleanup);
232 memcpy(val->
data, value, value_len);
236 val->
size = value_len;
244 LY_CHECK_GOTO(ret, cleanup);
248 ret = binary_base64_validate(value, value_len, type_bin, err);
249 LY_CHECK_GOTO(ret, cleanup);
253 ret = binary_base64_decode(value, value_len, &val->
data, &val->
size);
254 LY_CHECK_GOTO(ret, cleanup);
260 LY_CHECK_GOTO(ret, cleanup);
263 LY_CHECK_GOTO(ret, cleanup);
297 void *UNUSED(prefix_data),
ly_bool *dynamic,
size_t *value_len)
308 *value_len = val->
size;
316 if (binary_base64_encode(ctx, val->
data, val->
size, &ret, &ret_len)) {
332 *value_len = ret_len ? ret_len : strlen(value->
_canonical);
353 dup_val->
data = malloc(orig_val->
size);
354 if (!dup_val->
data) {
390 .name = LY_TYPE_BINARY_STR,
392 .plugin.id =
"libyang 2 - binary, version 1",
394 .plugin.validate = NULL,
const struct lyplg_type_record plugins_binary[]
Plugin information for binray type implementation.
API 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)
API 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)
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 ...
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 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...
LY_ERR
libyang's error codes returned by the libyang functions.
Libyang full error structure.
API 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.
API LY_ERR lyplg_type_compare_binary(const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_compare_clb for the built-in binary type.
API 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.
#define LYPLG_TYPE_VAL_INLINE_PREPARE(storage, type_val)
Prepare value memory for storing a specific type value, may be allocated dynamically.
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.
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.
#define LYPLG_TYPE_VAL_INLINE_DESTROY(type_val)
Destroy a prepared value.
LY_ERR ly_err_new(struct ly_err_item **err, LY_ERR ecode, LY_VECODE vecode, char *path, char *apptag, const char *err_msg,...)
Create and fill error structure.
#define LYPLG_TYPE_STORE_DYNAMIC
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.