xml.c

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

C
993
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database kernel                                             * *                                                                         * * Copyright (c) 2000 Centura Software Corporation. All rights reserved.   * *                                                                         * * Use of this software, whether in source code format, or in executable,  * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this  * * distribution of source code files.                                      *  *                                                                         * * Except as provided herein, the contents of this file are subject to the * * Centura Open Source Public License Version 1.0 (the "License"); you may * * not use this file except in compliance with the License.  A copy of the * * License will be provided to you by Club ITTIA.                          * *                                                                         * * Software distributed under the License is distributed on an "AS IS"     * * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * * License for the specific language governing rights and limitations      * * under the License.                                                      * *                                                                         * * The Original Code is db.linux version 1.0, released February 29, 2000.  * *                                                                         * * The Initial Developer of the Original Code is Centura Software          * * Corporation. Portions created by Centura Software Corporation are       * * Copyright (C) 1984-2000 Centura Software Corporation. All Rights        * * Reserved.                                                               * *                                                                         * * This file contains modifications to the Original Code made by ITTIA.    * * This file may only be used in accordance with the ITTIA DB.* V.2        * * License Agreement which is available at WWW.ITTIA.COM.                  * *                                                                         * **************************************************************************//*-----------------------------------------------------------------------    xml.c - XML support    Provides XML export.-----------------------------------------------------------------------*/#include "db.star.h"#include "xml.h"#include "dbexp.h"#define XML_COMPANY_INFO DB_TEXT("ITTIA db.* XML generator, www.ittia.com")#define XML_ID_PREFIX DB_TEXT("DB_ADDR:")static int xml_print_table(XML_FILE *xml, int rec_type, DB_TASK *task);static int xml_print_record(XML_FILE *xml, short rec_type, char *rec_area, DB_ADDR, DB_TASK *task);static int xml_print_members(XML_FILE *xml, short set_type, DB_ADDR dba, TASK *task);static int xml_print_struct(XML_FILE *xml, char *rec_area, int offset, int ndx, DB_TASK *task);static int xml_print_element(XML_FILE *xml, char *rec_area, int offset, int ndx, DB_TASK *task);static int xml_print_field(XML_FILE *xml, char *fld_area, int ndx, DB_TASK *task);DB_BOOLEAN xml_is_export_type(XML_FILE *, short);static void xml_cvt_dba(DB_TCHAR *sdba, DB_ADDR dba, DB_BOOLEAN decimal);static int xml_print_ascii(XML_FILE *xml, void *data, DB_TASK *task);static int xml_print_binary(XML_FILE *xml, char *rec_area, int width);static int xml_print_unicode(XML_FILE *xml, void *data, DB_TASK *task);static int xml_print_wbinary(XML_FILE *xml, char *rec_area, int width);/* * print a database to an XML file */int xml_print_db(XML_FILE *xml, DB_TASK *task){    int         rec_type,                status;    DB_TCHAR    *name;    /* assume the correct database has been selected already */    name = (DB_TCHAR *) psp_cGetMemory( (vtstrlen(task->curr_db_table->db_name) + 1) * sizeof(DB_TCHAR), 0);    vtstrupr(vtstrcpy(name, task->curr_db_table->db_name));    status = xml_print_content(xml, XML_START_TAG, name, NULL, 0);    psp_freeMemory(name, 0);    if (S_OKAY != status)        return S_NOSPACE;    /* print set members owned by system record */    for (rec_type = task->size_rt - 1; rec_type >= 0; rec_type--)    {        DB_ADDR   dba;        short     set_type;                /* continue until a system record is found */        if (task->record_table[rec_type].rt_fdtot != -1)            continue;        /* locate the system record itself */        status = d_recfrst(rec_type + RECMARK, task, CURR_DB);        if (S_OKAY != status)            return status;        /* find the system record's dba */        d_crget(&dba, task, CURR_DB);        /* print all sets owned by system record */        for (set_type = 0; set_type < task->size_st; set_type++)        {            if (task->set_table[set_type].st_own_rt == rec_type)            {                /* print set members */                status = xml_print_members(xml, set_type, dba, task);                if (S_OKAY != status)                    return status;            }        }        break;    }    /* print each table in the database. */    for (rec_type = 0; rec_type < task->size_rt; rec_type++)    {        /* ignore system record */        if (task->record_table[rec_type].rt_fdtot == -1)            continue;        if (!xml_is_export_type(xml, rec_type))            continue;        status = xml_print_table(xml, rec_type, task);        if (S_OKAY != status)            return status;    }    name = (DB_TCHAR *) psp_cGetMemory( (vtstrlen(task->curr_db_table->db_name) + 1) * sizeof(DB_TCHAR), 0);    vtstrupr(vtstrcpy(name, task->curr_db_table->db_name));    status = xml_print_content(xml, XML_END_TAG, name, NULL, 0);    psp_freeMemory(name, 0);    if (S_OKAY != status)        return S_NOSPACE;    return S_OKAY;}/* * print a database table (type of record) to an XML file */int xml_print_table(XML_FILE *xml, int rec_type, DB_TASK *task){    int status;    /* print each record in the table */    /* NOTE: this affects the currency table */    for (status = d_recfrst(rec_type + RECMARK, task, CURR_DB);         status == S_OKAY;          status = d_recnext(task, CURR_DB))     {        DB_ADDR   dba;        char     *rec;        /* Retrieve the database address and use it to access the         * record data */        d_crget(&dba, task, CURR_DB);        if ((status = dio_read(dba, &rec, NOPGHOLD, task)) != S_OKAY)            break;        /* Print the record to the XML file */        status = xml_print_record(xml, rec_type, rec, dba, task);        if (status != S_OKAY)            break;        /* Flush the buffer before moving on */        if (fflush(xml->fp) == EOF)        {            status = S_NOSPACE;            break;        }    }    /* Loop should only finish when no more records are found. All other cases     * indicate an error. */    if (S_NOTFOUND != status)        return status;    return S_OKAY;}/* * print all data in a record to an XML file */static int xml_print_record(    XML_FILE   *xml,    short       rec_type,    char       *rec_area,    DB_ADDR     dba,    DB_TASK    *task){    int         fld,                dims,                base,                nelem,                i,                size,                set_type,                status;    DB_TCHAR    str[38] = XML_ID_PREFIX;    XML_ATTRIBUTE id_attr = { "id", str };    /* open tag */    xml_cvt_dba(str + strlen(XML_ID_PREFIX), dba, xml->xo->decimal);    status = xml_print_content(xml, XML_START_TAG, task->record_names[rec_type], &id_attr, 1);    if (S_OKAY != status)        return status;    /* list set relationships */    for (set_type = 0; set_type < task->size_st; set_type++)       /* print all sets owned by this record */    {        if (task->set_table[set_type].st_own_rt == rec_type)        {            status = xml_print_members(xml, set_type, dba, task);            if (S_OKAY != status)                return status;        }    }    /* for each data field in this record */    for ( fld = task->record_table[rec_type].rt_fields;          fld < task->record_table[rec_type].rt_fields +                task->record_table[rec_type].rt_fdtot;          fld++)    {        /* If this field is structured */        if (task->field_table[fld].fd_type == GROUPED)        {            /* determine if there is an array of structures */            for ( dims = 0;                  dims < MAXDIMS && task->field_table[fld].fd_dim[dims];                  dims++)                ;  /* empty body */            base = task->field_table[fld].fd_ptr;            /* if this is an array of structures */            if (dims > 0)            {                /* determine how many elements will be printed */                for (nelem = 1, i = 0; i < dims; i++)                    nelem *= task->field_table[fld].fd_dim[i];                size = task->field_table[fld].fd_len / nelem;                for (i = 0; i < nelem; i++)                    xml_print_struct(xml, rec_area, base + i * size, fld, task);            }            else            {                xml_print_struct(xml, rec_area, base, fld, task);            }        }        else        {            /* make sure this field is not a part of a structure */            if (task->field_table[fld].fd_flags & STRUCTFLD)                continue;            /* print a non-structured field */            status = xml_print_element(xml, rec_area, task->field_table[fld].fd_ptr, fld, task);            if (status != S_OKAY)                return status;        }    }    status = xml_print_content(xml, XML_END_TAG, task->record_names[rec_type], NULL, 0);    if (S_OKAY != status)        return status;    return S_OKAY;}/* * print all members of a set relationship with a record */static int xml_print_members(    XML_FILE   *xml,    short       set_type,    DB_ADDR     dba,    TASK       *task){    DB_TCHAR    str[38] = XML_ID_PREFIX;    int status;    /* TODO: store and restore old set owner */    status = d_csoset(set_type + SETMARK, &dba, task, CURR_DB);    if (S_OKAY != status)        return status;    status = d_findfm(set_type + SETMARK, task, CURR_DB);    if (status == S_EOS)    {        /* no members for this set relationship */        status = xml_print_content(xml, XML_EMPTY_TAG, task->set_names[set_type], NULL, 0);        if (S_OKAY != status)            return status;    }    else    {        /* list members of this set relationship */        status = xml_print_content(xml, XML_START_TAG, task->set_names[set_type], NULL, 0);        if (S_OKAY != status)            return status;        for (status = d_findfm(set_type + SETMARK, task, CURR_DB);              status == S_OKAY;             status = d_findnm(set_type + SETMARK, task, CURR_DB))        {            DB_ADDR mem_dba;            char   *mem_rec;            short   mem_rec_type;            XML_ATTRIBUTE idref_attr = { "idref", str };            /* get the database address of the current member */            d_crget(&mem_dba, task, CURR_DB);            /* read the member record to determine type */            status = dio_read(mem_dba, &mem_rec, NOPGHOLD, task);            if (S_OKAY != status)                return status;            /* determine record type */            memcpy(&mem_rec_type, mem_rec, sizeof(short));            mem_rec_type &= ~RLBMASK;            xml_cvt_dba(str + strlen(XML_ID_PREFIX), mem_dba, xml->xo->decimal);            status = xml_print_content(xml, XML_EMPTY_TAG, task->record_names[mem_rec_type], &idref_attr, xml_is_export_type(xml, mem_rec_type) ? 1 : 0);            if (S_OKAY != status)                return status;#if 0            status = xml_print_content(xml, XML_EMPTY_TAG, "test", NULL, 0);               d_recread(&chk, task, CURR_DB);                  ... /* print check record */#endif        }        /* Only valid exit status is end of set */        if (S_EOS != status)            return status;    status = xml_print_content(xml, XML_END_TAG, task->set_names[set_type], NULL, 0);    if (S_OKAY != status)        return status;    }    return S_OKAY;}/* * print all elements of one structure */static int xml_print_struct(    XML_FILE   *xml,    char       *rec_area,    int         offset,    int         ndx,    DB_TASK    *task){    int      diff,                fld,                status;    status = xml_print_content(xml, XML_START_TAG, task->field_names[ndx], NULL, 0);    if (S_OKAY != status)        return status;    /* for each subfield */    fld = ndx + 1;    while (task->field_table[fld].fd_flags & STRUCTFLD)    {        diff = task->field_table[fld].fd_ptr - task->field_table[ndx].fd_ptr;        status = xml_print_element(xml, rec_area, offset + diff, fld, task);        if (status != S_OKAY)            return status;        fld++;    }    if (S_OKAY != status)        return status;    status = xml_print_content(xml, XML_END_TAG, task->field_names[ndx], NULL, 0);    return S_OKAY;}/* * print all elements of a non-structured field  */static int xml_print_element(    XML_FILE   *xml,    char       *rec_area,    int         offset,    int         ndx,    DB_TASK    *task){    int      i,             dims,             nelem,             idx,             fd_width,             size,             status;    /* determine if there is an array */    for (dims = 0; dims < MAXDIMS && task->field_table[ndx].fd_dim[dims]; dims++)        ;    /* if this field is an array */    if (dims > 0)    {        /* determine how many elements will be printed */        for (nelem = 1, i = 0; i < dims; i++)            nelem *= task->field_table[ndx].fd_dim[i];        size = task->field_table[ndx].fd_len / nelem;        /* character types are copied instead of converted */        if (task->field_table[ndx].fd_type == CHARACTER)        {            fd_width = task->field_table[ndx].fd_dim[dims - 1];            status = xml_print_content(xml, XML_START_TAG, task->field_names[ndx], NULL, 0);            if (S_OKAY != status)                return status;            if (fd_width > 1)            {                /* for each character string array element */                for (idx = 0; idx < task->field_table[ndx].fd_len; idx += fd_width)                {                    status = xml_print_ascii(xml, rec_area + offset + idx, task);                    if (status != S_OKAY)                        return status;                }            }            else            {                /* binary copy */                fd_width = task->field_table[ndx].fd_dim[dims - 2];                for (idx = 0; idx < task->field_table[ndx].fd_len; idx += fd_width)                {                    status = xml_print_binary(xml, rec_area + offset + idx, fd_width);                    if (status != S_OKAY)                        return status;                }            }            status = xml_print_content(xml, XML_END_TAG, task->field_names[ndx], NULL, 0);            if (S_OKAY != status)                return status;        }        else if (task->field_table[ndx].fd_type == WIDECHAR)        {            fd_width = task->field_table[ndx].fd_dim[dims - 1];            status = xml_print_content(xml, XML_START_TAG, task->field_names[ndx], NULL, 0);            if (S_OKAY != status)                return status;            if (fd_width > 1)            {                /* for each character string array element */                for (idx = 0; idx < task->field_table[ndx].fd_len;                       idx += fd_width * sizeof(wchar_t))                {                    status = xml_print_unicode(xml, rec_area + offset + idx, task);                    if (status != S_OKAY)                        return status;                }            }            else            {                /* binary copy */                fd_width = task->field_table[ndx].fd_dim[dims - 2];                for (idx = 0; idx < task->field_table[ndx].fd_len;                       idx += fd_width * sizeof(wchar_t))                {                    status = xml_print_wbinary(xml, rec_area + offset + idx, fd_width);                    if (status != S_OKAY)                        return status;                }            }            status = xml_print_content(xml, XML_END_TAG, task->field_names[ndx], NULL, 0);            if (S_OKAY != status)                return status;        }        else        {            /* else non-character data */            /* now loop once for each element following */            for (i = 0; i < nelem; i++)            {

⌨️ 快捷键说明

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