int ly_write_skip(struct lyout *out, size_t count, size_t *position) { switch (out->type) { case LYOUT_MEMORY: if (out->method.mem.len + count > out->method.mem.size) { out->method.mem.buf = ly_realloc(out->method.mem.buf, out->method.mem.len + count); if (!out->method.mem.buf) { out->method.mem.len = 0; out->method.mem.size = 0; LOGMEM(NULL); return -1; } out->method.mem.size = out->method.mem.len + count; } /* save the current position */ *position = out->method.mem.len; /* skip the memory */ out->method.mem.len += count; break; case LYOUT_FD: case LYOUT_STREAM: case LYOUT_CALLBACK: /* buffer the hole */ if (out->buf_len + count > out->buf_size) { out->buffered = ly_realloc(out->buffered, out->buf_len + count); if (!out->buffered) { out->buf_len = 0; out->buf_size = 0; LOGMEM(NULL); return -1; } out->buf_size = out->buf_len + count; } /* save the current position */ *position = out->buf_len; /* skip the memory */ out->buf_len += count; /* increase hole counter */ ++out->hole_count; } return count; }
int ly_write(struct lyout *out, const char *buf, size_t count) { if (out->hole_count) { /* we are buffering data after a hole */ if (out->buf_len + count > out->buf_size) { out->buffered = ly_realloc(out->buffered, out->buf_len + count); if (!out->buffered) { out->buf_len = 0; out->buf_size = 0; LOGMEM(NULL); return -1; } out->buf_size = out->buf_len + count; } memcpy(&out->buffered[out->buf_len], buf, count); out->buf_len += count; return count; } switch (out->type) { case LYOUT_MEMORY: if (out->method.mem.len + count + 1 > out->method.mem.size) { out->method.mem.buf = ly_realloc(out->method.mem.buf, out->method.mem.len + count + 1); if (!out->method.mem.buf) { out->method.mem.len = 0; out->method.mem.size = 0; LOGMEM(NULL); return -1; } out->method.mem.size = out->method.mem.len + count + 1; } memcpy(&out->method.mem.buf[out->method.mem.len], buf, count); out->method.mem.len += count; out->method.mem.buf[out->method.mem.len] = '\0'; return count; case LYOUT_FD: return write(out->method.fd, buf, count); case LYOUT_STREAM: return fwrite(buf, sizeof *buf, count, out->method.f); case LYOUT_CALLBACK: return out->method.clb.f(out->method.clb.arg, buf, count); } return 0; }
int ly_print(struct lyout *out, const char *format, ...) { int count = 0; char *msg = NULL, *aux; va_list ap; #ifndef HAVE_VDPRINTF FILE *stream; #endif va_start(ap, format); switch (out->type) { case LYOUT_FD: #ifdef HAVE_VDPRINTF count = vdprintf(out->method.fd, format, ap); #else stream = fdopen(dup(out->method.fd), "a+"); if (stream) { count = vfprintf(stream, format, ap); fclose(stream); } #endif break; case LYOUT_STREAM: count = vfprintf(out->method.f, format, ap); break; case LYOUT_MEMORY: count = vasprintf(&msg, format, ap); if (out->method.mem.len + count + 1 > out->method.mem.size) { aux = ly_realloc(out->method.mem.buf, out->method.mem.len + count + 1); if (!aux) { out->method.mem.buf = NULL; out->method.mem.len = 0; out->method.mem.size = 0; LOGMEM(NULL); va_end(ap); return -1; } out->method.mem.buf = aux; out->method.mem.size = out->method.mem.len + count + 1; } memcpy(&out->method.mem.buf[out->method.mem.len], msg, count); out->method.mem.len += count; out->method.mem.buf[out->method.mem.len] = '\0'; free(msg); break; case LYOUT_CALLBACK: count = vasprintf(&msg, format, ap); count = out->method.clb.f(out->method.clb.arg, msg, count); free(msg); break; } va_end(ap); return count; }
static int lyb_read_start_subtree(const char *data, struct lyb_state *lybs) { uint8_t meta_buf[LYB_META_BYTES]; if (lybs->used == lybs->size) { lybs->size += LYB_STATE_STEP; lybs->written = ly_realloc(lybs->written, lybs->size * sizeof *lybs->written); lybs->position = ly_realloc(lybs->position, lybs->size * sizeof *lybs->position); lybs->inner_chunks = ly_realloc(lybs->inner_chunks, lybs->size * sizeof *lybs->inner_chunks); LY_CHECK_ERR_RETURN(!lybs->written || !lybs->position || !lybs->inner_chunks, LOGMEM(NULL), -1); } memcpy(meta_buf, data, LYB_META_BYTES); ++lybs->used; lybs->written[lybs->used - 1] = meta_buf[0]; lybs->inner_chunks[lybs->used - 1] = meta_buf[LYB_SIZE_BYTES]; lybs->position[lybs->used - 1] = (lybs->written[lybs->used - 1] == LYB_SIZE_MAX ? 1 : 0); return LYB_META_BYTES; }
static int lyb_read_string(const char *data, char **str, int with_length, struct lyb_state *lybs) { int next_chunk = 0, r, ret = 0; size_t len = 0, cur_len; uint8_t len_buf[2]; if (with_length) { ret += (r = lyb_read(data, len_buf, 2, lybs)); LYB_HAVE_READ_GOTO(r, data, error); len = len_buf[0] | (len_buf[1] << 8); } else { /* read until the end of this subtree */ len = lybs->written[lybs->used - 1]; if (lybs->position[lybs->used - 1]) { next_chunk = 1; } } *str = malloc((len + 1) * sizeof **str); LY_CHECK_ERR_RETURN(!*str, LOGMEM(NULL), -1); ret += (r = lyb_read(data, (uint8_t *)*str, len, lybs)); LYB_HAVE_READ_GOTO(r, data, error); while (next_chunk) { cur_len = lybs->written[lybs->used - 1]; if (lybs->position[lybs->used - 1]) { next_chunk = 1; } else { next_chunk = 0; } *str = ly_realloc(*str, (len + cur_len + 1) * sizeof **str); LY_CHECK_ERR_RETURN(!*str, LOGMEM(NULL), -1); ret += (r = lyb_read(data, ((uint8_t *)*str) + len, cur_len, lybs)); LYB_HAVE_READ_GOTO(r, data, error); len += cur_len; } ((char *)*str)[len] = '\0'; return ret; error: free((char *)*str); *str = NULL; return -1; }
const char * transform_schema2json(const struct lys_module *module, const char *expr) { const char *in, *id; char *out, *col; size_t out_size, out_used, id_len, rc; const struct lys_module *mod; in = expr; out_size = strlen(in)+1; out = malloc(out_size); if (!out) { LOGMEM; return NULL; } out_used = 0; while (1) { col = strchr(in, ':'); /* we're finished, copy the remaining part */ if (!col) { strcpy(&out[out_used], in); out_used += strlen(in)+1; assert(out_size == out_used); return lydict_insert_zc(module->ctx, out); } id = strpbrk_backwards(col-1, "/ [\'\"", (col-in)-1); if ((id[0] == '/') || (id[0] == ' ') || (id[0] == '[') || (id[0] == '\'') || (id[0] == '\"')) { ++id; } id_len = col-id; rc = parse_identifier(id); if (rc < id_len) { LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, id[rc], &id[rc]); free(out); return NULL; } /* get the module */ mod = lys_get_import_module(module, id, id_len, NULL, 0); if (!mod) { LOGVAL(LYE_INMOD_LEN, LY_VLOG_NONE, NULL, id_len, id); free(out); return NULL; } /* adjust out size (it can even decrease in some strange cases) */ out_size += strlen(mod->name)-id_len; out = ly_realloc(out, out_size); if (!out) { LOGMEM; return NULL; } /* copy the data before prefix */ strncpy(&out[out_used], in, id-in); out_used += id-in; /* copy the model name */ strcpy(&out[out_used], mod->name); out_used += strlen(mod->name); /* copy ':' */ out[out_used] = ':'; ++out_used; /* finally adjust in pointer for next round */ in = col+1; } /* unreachable */ LOGINT; return NULL; }
const char * transform_xml2json(struct ly_ctx *ctx, const char *expr, struct lyxml_elem *xml, int log) { const char *in, *id; char *out, *col, *prefix; size_t out_size, out_used, id_len, rc; const struct lys_module *mod; const struct lyxml_ns *ns; in = expr; out_size = strlen(in)+1; out = malloc(out_size); if (!out) { if (log) { LOGMEM; } return NULL; } out_used = 0; while (1) { col = strchr(in, ':'); /* we're finished, copy the remaining part */ if (!col) { strcpy(&out[out_used], in); out_used += strlen(in)+1; assert(out_size == out_used); return lydict_insert_zc(ctx, out); } id = strpbrk_backwards(col-1, "/ [\'\"", (col-in)-1); if ((id[0] == '/') || (id[0] == ' ') || (id[0] == '[') || (id[0] == '\'') || (id[0] == '\"')) { ++id; } id_len = col-id; rc = parse_identifier(id); if (rc < id_len) { if (log) { LOGVAL(LYE_XML_INCHAR, LY_VLOG_XML, xml, id[rc], &id[rc]); } free(out); return NULL; } /* get the module */ prefix = strndup(id, id_len); if (!prefix) { if (log) { LOGMEM; } free(out); return NULL; } ns = lyxml_get_ns(xml, prefix); free(prefix); if (!ns) { if (log) { LOGVAL(LYE_XML_INVAL, LY_VLOG_XML, xml, "namespace prexif"); LOGVAL(LYE_SPEC, LY_VLOG_XML, xml, "XML namespace with prefix \"%.*s\" not defined.", id_len, id); } free(out); return NULL; } mod = ly_ctx_get_module_by_ns(ctx, ns->value, NULL); if (!mod) { if (log) { LOGVAL(LYE_XML_INVAL, LY_VLOG_XML, xml, "module namespace"); LOGVAL(LYE_SPEC, LY_VLOG_XML, xml, "Module with the namespace \"%s\" could not be found.", ns->value); } free(out); return NULL; } /* adjust out size (it can even decrease in some strange cases) */ out_size += strlen(mod->name)-id_len; out = ly_realloc(out, out_size); if (!out) { if (log) { LOGMEM; } return NULL; } /* copy the data before prefix */ strncpy(&out[out_used], in, id-in); out_used += id-in; /* copy the model name */ strcpy(&out[out_used], mod->name); out_used += strlen(mod->name); /* copy ':' */ out[out_used] = ':'; ++out_used; /* finally adjust in pointer for next round */ in = col+1; } /* unreachable */ LOGINT; return NULL; }
static const char * _transform_json2xml(const struct lys_module *module, const char *expr, int schema, const char ***prefixes, const char ***namespaces, uint32_t *ns_count) { const char *in, *id, *prefix; char *out, *col, *name; size_t out_size, out_used, id_len; const struct lys_module *mod; uint32_t i; assert(module && expr && ((!prefixes && !namespaces && !ns_count) || (prefixes && namespaces && ns_count))); if (ns_count) { *ns_count = 0; *prefixes = NULL; *namespaces = NULL; } in = expr; out_size = strlen(in) + 1; out = malloc(out_size); if (!out) { LOGMEM; return NULL; } out_used = 0; while (1) { col = strchr(in, ':'); /* we're finished, copy the remaining part */ if (!col) { strcpy(&out[out_used], in); out_used += strlen(in) + 1; assert(out_size == out_used); return lydict_insert_zc(module->ctx, out); } id = strpbrk_backwards(col - 1, "/ [\'\"", (col - in) - 1); if ((id[0] == '/') || (id[0] == ' ') || (id[0] == '[') || (id[0] == '\'') || (id[0] == '\"')) { ++id; } id_len = col - id; /* get the module */ if (!schema) { name = strndup(id, id_len); mod = ly_ctx_get_module(module->ctx, name, NULL); free(name); if (!mod) { LOGVAL(LYE_INMOD_LEN, LY_VLOG_NONE, NULL, id_len, id); goto fail; } prefix = mod->prefix; } else { name = strndup(id, id_len); prefix = transform_module_name2import_prefix(module, name); free(name); if (!prefix) { LOGVAL(LYE_INMOD_LEN, LY_VLOG_NONE, NULL, id_len, id); goto fail; } } /* remember the namespace definition (only if it's new) */ if (!schema && ns_count) { for (i = 0; i < *ns_count; ++i) { if (ly_strequal((*namespaces)[i], mod->ns, 1)) { break; } } if (i == *ns_count) { ++(*ns_count); *prefixes = ly_realloc(*prefixes, *ns_count * sizeof **prefixes); if (!(*prefixes)) { LOGMEM; goto fail; } *namespaces = ly_realloc(*namespaces, *ns_count * sizeof **namespaces); if (!(*namespaces)) { LOGMEM; goto fail; } (*prefixes)[*ns_count - 1] = mod->prefix; (*namespaces)[*ns_count - 1] = mod->ns; } } /* adjust out size */ out_size += strlen(prefix) - id_len; out = ly_realloc(out, out_size); if (!out) { LOGMEM; goto fail; } /* copy the data before prefix */ strncpy(&out[out_used], in, id-in); out_used += id - in; /* copy the model prefix */ strcpy(&out[out_used], prefix); out_used += strlen(prefix); /* copy ':' */ out[out_used] = ':'; ++out_used; /* finally adjust in pointer for next round */ in = col + 1; } /* unreachable */ LOGINT; fail: if (!schema && ns_count) { free(*prefixes); free(*namespaces); } free(out); return NULL; }