xml.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 993 行 · 第 1/2 页

C
993
字号
                status = xml_print_field(xml, rec_area + offset + i * size, ndx, task);                if (status != S_OKAY)                    return status;            }        }    }    else    {        status = xml_print_field(xml, rec_area + offset, ndx, task);        if (status != S_OKAY)            return status;    }    return S_OKAY;}/* * print one field of data, based on its type */static int xml_print_field(    XML_FILE   *xml,    char       *fld_area,    int         ndx,    DB_TASK    *task){    DB_TCHAR    str[30];    char        charint;    short       shortint;    int         regint;    long        longint;    float       floatval;    double      doubval;    DB_ADDR     dbaval;    int         unsignedFld;    int         status = S_OKAY;    /* print start tag */    if (task->field_table[ndx].fd_type == DBADDR)    {        XML_ATTRIBUTE idref_attr = { "idref", str };        memcpy(&dbaval, fld_area, DB_ADDR_SIZE);        strcpy(str, XML_ID_PREFIX);        xml_cvt_dba(str + strlen(XML_ID_PREFIX), dbaval, xml->xo->decimal);        status = xml_print_content(xml, XML_START_TAG, task->field_names[ndx], &idref_attr, (dbaval != NULL_DBA) ? 1 : 0);    }    else    {        status = xml_print_content(xml, XML_START_TAG, task->field_names[ndx], NULL, 0);        if (S_OKAY != status)            return status;    }    /* select action based on type */    unsignedFld = task->field_table[ndx].fd_flags & UNSIGNEDFLD;    switch (task->field_table[ndx].fd_type)    {        case CHARACTER:            /* single character type */            memcpy(&charint, fld_area, CHAR_SIZE);            if (unsignedFld)                vstprintf(str, DB_TEXT("%u"), (unsigned int) charint);            else                vstprintf(str, DB_TEXT("%d"), (int) charint);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case SHORTINT:            /* short integer type */            memcpy(&shortint, fld_area, SHORT_SIZE);            if (unsignedFld)                vstprintf(str, DB_TEXT("%u"), (unsigned int) ((unsigned short) shortint));            else                vstprintf(str, DB_TEXT("%d"), (int) shortint);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case REGINT:            /* regular integer type */            memcpy(&regint, fld_area, INT_SIZE);            if (unsignedFld)                vstprintf(str, DB_TEXT("%u"), (unsigned int) regint);            else                vstprintf(str, DB_TEXT("%d"), regint);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case LONGINT:            /* long integer type */            memcpy(&longint, fld_area, LONG_SIZE);            if (unsignedFld)                vstprintf(str, DB_TEXT("%lu"), (unsigned long) longint);            else                vstprintf(str, DB_TEXT("%ld"), longint);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case FLOAT:            /* float type */            memcpy(&floatval, fld_area, FLOAT_SIZE);            vstprintf(str, DB_TEXT("%.20g"), floatval);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case DOUBLE:            /* double float type */            memcpy(&doubval, fld_area, DOUBLE_SIZE);            vstprintf(str, DB_TEXT("%.20g"), doubval);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case DBADDR:            /* database address type */            memcpy(&dbaval, fld_area, DB_ADDR_SIZE);            xml_cvt_dba(str, dbaval, xml->xo->decimal);            status = xml_print_content(xml, XML_PCDATA, str, NULL, 0);            break;        case GROUPED:            /* grouped type - WRONG! */            vftprintf(stderr, DB_TEXT("Grouped type found in pr_field\n"));            break;    }                                   /* end select action based on type */    if (S_OKAY != status)        return status;    status = xml_print_content(xml, XML_END_TAG, task->field_names[ndx], NULL, 0);    return status;}/* * convert a database address into text */static void xml_cvt_dba(    DB_TCHAR   *sdba,    DB_ADDR     dba,    DB_BOOLEAN  decimal){    short       file;    DB_ULONG    slot;    if (dba == NULL_DBA)    {        vtstrcpy(sdba, DB_TEXT("NULL"));    }    else    {        if (decimal)        {            vstprintf(sdba, DB_TEXT("%lu"), dba);        }        else        {            d_decode_dba(dba, &file, &slot);            vstprintf(sdba, DB_TEXT("%d:%lu"), file, slot);        }    }    return;}/* * Returns true if the given record type should be exported. */DB_BOOLEAN xml_is_export_type(XML_FILE *xml, short rec_type){    int i;    /* check if this record type is to be exported */    if (xml->xo->n_recs)    {        for (i = 0; i < xml->xo->n_recs; i++)        {            if (rec_type == xml->xo->rt_index[i])                break;        }        /* skip if record type is not to be exported */        if (i == xml->xo->n_recs)            return FALSE;    }    return TRUE;}/* * Start printing an XML file to a previously opened FILE stream. */int xml_start_file(XML_FILE *xml, FILE* fp, DB_TCHAR *doctype, DB_TCHAR *schema){    xml->fp = fp;    xml->depth = 0;    xml->previous_type = XML_EMPTY_TAG;    if (vftprintf(xml->fp, "<?xml version=\"1.0\" standalone=\"no\"?>") == 0)        return S_NOSPACE;    /* Doctype and schema */    if ((vftprintf(xml->fp, "\n<!DOCTYPE ") == 0) ||        (vftprintf(xml->fp, doctype) == 0) ||        (vftprintf(xml->fp, " SYSTEM \"") == 0) ||        (vftprintf(xml->fp, schema) == 0) ||        (vftprintf(xml->fp, "\">") == 0))        return S_NOSPACE;    xml_print_content(xml, XML_COMMENT, XML_COMPANY_INFO, NULL, 0);    return S_OKAY;}/* * Finish printing an XML file. Does not close the file stream. */int xml_end_file(XML_FILE *xml){    if (vfputtc(DB_TEXT('\n'), xml->fp) != DB_TEXT('\n'))        return S_NOSPACE;    return S_OKAY;}/* * Print content (tag or PCDATA) to an XML file. */int xml_print_content(XML_FILE *xml, int type, DB_TCHAR *text, XML_ATTRIBUTE *attr, short size_attr){    int i;    /* Decrease the depth if this is an end tag */    if (type == XML_END_TAG)        xml->depth--;    /* Only start with a newline and indentation if neither this     * nor the previous content is PCDATA. */    if (type != XML_PCDATA && xml->previous_type != XML_PCDATA)    {        if (vfputtc(DB_TEXT('\n'), xml->fp) != DB_TEXT('\n'))            return S_NOSPACE;        /* print tab character to appropriate depth */        for (i = 0; i < xml->depth; i++)        {            if (vfputtc(DB_TEXT('\t'), xml->fp) != DB_TEXT('\t'))                return S_NOSPACE;        }    }    if (type == XML_PCDATA)    {        /* print pcdata text */        if (vftprintf(xml->fp, text) == 0)            return S_NOSPACE;    }    else if (type == XML_COMMENT)    {        if (vftprintf(xml->fp, "<!-- ") == 0)            return S_NOSPACE;        /* print comment text */        if (vftprintf(xml->fp, text) == 0)            return S_NOSPACE;        if (vftprintf(xml->fp, " -->") == 0)            return S_NOSPACE;    }    else /* type is a TAG */    {        /* begin XML tag */        if (vfputtc(DB_TEXT('<'), xml->fp) != DB_TEXT('<'))            return S_NOSPACE;        /* print slash if this is a closing tag */        if (type == XML_END_TAG)        {            if (vfputtc(DB_TEXT('/'), xml->fp) != DB_TEXT('/'))                return S_NOSPACE;        }        /* print name of tag */        if (vftprintf(xml->fp, text) == 0)            return S_NOSPACE;        /* print attributes, unless this is an end tag */        if (type != XML_END_TAG && attr != NULL)        {            for (i = 0; i < size_attr; i++)            {                if (vfputtc(DB_TEXT(' '), xml->fp) != DB_TEXT(' '))                    return S_NOSPACE;                if (vftprintf(xml->fp, attr[i].key) == 0)                    return S_NOSPACE;                if (vftprintf(xml->fp, DB_TEXT("=\"")) == 0)                    return S_NOSPACE;                /* assume value is already properly quoted */                if (vftprintf(xml->fp, attr[i].value) == 0)                    return S_NOSPACE;                if (vfputtc(DB_TEXT('\"'), xml->fp) != DB_TEXT('\"'))                    return S_NOSPACE;            }        }        /* print trailing slash if this is an empty tag */        if (type == XML_EMPTY_TAG)        {            if (vfputtc(DB_TEXT('/'), xml->fp) != DB_TEXT('/'))                return S_NOSPACE;        }        /* close XML tag */        if (vfputtc(DB_TEXT('>'), xml->fp) != DB_TEXT('>'))            return S_NOSPACE;    }    /* Increase depth for next tag if this is a start tag */    if (type == XML_START_TAG)        xml->depth++;    xml->previous_type = type;    return S_OKAY;}/* * print char-sized ascii text */static int xml_print_ascii(    XML_FILE      *xml,    void          *data,    DB_TASK       *task){    FILE          *df = xml->fp;    DB_BOOLEAN     extended = FALSE;    unsigned char  k;    char           buf[10];    char          *str = (char *) data;#if defined(UNICODE)    DB_TCHAR       tbuf[10];    DB_TCHAR       tstr[2];#else    DB_TCHAR      *tbuf = buf;    DB_TCHAR      *tstr;#endif    /* for each character to be printed */    while (*str)    {#if defined(UNICODE)        atow(str, tstr, 2);        tstr[1] = 0;#else        tstr = str;#endif        /* print the character */        if ((*str < ' ') || (*str > '~'))        {            buf[1] = '\0';            k = (unsigned char) *str;            if (task->ctbl_activ && task->country_tbl[k].out_chr)            {                buf[0] = k;            }            else            {                switch (*str)                {                    case '\n':                    case '\r':                    case '\t': buf[0] = *str; break;                    default:                        if (xml->xo->extended)                            buf[0] = *str;                        else /* convert to &#x00; form */                            sprintf(buf, "&#x%02x;", (0xff & (int) *str));                        break;                }            }#if defined(UNICODE)            atow(buf, tbuf, sizeof(tbuf) / sizeof(DB_TCHAR));#endif            if (vfputts(tbuf, df) == EOF)                return S_NOSPACE;        }        else        {            /* Escape special XML characters */            switch (*str)            {                /* TODO: error checking */                case '&': vfputts("&amp;", df); break;                case '<': vfputts("&lt;", df); break;                case '>': vfputts("&gt;", df); break;                case '\"': vfputts("&quot;", df); break;                case '\'': vfputts("&apos;", df); break;                default:                    if (vfputtc(tstr[0], df) != tstr[0])                        return S_NOSPACE;            }        }        str++;    }    xml->previous_type = XML_PCDATA;    return S_OKAY;}/* * print char-sized binary data */static int xml_print_binary(    XML_FILE   *xml,    char       *rec_area,    int         width){    FILE    *df = xml->fp;    int      i;    for (i = 0; i < width; i++)    {        if (vftprintf(df, DB_TEXT("%02x"), *rec_area++ & 0xff) == 0)            return S_NOSPACE;    }    xml->previous_type = XML_PCDATA;    return S_OKAY;}/* * print wide character unicode text */static int xml_print_unicode(    XML_FILE      *xml,    void          *data,    DB_TASK       *task){    FILE          *df = xml->fp;    wchar_t       *str = (wchar_t *) data;#if defined(UNICODE)    DB_TCHAR      *tstr;#else    DB_TCHAR       tstr[2];#endif    /* for each character to be printed */    while (*str)    {#if defined(UNICODE)        tstr = str;#else        wtoa(str, tstr, 2);        tstr[1] = 0;#endif        if (vfputtc(tstr[0], df) != tstr[0])            return S_NOSPACE;        str++;    }    xml->previous_type = XML_PCDATA;    return S_OKAY;}/* * print wide character binary data */static int xml_print_wbinary(    XML_FILE   *xml,    char       *rec_area,    int         width){    FILE    *df = xml->fp;    int      i;    wchar_t *p = (wchar_t *) rec_area;    for (i = 0; i < width; i++)    {        if (vftprintf(df, DB_TEXT("%04x"), (unsigned int) *p++) == 0)            return S_NOSPACE;    }    xml->previous_type = XML_PCDATA;    return S_OKAY;}

⌨️ 快捷键说明

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