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 + -
显示快捷键?