Пример #1
0
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;
}
Пример #2
0
static const char *
instid_xml2json(struct ly_ctx *ctx, struct lyxml_elem *xml)
{
    const char *in = xml->content;
    char *out, *aux, *prefix;
    size_t out_size, len, size, i = 0, o = 0;
    int start = 1, interior = 1;
    struct lys_module *mod, *mod_prev = NULL;
    struct lyxml_ns *ns;

    out_size = strlen(in);
    out = malloc((out_size + 1) * sizeof *out);

    while (in[i]) {

        /* skip whitespaces */
        while (isspace(in[i])) {
            i++;
        }

        if (start) {
            /* leading '/' character */
            if (start == 1 && in[i] != '/') {
                LOGVAL(LYE_INCHAR, LOGLINE(xml), in[i], &in[i]);
                free(out);
                return NULL;
            }

            /* check the output buffer size */
            if (out_size == o) {
                out_size += 16; /* just add some size */
                aux = realloc(out, out_size + 1);
                if (!aux) {
                    free(out);
                    LOGMEM;
                    return NULL;
                }
                out = aux;
            }

            out[o++] = in[i++];
            start = 0;
            continue;
        } else {
            /* translate the node identifier */
            /* prefix */
            aux = strchr(&in[i], ':');
            if (aux) {
                /* interior segment */
                len = aux - &in[i];
                prefix = strndup(&in[i], len);
                i += len + 1; /* move after ':' */
            } else {
                /* missing prefix -> invalid instance-identifier */
                LOGVAL(LYE_INVAL, LOGLINE(xml), xml->content, xml->name);
                free(out);
                return NULL;
            }
            ns = lyxml_get_ns(xml, prefix);
            free(prefix);
            mod = ly_ctx_get_module_by_ns(ctx, ns->value, NULL);

            /* node name */
            aux = strpbrk(&in[i], "/[=");
            if (aux) {
                /* interior segment */
                len = aux - &in[i];
            } else {
                /* end segment */
                interior = 0;
                len = strlen(&in[i]);
            }

            /* check the output buffer size */
            if (!mod_prev || (mod != mod_prev)) {
                /* prefix + ':' + name to print + '/' */
                size = o + len + 1 + strlen(mod->name) + interior;
            } else {
                /* name to print + '/' */
                size = o + len + interior;
            }
            if (out_size <= size) {
                /* extend to fit the needed size */
                out_size = size;
                aux = realloc(out, out_size + 1);
                if (!aux) {
                    free(out);
                    LOGMEM;
                    return NULL;
                }
                out = aux;
            }

            if (!mod_prev || (mod != mod_prev)) {
                mod_prev = mod;
                size = strlen(mod->name);
                memcpy(&out[o], mod->name, size);
                o += size;
                out[o++] = ':';
            }
            memcpy(&out[o], &in[i], len);
            o += len;
            i += len;

            if (in[i] == '=') {
                /* we are in the predicate on the value, so just copy data */
                aux = strchr(&in[i], ']');
                if (aux) {
                    len = aux - &in[i] + 1; /* include ] */

                    /* check the output buffer size */
                    size = o + len + 1;
                    if (out_size <= size) {
                        out_size = size; /* just add some size */
                        aux = realloc(out, out_size + 1);
                        if (!aux) {
                            free(out);
                            LOGMEM;
                            return NULL;
                        }
                        out = aux;
                    }

                    memcpy(&out[o], &in[i], len);
                    o += len;
                    i += len;
                } else {
                    /* missing closing ] of predicate -> invalid instance-identifier */
                    LOGVAL(LYE_INVAL, LOGLINE(xml), xml->content, xml->name);
                    free(out);
                    return NULL;
                }
            }
            start = 2;
        }
    }

    /* terminating NULL byte */
    /* check the output buffer size */
    if (out_size < o) {
        out_size += 1; /* just add some size */
        aux = realloc(out, out_size + 1);
        if (!aux) {
            free(out);
            LOGMEM;
            return NULL;
        }
        out = aux;
    }
    out[o] = '\0';

    return lydict_insert_zc(ctx, out);
}