⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xdata.c

📁 这是一个完全开放的
💻 C
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney, *                         Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA *//* xdata, whee! */#include "util.h"/** creation */xdata_t xdata_new(xdata_type_t type, char *title, char *instructions) {    pool p;    xdata_t xd;    assert((int) type);    p = pool_new();    xd = pmalloco(p, sizeof(struct _xdata_st));    xd->p = p;    xd->type = type;    if(title != NULL) xd->title = pstrdup(xd->p, title);    if(instructions != NULL) xd->instructions = pstrdup(xd->p, instructions);    log_debug(ZONE, "created new xd; title=%s, instructions=%s", title, instructions);    return xd;}/** new field */xdata_field_t xdata_field_new(xdata_t xd, xdata_field_type_t type, char *var, char *label, char *desc, int required) {    xdata_field_t xdf;    assert((int) xd);    assert((int) type);    assert((int) var);    xdf = pmalloco(xd->p, sizeof(struct _xdata_field_st));    xdf->p = xd->p;    xdf->type = type;    xdf->var = pstrdup(xdf->p, var);    if(label != NULL) xdf->label = pstrdup(xdf->p, label);    if(desc != NULL) xdf->desc = pstrdup(xdf->p, desc);    xdf->required = required;    return xdf;}/** new item */xdata_item_t xdata_item_new(xdata_t xd) {    xdata_item_t xdi;    assert((int) xd);    xdi = pmalloco(xd->p, sizeof(struct _xdata_item_st));    xdi->p = xd->p;    return xdi;}/** field insertion */void xdata_add_field(xdata_t xd, xdata_field_t xdf) {    assert((int) xd);    assert((int) xdf);    if(xd->fields == NULL)        xd->fields = xd->flast = xdf;    else {        xd->flast->next = xdf;        xd->flast = xdf;    }}void xdata_add_rfield(xdata_t xd, xdata_field_t xdf) {    assert((int) xd);    assert((int) xdf);    if(xd->rfields == NULL)        xd->rfields = xd->rflast = xdf;    else {        xd->rflast->next = xdf;        xd->rflast = xdf;    }}void xdata_add_field_item(xdata_item_t xdi, xdata_field_t xdf) {    assert((int) xdi);    assert((int) xdf);    if(xdi->fields == NULL)        xdi->fields = xdi->flast = xdf;    else {        xdi->flast->next = xdf;        xdi->flast = xdf;    }}/** item insertion */void xdata_add_item(xdata_t xd, xdata_item_t xdi) {    assert((int) xd);    assert((int) xdi);    if(xd->items == NULL)        xd->items = xd->ilast = xdi;    else {        xd->ilast->next = xdi;        xd->ilast = xdi;    }}/** option insertion */void xdata_option_new(xdata_field_t xdf, char *value, int lvalue, char *label, int llabel) {    xdata_option_t xdo;    assert((int) xdf);    assert((int) value);    xdo = pmalloco(xdf->p, sizeof(struct _xdata_option_st));    xdo->p = xdf->p;    if(lvalue <= 0) lvalue = strlen(value);    xdo->value = pstrdupx(xdo->p, value, lvalue);    if(label != NULL) {        if(llabel <= 0) llabel = strlen(label);        xdo->label = pstrdupx(xdo->p, label, llabel);    }    xdf->olast->next = xdo;    xdf->olast = xdo;    if(xdf->options == NULL) xdf->options = xdo;}/** value insertion */void xdata_add_value(xdata_field_t xdf, char *value, int vlen) {    int first = 0;    assert((int) xdf);    assert((int) value);    if(vlen <= 0) vlen = strlen(value);    if(xdf->values == NULL)        first = 1;    xdf->values = (char **) realloc(xdf->values, sizeof(char *) * (xdf->nvalues + 1));    xdf->values[xdf->nvalues] = pstrdupx(xdf->p, value, vlen);    xdf->nvalues++;    if(first)        pool_cleanup(xdf->p, free, xdf->values);}/** rip out a field */static xdata_field_t _xdata_field_parse(xdata_t xd, nad_t nad, int root) {    xdata_field_t xdf;    int attr, elem, eval;    xdf = pmalloco(xd->p, sizeof(struct _xdata_field_st));    xdf->p = xd->p;    attr = nad_find_attr(nad, root, -1, "var", NULL);    if(attr >= 0)        xdf->var = pstrdupx(xdf->p, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));    attr = nad_find_attr(nad, root, -1, "label", NULL);    if(attr >= 0)        xdf->label = pstrdupx(xdf->p, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));    attr = nad_find_attr(nad, root, -1, "desc", NULL);    if(attr >= 0)        xdf->desc = pstrdupx(xdf->p, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));    if(nad_find_elem(nad, root, NAD_ENS(nad, root), "required", 1) >= 0)        xdf->required = 1;    attr = nad_find_attr(nad, root, -1, "type", NULL);    if(attr >= 0) {        if(NAD_AVAL_L(nad, attr) == 7 && strncmp("boolean", NAD_AVAL(nad, attr), 7) == 0)            xdf->type = xd_field_BOOLEAN;        else if(NAD_AVAL_L(nad, attr) == 5 && strncmp("fixed", NAD_AVAL(nad, attr), 5) == 0)            xdf->type = xd_field_FIXED;        else if(NAD_AVAL_L(nad, attr) == 6 && strncmp("hidden", NAD_AVAL(nad, attr), 6) == 0)            xdf->type = xd_field_HIDDEN;        else if(NAD_AVAL_L(nad, attr) == 9 && strncmp("jid-multi", NAD_AVAL(nad, attr), 9) == 0)            xdf->type = xd_field_JID_MULTI;        else if(NAD_AVAL_L(nad, attr) == 10 && strncmp("jid-single", NAD_AVAL(nad, attr), 10) == 0)            xdf->type = xd_field_JID_SINGLE;        else if(NAD_AVAL_L(nad, attr) == 10 && strncmp("list-multi", NAD_AVAL(nad, attr), 10) == 0)            xdf->type = xd_field_LIST_MULTI;        else if(NAD_AVAL_L(nad, attr) == 11 && strncmp("list-single", NAD_AVAL(nad, attr), 11) == 0)            xdf->type = xd_field_LIST_SINGLE;        else if(NAD_AVAL_L(nad, attr) == 10 && strncmp("text-multi", NAD_AVAL(nad, attr), 10) == 0)            xdf->type = xd_field_TEXT_MULTI;        else if(NAD_AVAL_L(nad, attr) == 12 && strncmp("text-private", NAD_AVAL(nad, attr), 12) == 0)            xdf->type = xd_field_TEXT_PRIVATE;        else if(NAD_AVAL_L(nad, attr) == 11 && strncmp("text-single", NAD_AVAL(nad, attr), 11) == 0)            xdf->type = xd_field_TEXT_SINGLE;        else {            log_debug(ZONE, "unknown field type '%.*s'", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));            return NULL;        }    }    elem = nad_find_elem(nad, root, NAD_ENS(nad, root), "value", 1);    while(elem >= 0) {        if(NAD_CDATA_L(nad, elem) <= 0) {            log_debug(ZONE, "value element requires cdata");            return NULL;        }        xdata_add_value(xdf, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem));        elem = nad_find_elem(nad, elem, NAD_ENS(nad, elem), "value", 0);    }    elem = nad_find_elem(nad, root, NAD_ENS(nad, root), "options", 1);    while(elem >= 0) {        eval = nad_find_elem(nad, elem, NAD_ENS(nad, elem), "value", 1);        if(eval < 0) {            log_debug(ZONE, "option requires value subelement");            return NULL;        }        if(NAD_CDATA_L(nad, eval) <= 0) {            log_debug(ZONE, "value element requires cdata");            return NULL;        }        attr = nad_find_attr(nad, elem, -1, "label", NULL);        if(attr < 0)            xdata_option_new(xdf, NAD_CDATA(nad, eval), NAD_CDATA_L(nad, eval), NAD_AVAL(nad, eval), NAD_AVAL_L(nad, eval));        else            xdata_option_new(xdf, NAD_CDATA(nad, eval), NAD_CDATA_L(nad, eval), NULL, 0);        elem = nad_find_elem(nad, elem, NAD_ENS(nad, elem), "options", 0);    }    return xdf;}/** parse a nad and build */xdata_t xdata_parse(nad_t nad, int root) {    xdata_t xd;    int atype, elem, field;    xdata_field_t xdf;    assert((int) nad);    assert((int) (root >= 0));    log_debug(ZONE, "building xd from nad");    if(root >= nad->ecur || NAD_NURI_L(nad, NAD_ENS(nad, root)) != strlen(uri_XDATA) || strncmp(uri_XDATA, NAD_NURI(nad, NAD_ENS(nad, root)), strlen(uri_XDATA) != 0) || NAD_ENAME_L(nad, root) != 1 || (NAD_ENAME(nad, root))[0] != 'x') {        log_debug(ZONE, "elem %d does not exist, or is not {x:data}x", root);        return NULL;    }    atype = nad_find_attr(nad, root, -1, "type", NULL);    if(atype < 0) {        log_debug(ZONE, "no type attribute");        return NULL;    }    if(NAD_AVAL_L(nad, atype) == 4 && strncmp("form", NAD_AVAL(nad, atype), NAD_AVAL_L(nad, atype)) == 0)        xd = xdata_new(xd_type_FORM, NULL, NULL);    else if(NAD_AVAL_L(nad, atype) == 6 && strncmp("result", NAD_AVAL(nad, atype), NAD_AVAL_L(nad, atype)) == 0)        xd = xdata_new(xd_type_RESULT, NULL, NULL);    else if(NAD_AVAL_L(nad, atype) == 6 && strncmp("submit", NAD_AVAL(nad, atype), NAD_AVAL_L(nad, atype)) == 0)        xd = xdata_new(xd_type_SUBMIT, NULL, NULL);    else if(NAD_AVAL_L(nad, atype) == 6 && strncmp("cancel", NAD_AVAL(nad, atype), NAD_AVAL_L(nad, atype)) == 0)        xd = xdata_new(xd_type_CANCEL, NULL, NULL);    else {        log_debug(ZONE, "unknown xd type %.*s", NAD_AVAL_L(nad, atype), NAD_AVAL(nad, atype));        return NULL;    }    elem = nad_find_elem(nad, root, NAD_ENS(nad, root), "title", 1);    if(elem < 0 || NAD_CDATA_L(nad, elem) <= 0) {        log_debug(ZONE, "no cdata on x/title element");        pool_free(xd->p);        return NULL;    }    xd->title = pmalloco(xd->p, sizeof(char) * (NAD_CDATA_L(nad, elem) + 1));    strncpy(xd->title, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem));    elem = nad_find_elem(nad, root, NAD_ENS(nad, root), "instructions", 1);    if(elem < 0 || NAD_CDATA_L(nad, elem) <= 0) {        log_debug(ZONE, "no cdata on x/instructions element");        pool_free(xd->p);        return NULL;    }    xd->instructions = pstrdupx(xd->p, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem));    switch(xd->type) {        case xd_type_FORM:        case xd_type_SUBMIT:            /* form and submit just have fields, one level */            field = nad_find_elem(nad, root, NAD_ENS(nad, root), "field", 1);            while(field >= 0) {                xdf = _xdata_field_parse(xd, nad, field);                if(xdf == NULL) {                    log_debug(ZONE, "field parse failed");                    pool_free(xd->p);                    return NULL;                }                xdata_add_field(xd, xdf);                field = nad_find_elem(nad, field, NAD_ENS(nad, root), "field", 0);            }            break;        case xd_type_RESULT:            /* result has reported and item */            elem = nad_find_elem(nad, root, NAD_ENS(nad, root), "reported", 1);            if(elem >= 0) {                field = nad_find_elem(nad, elem, NAD_ENS(nad, root), "field", 1);                while(field >= 0) {                    xdf = _xdata_field_parse(xd, nad, field);                    if(xdf == NULL) {                        log_debug(ZONE, "field parse failed");                        pool_free(xd->p);                        return NULL;                    }                    xdata_add_field(xd, xdf);                    field = nad_find_elem(nad, field, NAD_ENS(nad, root), "field", 0);                }            }            elem = nad_find_elem(nad, root, NAD_ENS(nad, root), "item", 1);            if(elem >= 0) {                field = nad_find_elem(nad, elem, NAD_ENS(nad, root), "field", 1);                while(field >= 0) {                    xdf = _xdata_field_parse(xd, nad, field);                    if(xdf == NULL) {                        log_debug(ZONE, "field parse failed");                        pool_free(xd->p);                        return NULL;                    }                    xdata_add_field(xd, xdf);                    field = nad_find_elem(nad, field, NAD_ENS(nad, root), "field", 0);                }            }            break;        case xd_type_CANCEL:            /* nothing to do with cancel, its all based on context */            break;        case xd_type_NONE:            break;    }    return xd;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -