IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 4786


Ignore:
Timestamp:
Aug 16, 2005, 10:13:20 AM (21 years ago)
Author:
drobbin
Message:

Created XML interface for psLib

Location:
trunk/psLib/src/xml
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/xml/psXML.c

    r4540 r4786  
    11/** @file  psXML.c
    22*
    3 *  @brief Contains XML input/output functions.
     3*  @brief Contains basic XML definitions and operations
    44*
    5 *  This file defines functions to read metadata from an XML file.
     5*  This file defines the basic type for an XML struct and functions useful
     6*  in creation and usage of XML documents/files.
    67*
    78*  @ingroup XML
    89*
    9 *  @author Ross Harman, MHPCC
    10 *  @author Eric Van Alst, MHPCC
     10*  @author David Robbins, MHPCC
    1111*
    12 *  @version $Revision: 1.35 $ $Name: not supported by cvs2svn $
    13 *  @date $Date: 2005-07-12 19:12:01 $
     12*  @version $Revision: 1.36 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2005-08-16 20:13:20 $
    1414*
    1515*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    1616*/
    1717
    18 #include <libxml/parser.h>
    19 #include <string.h>
    20 #include <ctype.h>
    21 #include <limits.h>
    22 
    2318#include "psXML.h"
    24 #include "psMemory.h"
    25 #include "psError.h"
    26 #include "psString.h"
    27 #include "psConstants.h"
    28 #include "psErrorText.h"
     19#include <unistd.h>
     20#include <fcntl.h>
    2921
    3022/******************************************************************************/
     
    3224/******************************************************************************/
    3325
    34 /** Maximum size of a FITS line */
    35 #define FITS_LINE_SIZE 80
    36 
    3726/** Maximum size of a string */
    38 #define MAX_STRING_LENGTH 256
    39 
    40 // Returns single parsed value as a double precision number. The input string must be cleaned and null
    41 // terminated.
    42 static double parseValue(char *inString, psS32 *status)
    43 {
    44     char *end = NULL;
    45     double value = 0.0;
    46 
    47     value = strtod(inString, &end);
    48     if(*end != '\0') {
    49         *status = 1;
    50     } else if(inString==end) {
    51         *status = 1;
    52     }
    53 
    54     return value;
    55 }
    56 
    57 /** Returns true or false. 'T', 't', '1', 'F', 'f', and '0' are acceptable, parsable variations. */
    58 static psBool parseBool(char *inString, psS32 *status)
    59 {
    60     psBool value = false;
    61 
    62 
    63     if(*inString=='T' || *inString=='t' || *inString=='1') {
    64         value = true;
    65     } else if(*inString=='F' || *inString=='f' || *inString=='0') {
    66         value = false;
    67     } else {
    68         *status = 1;
    69     }
    70 
    71     return value;
    72 }
    73 
    74 /** Returns parsed vector filled with with data. The input string must be null terminated. */
    75 static psVector* parseVector(char *inString, psElemType elemType, psS32 *status)
    76 {
    77     char*      end       = NULL;
    78     char*      saveValue = NULL;
    79     psS32      i         = 0;
    80     psS32      numValues = 0;
    81     double     value     = 0.0;
    82     psVector*  vec       = NULL;
    83 
    84     // Cycle through string and count entries
    85     saveValue = inString;
    86     while(*inString!='\0') {
    87         strtod(inString, &end);
    88         if(inString==end) {
    89             *status = 1;
     27#define MAXSTR 256
     28#define MAXVEC 2048
     29#define MAXBUF 10000
     30
     31
     32static void XMLFree(psXMLDoc *XML)
     33{
     34    xmlFreeDoc(*XML);
     35}
     36
     37psXMLDoc *psXMLDocAlloc(void)
     38{
     39    psXMLDoc *XML;
     40    XML = psAlloc(sizeof(psXMLDoc));
     41    psMemSetDeallocator(XML, (psFreeFunc) XMLFree);
     42    return(XML);
     43}
     44
     45psXMLDoc *psMetadataToXMLDoc(const psMetadata *md)
     46{
     47    PS_ASSERT_PTR_NON_NULL(md, NULL);
     48
     49    psXMLDoc *XML = psXMLDocAlloc();
     50    xmlNode *cur_node;
     51    xmlNode *root = NULL;
     52    xmlAttr *prop = NULL;
     53    psDataType type;
     54    char content[MAXSTR];
     55    char vec[MAXVEC];
     56    int i;
     57    psMetadataIterator *iter = psMetadataIteratorAlloc(*(psMetadata**)&md, PS_LIST_HEAD, NULL);
     58    psMetadataItem *item;
     59
     60    //setup root element
     61    if( root == NULL ) {
     62        *XML = xmlNewDoc((const xmlChar*)"1.0");
     63        root = xmlNewDocNode(*XML, NULL, (const xmlChar*)"metadata", "\n");
     64        xmlDocSetRootElement(*XML, root);
     65    }
     66    item = psMetadataGetAndIncrement(iter);
     67    while ( item != NULL ) {
     68        type = item->type;
     69        if ( type == 65537)
     70            type = PS_DATA_STRING;
     71        if ( type == 65538)
     72            type = PS_DATA_VECTOR;
     73        if ( type == 65547)
     74            type = PS_DATA_METADATA;
     75        switch (type) {
     76        case PS_DATA_BOOL:
     77            cur_node = xmlNewChild(root, NULL, "item", "\n");
     78            prop = xmlNewProp(cur_node, "name", item->name);
     79            prop = xmlNewProp(cur_node, "psType", "BOOL");
     80            if ( item->data.B )
     81                strncpy(content, "TRUE", MAXSTR);
     82            else
     83                strncpy(content, "FALSE", MAXSTR);
     84            prop = xmlNewProp(cur_node, "value", content);
     85            break;
     86        case PS_DATA_S32:
     87            snprintf(content, MAXSTR, "%d", item->data.S32);
     88            cur_node = xmlNewChild(root, NULL, "item", "\n");
     89            prop = xmlNewProp(cur_node, "name", item->name);
     90            prop = xmlNewProp(cur_node, "psType", "S32");
     91            prop = xmlNewProp(cur_node, "value", content);
     92            break;
     93        case PS_DATA_F32:
     94            snprintf(content, MAXSTR, "%f", item->data.F32);
     95            cur_node = xmlNewChild(root, NULL, "item", "\n");
     96            prop = xmlNewProp(cur_node, "name", item->name);
     97            prop = xmlNewProp(cur_node, "psType", "F32");
     98            prop = xmlNewProp(cur_node, "value", content);
     99            break;
     100        case PS_DATA_F64:
     101            snprintf(content, MAXSTR, "%lf", item->data.F64);
     102            cur_node = xmlNewChild(root, NULL, "item", "\n");
     103            prop = xmlNewProp(cur_node, "name", item->name);
     104            prop = xmlNewProp(cur_node, "psType", "F64");
     105            prop = xmlNewProp(cur_node, "value", content);
     106            break;
     107        case PS_DATA_STRING:
     108            cur_node = xmlNewChild(root, NULL, "item", "\n");
     109            prop = xmlNewProp(cur_node, "name", item->name);
     110            prop = xmlNewProp(cur_node, "psType", "STR");
     111            strncpy(content, ((char *)(item->data.V)), MAXSTR);
     112            prop = xmlNewProp(cur_node, "value", content);
     113            break;
     114        case PS_DATA_METADATA:
     115            i = 0;
     116            psXMLDoc *newDoc;
     117            xmlNode *new_root = NULL;
     118            xmlNode *new_node = NULL;
     119            newDoc = psMetadataToXMLDoc(item->data.md);
     120            new_root = xmlDocGetRootElement(*newDoc);
     121            prop = xmlNewProp(new_root, "name", item->name);
     122            prop = xmlNewProp(new_root, "psType", "METADATA");
     123            new_node = xmlAddSibling(cur_node, new_root);
     124            psFree(newDoc);
     125            break;
     126        case PS_DATA_VECTOR:
     127            cur_node = xmlNewChild(root, NULL, "vector", "\n");
     128            prop = xmlNewProp(cur_node, "name", item->name);
     129            type = ((psVector*)(item->data.V))->type.type;
     130            strncpy(vec, "", MAXSTR);
     131            switch (type) {
     132            case PS_DATA_S32:
     133                prop = xmlNewProp(cur_node, "psType", "S32");
     134                for (i = 0; ((psVector*)(item->data.V))->data.S32[i] != 0; i++) {
     135                    snprintf(content, MAXSTR, "%d",
     136                             ((psVector*)(item->data.V))->data.S32[i]);
     137                    if ( ((psVector*)(item->data.V))->data.S32[i+1] != 0 ) {
     138                        strncat(content, ", ", 2);
     139                    }
     140                    strncat(vec, content, MAXSTR);
     141                }
     142
     143                break;
     144            case PS_DATA_F32:
     145                prop = xmlNewProp(cur_node, "psType", "F32");
     146                for (i = 0; ((psVector*)(item->data.V))->data.F32[i] != 0; i++) {
     147                    snprintf(content, MAXSTR, "%f",
     148                             ((psVector*)(item->data.V))->data.F32[i]);
     149                    if ( ((psVector*)(item->data.V))->data.F32[i+1] != 0 ) {
     150                        strncat(content, ", ", 2);
     151                    }
     152                    strncat(vec, content, MAXSTR);
     153                }
     154                break;
     155            case PS_DATA_F64:
     156                prop = xmlNewProp(cur_node, "psType", "F64");
     157                for (i = 0; ((psVector*)(item->data.V))->data.F64[i] != 0; i++) {
     158                    snprintf(content, MAXSTR, "%lf",
     159                             ((psVector*)(item->data.V))->data.F64[i]);
     160                    if ( ((psVector*)(item->data.V))->data.F64[i+1] != 0 ) {
     161                        strncat(content, ", ", 2);
     162                    }
     163                    strncat(vec, content, MAXSTR);
     164                }
     165                break;
     166            case PS_DATA_UNKNOWN:
     167            default:
     168                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     169                        PS_ERRORTEXT_psXML_INVALID_DATATYPE);
     170                psFree(XML);
     171                psFree(iter);
     172                return NULL;
     173            }
     174            prop = xmlNewProp(cur_node, "value", vec);
     175            break;
     176        case PS_DATA_UNKNOWN:
     177        default:
     178            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     179                    PS_ERRORTEXT_psXML_INVALID_DATATYPE);
     180            psFree(XML);
     181            psFree(iter);
    90182            return NULL;
    91183        }
    92         while(*end==' ' || *end==',') { // Commas or spaces may be used as delimiters for vector values
    93             end++;
    94         }
    95         inString=end;
    96         numValues++;
    97     }
    98 
    99     // Cycle through string and convert string values to values
    100     if(numValues) {
    101         inString = saveValue;
    102         end = NULL;
    103         vec = psVectorAlloc(numValues, elemType);
    104 
    105         while(*inString!='\0') {
    106             value = strtod(inString, &end);
    107             if(inString==end) {
    108                 *status = 1;
    109                 return vec;
    110             }
    111             switch(elemType) {
    112             case PS_TYPE_U8:
    113                 vec->data.U8[i++] = (psU8)value;
    114                 break;
    115             case PS_TYPE_U16:
    116                 vec->data.U16[i++] = (psU16)value;
    117                 break;
    118             case PS_TYPE_U32:
    119                 vec->data.U32[i++] = (psU32)value;
    120                 break;
    121             case PS_TYPE_U64:
    122                 vec->data.U64[i++] = (psU64)value;
    123                 break;
    124             case PS_TYPE_S8:
    125                 vec->data.S8[i++] = (psS8)value;
    126                 break;
    127             case PS_TYPE_S16:
    128                 vec->data.S16[i++] = (psS16)value;
    129                 break;
    130             case PS_TYPE_S32:
    131                 vec->data.S32[i++] = (psS32)value;
    132                 break;
    133             case PS_TYPE_S64:
    134                 vec->data.S64[i++] = (psS64)value;
    135                 break;
    136             case PS_TYPE_F32:
    137                 vec->data.F32[i++] = (psF32)value;
    138                 break;
    139             case PS_TYPE_F64:
    140                 vec->data.F64[i++] = (psF64)value;
    141                 break;
    142             default:
    143                 *status = 1;
    144                 psError(PS_ERR_BAD_PARAMETER_VALUE,true,
    145                         PS_ERRORTEXT_psMetadataIO_TYPE_INVALID,
    146                         elemType);
    147             }
    148 
    149             while(*end==' ' || *end==',') {
    150                 end++;
    151             }
    152             inString=end;
    153         }
    154     }
    155 
    156     return vec;
    157 }
    158 
    159 
    160 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts)
    161 {
    162     psU64 i = 0;
    163     char* psTagName = NULL;
    164     char *psAttName = NULL;
    165     char *psAttValue = NULL;
    166     const xmlChar *attName = NULL;
    167     const xmlChar *attValue = NULL;
    168     psMetadata* md = NULL;
    169     psHash* htAtts = NULL;
    170     xmlParserCtxtPtr ctxt = NULL;
    171     xmlParserInputPtr input = NULL;
    172 
    173 
    174     // Get and check initial data pointers
    175     ctxt = (xmlParserCtxtPtr)ctx;
    176     PS_ASSERT_GENERAL_PTR_NON_NULL(ctxt, return);
    177     md = (psMetadata*)ctxt->sax->_private;
    178     PS_ASSERT_GENERAL_PTR_NON_NULL(md, return);
    179     input = (xmlParserInputPtr)ctxt->input;
    180     PS_ASSERT_GENERAL_PTR_NON_NULL(input, return);
    181 
    182     // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
    183     psTagName = psStringCopy((const char*)tagName);
    184 
    185     // Metadata containter for housing element attributes used by other SAX events
    186     htAtts = psHashAlloc(10);
    187 
    188 
    189     // Get tag name
    190     if(psTagName != NULL) {
    191         psHashAdd(htAtts, "tagName", psTagName);
    192     } else {
    193         PS_ASSERT_GENERAL_PTR_NON_NULL(psTagName, return);
    194         psFree(htAtts);
    195         psFree(psTagName);
    196         return;
    197     }
    198 
    199     // Get all attribute names and attribute values
    200     if(atts != NULL) {
    201         attName = atts[i++];
    202         attValue = atts[i++];
    203         while(attName != NULL) {
    204             if(attValue != NULL) {
    205 
    206                 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
    207                 psAttName = psStringCopy((const char*)attName);
    208                 psAttValue = psStringCopy((const char*)attValue);
    209                 psHashAdd(htAtts, psAttName, psAttValue);
    210                 psFree(psAttName);
    211                 psFree(psAttValue);
    212             } else {
    213                 PS_ASSERT_GENERAL_PTR_NON_NULL(psAttValue, return);
    214                 psFree(htAtts);
    215                 psFree(psTagName);
    216                 return;
    217             }
    218             attName = atts[i++];
    219             attValue = atts[i++];
    220         }
    221     }
    222 
    223     // Add attributes to metadata
    224 
    225     psMetadataAdd(md, PS_LIST_TAIL, "htAtts",
    226                   PS_META_HASH | PS_META_DUPLICATE_OK,
    227                   NULL, htAtts);
    228 
    229     psFree(psTagName);
    230     psFree(htAtts);
    231 
    232     return;
    233 }
    234 
    235 static void initMetadataItemXml(void *ctx, char *tagName)
    236 {
    237     psBool overwrite = false;
    238     psBool tempBool = false;
    239     psS32 status = 0;
    240     psU32 lineNumber = 0;
    241     psF64 tempDbl = 0.0;
    242     psS32 tempInt = 0.0;
    243     psMetadataType mdType = PS_META_UNKNOWN;
    244     char *fileName = NULL;
    245     char *strName = NULL;
    246     char *strType = NULL;
    247     char *strValue = NULL;
    248     psMetadata* md = NULL;
    249     psHash* htAtts = NULL;
    250     psMetadataItem *metadataItem = NULL;
    251     xmlParserCtxtPtr ctxt = NULL;
    252     xmlParserInputPtr input = NULL;
    253 
    254 
    255     // Get and check initial data pointers
    256     ctxt = (xmlParserCtxtPtr)ctx;
    257     PS_ASSERT_GENERAL_PTR_NON_NULL(ctxt, return);
    258     md = (psMetadata*)ctxt->sax->_private;
    259     PS_ASSERT_GENERAL_PTR_NON_NULL(md, return);
    260     input = (xmlParserInputPtr)ctxt->input;
    261     PS_ASSERT_GENERAL_PTR_NON_NULL(input, return);
    262     metadataItem = psMetadataLookup(md, "htAtts");
    263     PS_ASSERT_GENERAL_PTR_NON_NULL(metadataItem, return);
    264     PS_ASSERT_GENERAL_PTR_NON_NULL(metadataItem->data.list, return);
    265     metadataItem = (psMetadataItem*)psListGet(metadataItem->data.list,PS_LIST_TAIL);
    266     htAtts = (psHash*)metadataItem->data.list;
    267     PS_ASSERT_GENERAL_PTR_NON_NULL(htAtts, return);
    268     fileName = (char*)input->filename;
    269     PS_ASSERT_GENERAL_PTR_NON_NULL(fileName, return);
    270     lineNumber = input->line;
    271 
    272     // Get attribute name
    273     strName = psHashLookup(htAtts, "name");
    274     if(strName == NULL) {
    275         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
    276         return;
    277     }
    278 
    279     // Get attribute type, if there is one
    280     strType = psHashLookup(htAtts, "psType");
    281     if(strType!= NULL) {
    282         if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
    283             mdType = PS_META_STR;
    284         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
    285             mdType = PS_META_BOOL;
    286         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
    287             mdType = PS_META_S32;
    288         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
    289             mdType = PS_META_F32;
    290         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
    291             mdType = PS_META_F64;
    292         } else {
    293             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strType, lineNumber,
    294                     fileName);
    295             return;
    296         }
    297     }
    298 
    299     // Get attribute value, if there is one
    300     strValue = psHashLookup(htAtts, "value");
    301 
    302     /* If metadata item is found, and is not a folder node, and overwrite is allowed, then remove
    303     existing and allow switch/case below to add new item. If overwrite is false, then report error. If
    304     found item is folder node, then psMetadataAdd will automatically add a new child. */
    305     metadataItem = psMetadataLookup(md, "overwrite");
    306     if(metadataItem != NULL) {
    307         overwrite = parseBool((char*)strValue, &status);
    308         if(status) {
    309             status = 0;
    310             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
    311                     lineNumber, fileName);
    312         }
    313         metadataItem = psMetadataLookup(md, strName);
    314         if(metadataItem != NULL) {
    315             if(metadataItem->type != PS_META_LIST) {
    316                 if(overwrite) {
    317                     psMetadataRemove(md, INT_MIN, strName);
    318                 } else {
    319                     psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
    320                             fileName);
    321                     return;
    322                 }
    323             }
    324         }
    325     }
    326 
    327     // Create metadata item and add to metadata
    328     switch(mdType) {
    329     case PS_META_LIST:
    330         psMetadataAdd(md, PS_LIST_TAIL, strName,
    331                       mdType | PS_META_DUPLICATE_OK,
    332                       NULL, NULL);
     184        item = psMetadataGetAndIncrement(iter);
     185    }
     186    //    xmlSaveFormatFile("xmlfname", *XML, 1);
     187    psFree(iter);
     188    return XML;
     189}
     190
     191//compares strings and returns the correct data type//
     192static psDataType getType(const char *in)
     193{
     194    //Returns types S32, F32, F64, STRING, BOOL, or UNKNOWN on ERROR
     195    if ( !strncmp(in, "S32", MAXSTR) ) {
     196        return(PS_DATA_S32);
     197    } else if ( !strncmp(in, "F32", MAXSTR) ) {
     198        return(PS_DATA_F32);
     199    } else if ( !strncmp(in, "F64", MAXSTR) ) {
     200        return(PS_DATA_F64);
     201    } else if ( !strncmp(in, "STR", MAXSTR) ) {
     202        return(PS_DATA_STRING);
     203    } else if ( !strncmp(in, "BOOL", MAXSTR) ) {
     204        return(PS_DATA_BOOL);
     205    }
     206
     207    return(PS_DATA_UNKNOWN);
     208}
     209
     210static void storeValues(psVector *inVector, char *in, psDataType type)
     211{
     212    int i;
     213    char *endp;
     214
     215    switch (type) {
     216    case PS_DATA_S32:
     217        i = 0;
     218        int intValue = 0;
     219        while (i < MAXSTR) {
     220            intValue = (int)strtol(in, &endp, 10);
     221            if ( intValue != 0 ) {
     222                inVector->data.S32[i] = intValue;
     223                i++;
     224                while (!strncmp(endp, ",", 1))
     225                    endp++;
     226                in = endp;
     227            } else
     228                i = MAXSTR;
     229        }
    333230        break;
    334     case PS_META_STR:
    335         psMetadataAdd(md, PS_LIST_TAIL, strName,
    336                       mdType | PS_META_DUPLICATE_OK,
    337                       NULL, strValue);
     231    case PS_DATA_F32:
     232        i = 0;
     233        float floatValue = 0.0;
     234        while (i < MAXSTR) {
     235            floatValue = strtof(in, &endp);
     236            if ( floatValue != 0.0 ) {
     237                inVector->data.F32[i] = floatValue;
     238                i++;
     239                while (!strncmp(endp, ",", 1))
     240                    endp++;
     241                in = endp;
     242            } else
     243                i = MAXSTR;
     244        }
     245
    338246        break;
    339     case PS_META_BOOL:
    340         tempBool = parseBool((char*)strValue, &status);
    341         if(!status) {
    342             psMetadataAdd(md, PS_LIST_TAIL, strName,
    343                           mdType | PS_META_DUPLICATE_OK,
    344                           NULL, tempBool);
    345         } else {
    346             status = 0;
    347             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
    348                     lineNumber, fileName);
    349         }
    350         break;
    351     case PS_META_S32:
    352         tempInt = (psS32)parseValue((char*)strValue, &status);
    353         if(!status) {
    354             psMetadataAdd(md, PS_LIST_TAIL, strName,
    355                           mdType | PS_META_DUPLICATE_OK,
    356                           NULL, tempInt);
    357         } else {
    358             status = 0;
    359             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
    360                     lineNumber, fileName);
    361         }
    362         break;
    363     case PS_META_F32:
    364     case PS_META_F64:
    365         tempDbl = parseValue((char*)strValue, &status);
    366         if(!status) {
    367             psMetadataAdd(md, PS_LIST_TAIL, strName,
    368                           mdType | PS_META_DUPLICATE_OK,
    369                           NULL, tempDbl);
    370         } else {
    371             status = 0;
    372             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
    373                     lineNumber, fileName);
     247    case PS_DATA_F64:
     248        i = 0;
     249        double doubleValue = 0.0;
     250        while (i < MAXSTR) {
     251            doubleValue = strtod(in, &endp);
     252            if ( doubleValue != 0.0 ) {
     253                inVector->data.F64[i] = doubleValue;
     254                i++;
     255                while (!strncmp(endp, ",", 1))
     256                    endp++;
     257                in = endp;
     258            } else
     259                i = MAXSTR;
    374260        }
    375261        break;
    376262    default:
    377         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
    378     } // End switch
    379 
    380     return;
    381 }
    382 
    383 
    384 static void initVectorXml(void *ctx, char *tagName)
    385 {
    386     bool overwrite = false;
    387     psS32 status = 0;
    388     psU32 lineNumber = 0;
    389     psElemType pType = 0;
    390     char *strName = NULL;
    391     char *strType = NULL;
    392     char *strValue = NULL;
    393     char *fileName = NULL;
    394     psMetadataItem *table = NULL;
    395     psMetadataItem *tables = NULL;
    396     psMetadataItem *metadataItem = NULL;
    397     psVector *vec = NULL;
    398     psMetadata* md = NULL;
    399     psHash* htAtts = NULL;
    400     xmlParserCtxtPtr ctxt = NULL;
    401     xmlParserInputPtr input = NULL;
    402 
    403 
    404     // Get and check initial data pointers
    405     ctxt = (xmlParserCtxtPtr)ctx;
    406     PS_ASSERT_GENERAL_PTR_NON_NULL(ctxt, return);
    407     md = (psMetadata*)ctxt->sax->_private;
    408     PS_ASSERT_GENERAL_PTR_NON_NULL(md, return);
    409     input = (xmlParserInputPtr)ctxt->input;
    410     PS_ASSERT_GENERAL_PTR_NON_NULL(input, return);
    411     tables = psMetadataLookup(md, "htAtts");
    412     PS_ASSERT_GENERAL_PTR_NON_NULL(tables, return);
    413     PS_ASSERT_GENERAL_PTR_NON_NULL(tables->data.list, return);
    414     table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
    415     htAtts = (psHash*)table->data.list;
    416     PS_ASSERT_GENERAL_PTR_NON_NULL(htAtts, return);
    417     fileName = (char*)input->filename;
    418     PS_ASSERT_GENERAL_PTR_NON_NULL(fileName, return);
    419     lineNumber = input->line;
    420 
    421     // Get attribute name
    422     strName = psHashLookup(htAtts, "name");
    423     if(strName == NULL) {
    424         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
    425         return;
    426     }
    427 
    428     // Get attribute type, if there is one
    429     strType = psHashLookup(htAtts, "psType");
    430     if(strType!= NULL) {
    431         if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
    432             pType = PS_TYPE_U8;
    433         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
    434             pType = PS_TYPE_S32;
    435         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
    436             pType = PS_TYPE_F32;
    437         } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
    438             pType = PS_TYPE_F64;
     263        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     264                PS_ERRORTEXT_psXML_INVALID_DATATYPE);
     265    }
     266}
     267
     268//Check the xml item for errors.  Returns the data type or PS_DATA_UNKNOWN for errors.//
     269static psDataType chkType(xmlNode *node)
     270{
     271    //NEED TO CHECK CONTENTS OF EACH ITEM/NODE //
     272    //if item then,
     273    if(!strncmp(node->name, "item", MAXSTR) || !strncmp(node->name, "ITEM", MAXSTR)) {
     274        if (node->properties != NULL && node->properties->name != NULL
     275                && node->properties->next != NULL && node->properties->next->name != NULL
     276                && node->properties->next->next != NULL
     277                && node->properties->next->next->name != NULL) {
     278            psDataType type = getType(node->properties->next->children->content);
     279            return type;
    439280        } else {
    440             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strName, lineNumber,
    441                     fileName);
    442             return;
    443         }
    444     }
    445 
    446     strValue = psHashLookup(htAtts, "value");
    447     PS_ASSERT_GENERAL_PTR_NON_NULL(strValue, return);
    448 
    449 
    450     /* If metadata item is found, and is not a folder node, and overwrite is allowed, then remove
    451     existing and allow switch/case below to add new item. If overwrite is false, then report error. If
    452     found item is folder node, then psMetadataAdd will automatically add a new child. */
    453     metadataItem = psMetadataLookup(md, "overwrite");
    454     if(metadataItem != NULL) {
    455         overwrite = parseBool((char*)strValue, &status);
    456         if(status) {
    457             status = 0;
    458             psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
    459                     input->line, input->filename);
    460         }
    461         metadataItem = psMetadataLookup(md, strName);
    462         if(metadataItem != NULL) {
    463             if(metadataItem->type != PS_META_LIST) {
    464                 if(overwrite) {
    465                     psMetadataRemove(md, INT_MIN, strName);
    466                 } else {
    467                     psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
    468                             fileName);
    469                     return;
     281            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     282                    PS_ERRORTEXT_psXML_INVALID_CONTENT);
     283            return(PS_DATA_UNKNOWN);
     284        }
     285    }
     286    //if vector then,
     287    if(!strncmp(node->name, "vector", MAXSTR) || !strncmp(node->name, "VECTOR", MAXSTR)) {
     288        if (node->properties != NULL && node->properties->name != NULL
     289                && node->properties->next != NULL && node->properties->next->name != NULL
     290                && node->properties->next->next != NULL
     291                && node->properties->next->next->name != NULL) {
     292            return(PS_DATA_VECTOR);
     293        } else {
     294            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     295                    PS_ERRORTEXT_psXML_INVALID_CONTENT);
     296            return(PS_DATA_UNKNOWN);
     297        }
     298
     299    }
     300    //if metadata then,
     301    if(!strncmp(node->name, "metadata", MAXSTR)) {
     302        if (node->properties != NULL && node->properties->name
     303                && node->properties->next != NULL && node->properties->next->name != NULL) {
     304            return(PS_DATA_METADATA);
     305        } else {
     306            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     307                    PS_ERRORTEXT_psXML_INVALID_CONTENT);
     308            return(PS_DATA_UNKNOWN);
     309        }
     310    }
     311    return(PS_DATA_UNKNOWN);
     312}
     313
     314//Sorts the xmlDocPtr data into a usable Metadata structure.  Transverses an xml tree.//
     315static psMetadata *xml2metadata(xmlNode *nodePtr, int nodeNum)
     316{
     317    psMetadata *meta = NULL;
     318    xmlNode *cur_node = NULL;
     319    char name[MAXSTR];
     320    char content[MAXSTR];
     321    //    char *name = NULL;
     322    //    char *content = NULL;
     323    psDataType type = PS_DATA_UNKNOWN;
     324    psDataType elemType = PS_DATA_UNKNOWN;
     325
     326    meta = psMetadataAlloc();
     327    cur_node = nodePtr;
     328
     329    //    for ( cur_node = nodePtr; cur_node != NULL; cur_node = cur_node->next )
     330    while (cur_node != NULL) {
     331        if ( cur_node->type == XML_ELEMENT_NODE ) {
     332            //if the root node isn't a metadata//
     333            if ( nodeNum == 0 && strncmp(cur_node->name, "metadata", MAXSTR) ) {
     334                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     335                        PS_ERRORTEXT_psXML_INVALID_CONTENT);
     336                psFree(meta);
     337                return NULL;
     338            }
     339
     340            if ( nodeNum != 0 ) {
     341                type = chkType(cur_node);
     342                //name = NULL;
     343                //content = NULL;
     344                switch ( type ) {
     345                case PS_DATA_S32:
     346                    strncpy(name, (char*)cur_node->properties->children->content, MAXSTR);
     347                    strncpy(content,
     348                            (char*)cur_node->properties->next->next->children->content, MAXSTR);
     349                    psMetadataAddS32(meta, PS_LIST_TAIL, name, "",
     350                                     (int)strtol(content, NULL, 10));
     351                    break;
     352                case PS_DATA_F32:
     353                    strncpy(name, cur_node->properties->children->content, MAXSTR);
     354                    strncpy(content,
     355                            cur_node->properties->next->next->children->content, MAXSTR);
     356                    psMetadataAddF32(meta, PS_LIST_TAIL, name, "", strtof(content, NULL));
     357                    break;
     358                case PS_DATA_F64:
     359                    strncpy(name, cur_node->properties->children->content, MAXSTR);
     360                    strncpy(content,
     361                            cur_node->properties->next->next->children->content, MAXSTR);
     362                    psMetadataAddF64(meta, PS_LIST_TAIL, name, "", strtod(content, NULL));
     363                    break;
     364                case PS_DATA_STRING:
     365                    strncpy(name, cur_node->properties->children->content, MAXSTR);
     366                    psMetadataAddStr(meta, PS_LIST_TAIL, name, "",
     367                                     cur_node->properties->next->next->children->content);
     368                    break;
     369                case PS_DATA_VECTOR:
     370                    strncpy(name, cur_node->properties->children->content, MAXSTR);
     371                    strncpy(content,
     372                            cur_node->properties->next->next->children->content, MAXSTR);
     373                    elemType = getType(cur_node->properties->next->children->content);
     374                    if (elemType == PS_DATA_UNKNOWN || elemType == PS_DATA_STRING
     375                            || elemType == PS_DATA_BOOL) {
     376                        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     377                                PS_ERRORTEXT_psXML_INVALID_DATATYPE);
     378                        psFree(meta);
     379                        return NULL;
     380                    }
     381
     382                    psVector *vec = psVectorAlloc(strlen(content), elemType);
     383                    storeValues(vec, content, elemType);
     384                    psMetadataAddVector(meta, PS_LIST_TAIL, name, "", vec);
     385                    psFree(vec);
     386                    break;
     387                case PS_DATA_METADATA:
     388                    strncpy(name, cur_node->properties->children->content, MAXSTR);
     389                    //                        psMetadata *temp = psMetadataAlloc();
     390                    psMetadata *temp = NULL;
     391                    temp = xml2metadata(cur_node->children, nodeNum);
     392                    psMetadataAddMetadata(meta, PS_LIST_TAIL, name, "", temp);
     393                    psFree(temp);
     394                    break;
     395                case PS_DATA_BOOL:
     396                    strncpy(name, cur_node->properties->children->content, MAXSTR);
     397                    strncpy(content,
     398                            cur_node->properties->next->next->children->content, MAXSTR);
     399                    if ( !strncmp(content, "true", MAXSTR) ||
     400                            !strncmp(content, "TRUE", MAXSTR) ||
     401                            !strncmp(content, "T", MAXSTR) ||
     402                            !strncmp(content, "t", MAXSTR) ) {
     403                        psMetadataAddBool(meta, PS_LIST_TAIL, name, "", true);
     404                    } else if ( !strncmp(content, "false", MAXSTR) ||
     405                                !strncmp(content, "FALSE", MAXSTR) ||
     406                                !strncmp(content, "F", MAXSTR) ||
     407                                !strncmp(content, "f", MAXSTR) ) {
     408                        psMetadataAddBool(meta, PS_LIST_TAIL, name, "", false);
     409                    } else {
     410                        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     411                                PS_ERRORTEXT_psXML_INVALID_CONTENT);
     412                        psFree(meta);
     413                        return NULL;
     414                    }
     415                    break;
     416                case PS_DATA_UNKNOWN:
     417                default:
     418                    psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     419                            PS_ERRORTEXT_psXML_INVALID_DATATYPE);
     420                    psFree(meta);   //XXX: Do I really need this?
     421                    return NULL;
    470422                }
     423                nodeNum++;
     424            } else //if root node, then increment nodeNum and go to children//
     425            {
     426                nodeNum++;
     427                cur_node = cur_node->children;
    471428            }
    472429        }
    473     }
    474 
    475     // Get value
    476     vec = parseVector((char*)strValue, pType, &status);
    477     if(!status) {
    478         psMetadataAdd(md, PS_LIST_TAIL, strName+1,
    479                       PS_META_VEC | PS_META_DUPLICATE_OK,
    480                       NULL, vec);
    481     } else {
    482         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
    483                 lineNumber, fileName);
    484     }
    485     psFree(vec);
    486 }
    487 
    488 static void saxEndElement(void *ctx, const xmlChar *tagName)
    489 {
    490     char *psStartTagName = NULL;
    491     char *psEndTagName = NULL;
    492     psMetadata* md = NULL;
    493     psHash* htAtts = NULL;
    494     psMetadataItem *table = NULL;
    495     psMetadataItem *tables = NULL;
    496     xmlParserCtxtPtr ctxt = NULL;
    497     xmlParserInputPtr input = NULL;
    498 
    499 
    500     // Get and check initial data pointers
    501     ctxt = (xmlParserCtxtPtr)ctx;
    502     PS_ASSERT_GENERAL_PTR_NON_NULL(ctxt, return);
    503     md = (psMetadata*)ctxt->sax->_private;
    504     PS_ASSERT_GENERAL_PTR_NON_NULL(md, return);
    505     input = (xmlParserInputPtr)ctxt->input;
    506     PS_ASSERT_GENERAL_PTR_NON_NULL(input, return);
    507     tables = psMetadataLookup(md, "htAtts");
    508     PS_ASSERT_GENERAL_PTR_NON_NULL(tables, return);
    509     PS_ASSERT_GENERAL_PTR_NON_NULL(tables->data.list, return);
    510     table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
    511     htAtts = (psHash*)table->data.list;
    512     PS_ASSERT_GENERAL_PTR_NON_NULL(htAtts, return);
    513 
    514     // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
    515     psEndTagName = psStringCopy((const char*)tagName);
    516 
    517     // Compare start and end tag names
    518     psStartTagName = psHashLookup(htAtts, "tagName");
    519     PS_ASSERT_GENERAL_PTR_NON_NULL(psStartTagName, return);
    520     if(strcmp(psEndTagName, psStartTagName)) {
    521         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH, psStartTagName, psEndTagName);
    522     }
    523 
    524     // Initialize psLib structs
    525     if(!strcmp(psEndTagName, "psMetadataItem")) {
    526         initMetadataItemXml(ctx, psEndTagName);
    527     } else if(!strcmp(psEndTagName, "psVector")) {
    528         initVectorXml(ctx, psEndTagName);
    529     } else if(strcmp(psEndTagName, "psRoot")) {
    530         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN, psEndTagName);
    531     }
    532 
    533     // Free temporary metadata item and its hash table
    534     psListRemove(tables->data.list, PS_LIST_TAIL);
    535 
    536     psFree(psEndTagName);
    537 
    538     return;
    539 }
    540 
    541 psMetadata*  psMetadataConfigParseXml(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
    542 {
    543     xmlSAXHandler saxHandler;
    544 
    545 
    546     // Error checks
    547     PS_ASSERT_PTR_NON_NULL(fileName, NULL);
    548 
    549     // Allocate metadata if necessary
    550     if (md == NULL) {
    551         md = psMetadataAlloc();
    552     }
    553 
    554     // Sax handler initializations
    555     saxHandler.internalSubset           = NULL;
    556     saxHandler.isStandalone             = NULL;
    557     saxHandler.hasInternalSubset        = NULL;
    558     saxHandler.hasExternalSubset        = NULL;
    559     saxHandler.resolveEntity            = NULL;
    560     saxHandler.getEntity                = NULL;
    561     saxHandler.entityDecl               = NULL;
    562     saxHandler.notationDecl             = NULL;
    563     saxHandler.attributeDecl            = NULL;
    564     saxHandler.elementDecl              = NULL;
    565     saxHandler.unparsedEntityDecl       = NULL;
    566     saxHandler.setDocumentLocator       = NULL;
    567     saxHandler.startDocument            = NULL;
    568     saxHandler.endDocument              = NULL;
    569     saxHandler.startElement             = saxStartElement;
    570     saxHandler.endElement               = saxEndElement;
    571     saxHandler.reference                = NULL;
    572     saxHandler.characters               = NULL;
    573     saxHandler.ignorableWhitespace      = NULL;
    574     saxHandler.processingInstruction    = NULL;
    575     saxHandler.comment                  = NULL;
    576     saxHandler.warning                  = xmlParserError;
    577     saxHandler.error                    = xmlParserError;
    578     saxHandler.fatalError               = xmlParserError;
    579     saxHandler.getParameterEntity       = NULL;
    580     saxHandler.cdataBlock               = NULL;
    581     saxHandler.externalSubset           = NULL;
    582     saxHandler.initialized              = 1;
    583     saxHandler._private                 = md;
    584     saxHandler.startElementNs           = NULL;
    585     saxHandler.endElementNs             = NULL;
    586     saxHandler.serror                   = NULL;
    587 
    588     // Parse XML file
    589     if (xmlSAXUserParseFile(&saxHandler, NULL, fileName)) {
    590         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
    591         return NULL;
    592     }
    593 
    594     // Parser and memory cleanups for libxml2
     430        cur_node = cur_node->next;
     431    }
     432    psFree(cur_node);
     433    return meta;
     434}
     435
     436psMetadata *psXMLDocToMetadata(const psXMLDoc *doc)
     437{
     438    PS_ASSERT_PTR_NON_NULL(doc, NULL);
     439    //    psMetadata *md = psMetadataAlloc();
     440    psMetadata *md = NULL;
     441    xmlNode *root_element = NULL;
     442    //XXX: doc changed to *doc
     443    root_element = xmlDocGetRootElement(*doc);
     444    md = xml2metadata(root_element, 0);
     445    return md;
     446}
     447
     448psXMLDoc *psXMLParseFile(const char *filename)
     449{
     450
     451    PS_ASSERT_PTR_NON_NULL(filename, NULL);
     452    psXMLDoc *XML;
     453    XML = psXMLDocAlloc();
     454    *XML = xmlReadFile(filename, NULL, 0);
     455
    595456    xmlCleanupParser();
    596457    xmlMemoryDump();
    597 
    598     return md;
    599 }
     458    return XML;
     459}
     460
     461bool psXMLDocToFile(const psXMLDoc *doc,
     462                    const char *filename)
     463{
     464    PS_ASSERT_PTR_NON_NULL(doc, 0);
     465    PS_ASSERT_PTR_NON_NULL(filename, 0);
     466    FILE *file;
     467    if( (file = fopen(filename, "w")) == NULL ) {
     468        psError(PS_ERR_IO, true, PS_ERRORTEXT_psXML_IO_FILE_OPEN_FAILED, filename);
     469        return false;
     470    }
     471
     472    xmlDocDump(file, *doc);
     473    fclose(file);
     474    return true;
     475}
     476
     477psXMLDoc *psXMLParseMem(const char *buffer,
     478                        int size)
     479{
     480    PS_ASSERT_PTR_NON_NULL(buffer, NULL);
     481    PS_ASSERT_INT_NONZERO(size, NULL);
     482    char *URL = "new.xml";
     483    psXMLDoc *XML;
     484    XML = psXMLDocAlloc();
     485    *XML = xmlReadMemory(buffer, size, URL, NULL, 0);
     486
     487    xmlCleanupParser();
     488    xmlMemoryDump();
     489
     490    return XML;
     491}
     492
     493bool psXMLDocToMem(const psXMLDoc *doc,
     494                   char *buffer)
     495{
     496    PS_ASSERT_PTR_NON_NULL(doc, 0);
     497    int bufferSize;
     498    xmlChar *buff;
     499
     500    xmlDocDumpMemory(*doc, &buff, &bufferSize);
     501    if ( MAXVEC < strlen((char *)buff) ) {
     502        psError(PS_ERR_LOCATION_INVALID, true, PS_ERRORTEXT_psXML_BUFFER_TOO_SMALL);
     503        //        xmlFree(buff);
     504        return false;
     505    }
     506    strncpy(buffer, buff, MAXVEC);
     507    xmlFree(buff);
     508
     509    return true;
     510}
     511
     512psXMLDoc *psXMLParseFD(int fd)
     513{
     514    PS_ASSERT_INT_NONNEGATIVE(fd, NULL);
     515    char *URL = "new.xml";
     516    psXMLDoc *XML;
     517    XML = psXMLDocAlloc();
     518    *XML = xmlReadFd(fd, URL, NULL, 0);
     519
     520    xmlCleanupParser();
     521    xmlMemoryDump();
     522
     523    return XML;
     524}
     525
     526bool psXMLDocToFD(const psXMLDoc *doc,
     527                  int fd)
     528{
     529    PS_ASSERT_PTR_NON_NULL(doc, 0);
     530    PS_ASSERT_INT_NONNEGATIVE(fd, 0);
     531
     532    char buf[MAXBUF];
     533    int n;
     534    if ( psXMLDocToMem(doc, buf) ) {
     535        n = strlen(buf);
     536        write(fd, buf, n);
     537    } else {
     538        psError(PS_ERR_LOCATION_INVALID, true, PS_ERRORTEXT_psXML_BUFFER_TOO_SMALL);
     539        return false;
     540    }
     541    return true;
     542}
  • trunk/psLib/src/xml/psXML.h

    r4540 r4786  
    11/** @file  psXML.h
    22 *
    3  *  @brief Contains XML functions.
     3 *  @brief Contains basic XML definitions and operations
    44 *
    5  *  This file defines functions to read metadata from an XML file.
     5 *  This file defines the basic type for an XML struct and functions useful
     6 *  in creation and usage of XML documents/files.
    67 *
    78 *  @ingroup XML
    89 *
    9  *  @author Ross Harman, MHPCC
    10  *  @author Robert DeSonia, MHPCC
     10 *  @author David Robbins, MHPCC
    1111 *
    12  *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2005-07-12 19:12:01 $
     12 *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2005-08-16 20:13:20 $
    1414 *
    15  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     15 *  Copyright 2005 Maui High Performance Computing Center, University of Hawaii
    1616 */
     17
    1718#ifndef PS_XML_H
    1819#define PS_XML_H
    1920
     21//#include <libxml/parser.h>
     22#include <libxml/tree.h>
     23#include <string.h>
     24#include <ctype.h>
     25#include <limits.h>
     26
    2027#include "psMetadata.h"
    2128#include "psMetadataConfig.h"
     29#include "psMemory.h"
     30#include "psError.h"
     31#include "psString.h"
     32#include "psConstants.h"
     33#include "psErrorText.h"
     34
    2235
    2336/// @addtogroup XML
    2437/// @{
    2538
    26 psMetadata*  psMetadataConfigParseXml(
    27     psMetadata* md,                    ///< Resulting metadata from read.
    28     psU32 *nFail,                      ///< Number of failed lines.
    29     const char *fileName,              ///< Name of file to read.
    30     psBool overwrite                   ///< Allow overwrite of duplicate specifications.
     39/** XML wrapper pointing to an XML document in memory */
     40typedef xmlDocPtr psXMLDoc;
     41
     42
     43/*****************************************************************************/
     44
     45/* FUNCTION PROTOTYPES                                                       */
     46
     47/*****************************************************************************/
     48
     49/** Allocates a new psXMLDoc
     50 *
     51 *  @return psXMLDoc*         a new psXMLDoc object
     52*/
     53psXMLDoc *psXMLDocAlloc(void);
     54
     55/** Converts a psMetadata data structure to a complete psXMLDoc (in memory)
     56 *
     57 *  @return psXMLDoc*           Pointer to XML document from read
     58*/
     59psXMLDoc *psMetadataToXMLDoc(
     60    const psMetadata *md               ///< psMetadata structure to read
     61);
     62
     63/** Converts a complete psXMLDoc (in memory) to a psMetadata data structure
     64 *
     65 *  @return psMetadata*         Pointer to psMetadata data structure from read
     66*/
     67psMetadata *psXMLDocToMetadata(
     68    const psXMLDoc *doc                ///< psXMLDoc to read
     69);
     70
     71/** Loads the data in a named file into a complete psXMLDoc (in memory)
     72 *
     73 *  @return psXMLDoc*       Pointer to resulting XML document from read
     74*/
     75psXMLDoc *psXMLParseFile(
     76    const char *filename               ///< Filename of file to be read
     77);
     78
     79/** Writes out a complete psXMLDoc (in memory) to a named file
     80 *
     81 *  @return bool:       True on success or false otherwise.
     82*/
     83bool psXMLDocToFile(
     84    const psXMLDoc *doc,               ///< psXMLDoc to read
     85    const char *filename               ///< Filename of file to be written
     86);
     87
     88/** Accepts a block of memory and parses it into a complete psXMLDoc (also in memory)
     89 *
     90 *  @return psXMLDoc*       Pointer to resulting XML document from read
     91*/
     92psXMLDoc *psXMLParseMem(
     93    const char *buffer,                ///< Buffer to read
     94    int size                           ///< Size of buffer
     95);
     96
     97/** Accepts a complete psXMLDoc (in memory) and parses it into a block of memory
     98 *
     99 *  @return bool:       True on success or false otherwise.
     100*/
     101bool psXMLDocToMem(
     102    const psXMLDoc *doc,               ///< psXMLDoc to read
     103    char *buffer                       ///< Buffer to write
     104);
     105
     106/** Reads from a file descriptor and converts the incoming data to a complete
     107 *  psXMLDoc (in memory)
     108 *
     109 *  @return psXMLDoc*      Pointer to resulting XML document from read
     110*/
     111psXMLDoc *psXMLParseFD(
     112    int fd                             ///< File descriptor to read
     113);
     114
     115/** Reads from a complete psXMLDoc (in memory) and writes it to a file descriptor
     116 *
     117 *  @return bool:       True on success or false otherwise.
     118*/
     119bool psXMLDocToFD(
     120    const psXMLDoc *doc,               ///< psXMLDoc to read
     121    int fd                             ///< File descriptor to write
    31122);
    32123
     
    34125
    35126#endif // #ifndef PS_XML_H
     127
Note: See TracChangeset for help on using the changeset viewer.