Annotation of libwww/Library/src/HTXML.c, revision 2.2

2.1       frystyk     1: /*
                      2: **     LIBWWW STREAM WRAPPER FOR EXPAT XML PARSER
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.2     ! frystyk     6: **     @(#) $Id: HTXML.c,v 2.1 1999/01/08 14:55:01 frystyk Exp $
2.1       frystyk     7: **
                      8: **     This module requires expat in order to compile/link
                      9: */
                     10: 
                     11: /* Library include files */
                     12: #include "wwwsys.h"
                     13: #include "WWWUtil.h"
                     14: #include "WWWCore.h"
2.2     ! frystyk    15: #include "HTXML.h"                                      /* Implemented here */
        !            16: #include "SGML.h"
2.1       frystyk    17: 
2.2     ! frystyk    18: #define XML_MAX_ATTRIBUTES 50
2.1       frystyk    19: 
                     20: struct _HTStream {
                     21:     const HTStreamClass *      isa;
                     22:     int                                state;
                     23:     HTRequest *                        request;
2.2     ! frystyk    24:     HTStream *                  target;
        !            25:     HTStructuredClass *         actions;       
        !            26:     HTStructured *              starget;       
2.1       frystyk    27:     XML_Parser                         xmlstream;
2.2     ! frystyk    28:     SGML_dtd *                  dtd;
        !            29:     XML_StartElementHandler     xml_start_element;
        !            30:     XML_EndElementHandler       xml_end_element;
        !            31:     XML_CharacterDataHandler    xml_character_data;
        !            32:     XML_DefaultHandler          xml_default_handler;
        !            33:     void *                      xml_user_data;
2.1       frystyk    34: };
                     35: 
2.2     ! frystyk    36: PRIVATE HTXMLCallback_new *    newInstance = NULL;
        !            37: 
2.1       frystyk    38: /* ------------------------------------------------------------------------- */
                     39: 
                     40: PRIVATE int HTXML_flush (HTStream * me)
                     41: {
2.2     ! frystyk    42:     if(me->target)
        !            43:        return (*me->target->isa->flush)(me->target);
        !            44:     else if (me->starget)
        !            45:        return (*me->actions->flush)(me->starget);
        !            46:     return HT_OK;
2.1       frystyk    47: }
                     48: 
                     49: PRIVATE int HTXML_free (HTStream * me)
                     50: {
                     51:     int status = HT_OK;
                     52:     XML_ParserFree(me->xmlstream);
2.2     ! frystyk    53:     if (me->target) {
        !            54:        if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
        !            55:            return HT_WOULD_BLOCK;
        !            56:     } else if(me->starget) {
        !            57:       if ((status = (*me->actions->_free)(me->starget)) == HT_WOULD_BLOCK)
        !            58:            return HT_WOULD_BLOCK;
        !            59:     }
        !            60: 
2.1       frystyk    61:     if (STREAM_TRACE) HTTrace("XML Parser.. FREEING...\n");
                     62:     HT_FREE(me);
                     63:     return status;
                     64: }
                     65: 
                     66: PRIVATE int HTXML_abort (HTStream * me, HTList * e)
                     67: {
                     68:     if (STREAM_TRACE) HTTrace("XML Parser.. ABORTING...\n");
                     69:     XML_ParserFree(me->xmlstream);
2.2     ! frystyk    70:     if (me->target)    
        !            71:        (*me->target->isa->abort)(me->target, NULL);
        !            72:     else if (me->starget)      
        !            73:        (*me->actions->abort)(me->starget, e);
2.1       frystyk    74:     HT_FREE(me);
                     75:     return HT_ERROR;
                     76: }
                     77: 
                     78: PRIVATE int HTXML_write (HTStream * me, const char * buf, int len)
                     79: {
                     80:     if (me->state == HT_OK) {
                     81:        int status = XML_Parse(me->xmlstream, buf, len, 0);
                     82:        if (!status) {
2.2     ! frystyk    83:            HTTrace("XML Parser..  `%s\'\n",
        !            84:                    (char *)XML_ErrorString(XML_GetErrorCode(me->xmlstream)));
2.1       frystyk    85:            me->state = HT_ERROR;
                     86:        }
                     87:     }
                     88:     return me->state;
                     89: }
                     90: 
                     91: PRIVATE int HTXML_putCharacter (HTStream * me, char c)
                     92: {
                     93:     return HTXML_write(me, &c, 1);
                     94: }
                     95: 
                     96: PRIVATE int HTXML_putString (HTStream * me, const char * s)
                     97: {
                     98:     return HTXML_write(me, s, (int) strlen(s));
                     99: }
                    100: 
2.2     ! frystyk   101: PRIVATE BOOL set_attributes_values(HTTag *tag,BOOL *present,char **value,
        !           102:                                   const char *nameatt,const char *valueatt)
        !           103: {
        !           104:     if(tag && nameatt && valueatt) {
        !           105:        int i;
        !           106:        HTAttr *attributes= tag->attributes;
        !           107:        for(i = 0; i< tag->number_of_attributes ; i++) {
        !           108:            if(!strcasecomp(attributes[i].name,nameatt)) {
        !           109:                present[i] = TRUE;
        !           110:                value[i] = (char *)valueatt;
        !           111:                return TRUE;
        !           112:            }
        !           113:        }
        !           114:     }
        !           115:     return FALSE;
        !           116: }
        !           117: 
        !           118: PRIVATE void start_element(HTStream *  me,
        !           119:                           const XML_Char *name,
        !           120:                           const XML_Char **atts)
        !           121: {
        !           122:     int element_number = 
        !           123:        SGML_findElementNumber((SGML_dtd *)me->dtd,(char *)name);
        !           124:     if(element_number >= 0) {
        !           125:        HTTag *tag = SGML_findTag (me->dtd,element_number);
        !           126:        int i = 0;  
        !           127:        BOOL present[XML_MAX_ATTRIBUTES];
        !           128:        const char *value[XML_MAX_ATTRIBUTES];
        !           129:        memset((void *) present, '\0', XML_MAX_ATTRIBUTES);
        !           130:        memset((void *) value, '\0', XML_MAX_ATTRIBUTES*sizeof(char *));
        !           131: 
        !           132:        while(atts[i]) {
        !           133:           set_attributes_values(tag,present,(char **)value,atts[i],atts[i+1]);
        !           134:            i+=2;
        !           135:            /* attributes that are not in the dtd will be lost */
        !           136:        }
        !           137:        (*me->actions->start_element)
        !           138:            (me->starget,element_number,present,value); 
        !           139:     } else {
        !           140:        /* elements that are not in the dtd will be lost */     
        !           141:     }
        !           142: }
        !           143: 
        !           144: PRIVATE void end_element(HTStream * me, const XML_Char *name)
        !           145: {
        !           146:     int element_number = SGML_findElementNumber(me->dtd,(char *)name);
        !           147: 
        !           148:     if(element_number > 0) {
        !           149:        (*me->actions->end_element)(me->starget, element_number);
        !           150:     } else {
        !           151:        /* elements that are not in the dtd will be lost */     
        !           152:     }
        !           153: }
        !           154: PRIVATE void character_data(HTStream *me, const XML_Char *s, int len)
        !           155: {
        !           156:     (*me->actions->put_block)(me->starget, s, len);
        !           157: }
        !           158: 
        !           159: PRIVATE void default_handler(HTStream *me, const XML_Char *s, int len)
        !           160: {
        !           161:     if(s[0] == '&' && s[len-1]==';') {
        !           162:        (*me->actions->unparsed_entity)(me->starget, s,len);
        !           163:     } else {
        !           164:        /* characters that can not be parsed are lost */
        !           165:     }
        !           166: }
        !           167: 
2.1       frystyk   168: PRIVATE const HTStreamClass HTXMLClass =
                    169: {              
                    170:     "xml",
                    171:     HTXML_flush,
                    172:     HTXML_free,
                    173:     HTXML_abort,
                    174:     HTXML_putCharacter,
                    175:     HTXML_putString,
                    176:     HTXML_write
                    177: }; 
                    178: 
                    179: PUBLIC HTStream * HTXML_new (HTRequest *       request,
                    180:                             void *             param,
                    181:                             HTFormat           input_format,
                    182:                             HTFormat           output_format,
                    183:                             HTStream *         output_stream)
                    184: {
                    185:     HTStream * me = NULL;
                    186:     HTCharset charset = HTResponse_charset (HTRequest_response(request));
                    187:     if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
                    188:        HT_OUTOFMEM("HTXML_new");
                    189:     me->isa = &HTXMLClass;
                    190:     me->state = HT_OK;
                    191:     me->request = request;
                    192:     me->target = output_stream ? output_stream : HTErrorStream();
                    193: 
                    194:     /* Now create the XML parser instance */
                    195:     if ((me->xmlstream = XML_ParserCreate(HTAtom_name(charset))) == NULL) {
                    196:        HT_FREE(me);
                    197:        return HTErrorStream();
                    198:     }
                    199: 
                    200:     if (STREAM_TRACE) HTTrace("XML Parser.. Stream created\n");
2.2     ! frystyk   201:     
        !           202:     /* Call the stream callback handler (if any) with this new stream */
        !           203:     if (newInstance)
        !           204:        (*newInstance)(me, request, output_format, output_stream, me->xmlstream);
        !           205: 
2.1       frystyk   206:     return me;
2.2     ! frystyk   207: }
        !           208: 
        !           209: PUBLIC BOOL HTXMLCallback_registerNew (HTXMLCallback_new * me)
        !           210: {
        !           211:     newInstance = me;
        !           212:     return YES;
        !           213: }
        !           214: 
        !           215: PUBLIC HTStream * HTXMLStructured_new (const SGML_dtd * dtd, HTStructured * starget)
        !           216: {
        !           217:     HTStream * me = NULL;
        !           218:     if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
        !           219:        HT_OUTOFMEM("HTXML_new");
        !           220:     me->isa = &HTXMLClass;
        !           221:     me->state = HT_OK;
        !           222:     me->starget = starget;
        !           223:     me->dtd = (SGML_dtd *)dtd; 
        !           224:     me->actions = (HTStructuredClass*)(((HTStream*)starget)->isa);
        !           225: 
        !           226:     /* Now create the XML parser instance */
        !           227:     if ((me->xmlstream = XML_ParserCreate(NULL)) == NULL) {
        !           228:        HT_FREE(me);
        !           229:        return HTErrorStream();
        !           230:     }
        !           231:     XML_SetUserData(me->xmlstream,me);
        !           232:     XML_SetElementHandler(me->xmlstream,
        !           233:                          (XML_StartElementHandler)start_element, 
        !           234:                          (XML_EndElementHandler)end_element);
        !           235:     XML_SetCharacterDataHandler(me->xmlstream,  
        !           236:                                (XML_CharacterDataHandler)character_data);
        !           237:     XML_SetDefaultHandler(me->xmlstream,
        !           238:                          (XML_DefaultHandler)default_handler);
        !           239: 
        !           240:     if (STREAM_TRACE) HTTrace("XML Parser.. Stream created\n");
        !           241:     return me;
        !           242: }
        !           243: 
        !           244: PUBLIC BOOL HTXMLStructured_setHandlers (HTStream *                    me,
        !           245:                                         XML_StartElementHandler        start,
        !           246:                                         XML_EndElementHandler          end, 
        !           247:                                         XML_CharacterDataHandler       char_data,
        !           248:                                         XML_DefaultHandler             def_handler)
        !           249: {
        !           250:     if(me) {
        !           251:        me->xml_start_element = start;
        !           252:        me->xml_end_element = end;
        !           253:        me->xml_character_data = char_data;
        !           254:        me->xml_default_handler = def_handler;
        !           255:        XML_SetElementHandler(me->xmlstream,start,end);
        !           256:        XML_SetCharacterDataHandler(me->xmlstream,char_data);
        !           257:        XML_SetDefaultHandler(me->xmlstream,def_handler);
        !           258:        return YES;
        !           259:     }
        !           260:     return NO;
        !           261: }
        !           262:                        
        !           263: PUBLIC BOOL HTXMLStructured_setUserData(HTStream *me, void *user_data)
        !           264: {
        !           265:     if(me) {
        !           266:        me->xml_user_data = user_data;
        !           267:        XML_SetUserData(me->xmlstream,me->xml_user_data);
        !           268:        return YES;
        !           269:     }
        !           270:     return NO;
2.1       frystyk   271: }

Webmaster