📄 htxml.c
字号:
/*** LIBWWW STREAM WRAPPER FOR EXPAT XML PARSER**** (c) COPYRIGHT MIT 1995.** Please first read the full copyright statement in the file COPYRIGH.** @(#) $Id: HTXML.c,v 2.9 2000/12/19 08:53:43 kahan Exp $**** This module requires expat in order to compile/link*//* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "WWWCore.h"/* 2000-29-08 JK : pre-pruning code out of libwww */#ifdef HT_STRUCT_XML_STREAM #undef HT_STRUCT_XML_STREAM#endif#ifdef HT_STRUCT_XML_STREAM#include "SGML.h"#endif /* HT_STRUCT_XML_STREAM */#include "HTXML.h" /* Implemented here */#define XML_MAX_ATTRIBUTES 50struct _HTStream { const HTStreamClass * isa; int state; HTRequest * request; HTStream * target; HTStructuredClass * actions; HTStructured * starget; XML_Parser xmlstream;#ifdef HT_STRUCT_XML_STREAM SGML_dtd * dtd;#endif /* HT_STRUCT_XML_STREAM */ XML_StartElementHandler xml_start_element; XML_EndElementHandler xml_end_element; XML_CharacterDataHandler xml_character_data; XML_DefaultHandler xml_default_handler; void * xml_user_data;};/* @@@ SHould not be global but controlled by name spaces @@@ */PRIVATE HTXMLCallback_new * XMLInstance = NULL;PRIVATE void * XMLInstanceContext = NULL;/* ------------------------------------------------------------------------- */PRIVATE int HTXML_flush (HTStream * me){ if(me->target) return (*me->target->isa->flush)(me->target); else if (me->starget) return (*me->actions->flush)(me->starget); return HT_OK;}PRIVATE int HTXML_free (HTStream * me){ int status = HT_OK; XML_ParserFree(me->xmlstream); if (me->target) { if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK) return HT_WOULD_BLOCK; } else if(me->starget) { if ((status = (*me->actions->_free)(me->starget)) == HT_WOULD_BLOCK) return HT_WOULD_BLOCK; } HTTRACE(XML_TRACE, "XML Parser.. FREEING...\n"); HT_FREE(me); return status;}PRIVATE int HTXML_abort (HTStream * me, HTList * e){ HTTRACE(XML_TRACE, "XML Parser.. ABORTING...\n"); XML_ParserFree(me->xmlstream); if (me->target) (*me->target->isa->abort)(me->target, NULL); else if (me->starget) (*me->actions->abort)(me->starget, e); HT_FREE(me); return HT_ERROR;}PRIVATE int HTXML_write (HTStream * me, const char * buf, int len){ if (me->state == HT_OK) { int status = XML_Parse(me->xmlstream, buf, len, 0); if (!status) { HTTRACE(XML_TRACE, "XML Parser.. `%s\'\n" _ (char *)XML_ErrorString(XML_GetErrorCode(me->xmlstream))); me->state = HT_ERROR; } } /* ** We don't want to return an error here as this kills ** a potential pipeline of requests we might have */ return HT_OK;}PRIVATE int HTXML_putCharacter (HTStream * me, char c){ return HTXML_write(me, &c, 1);}PRIVATE int HTXML_putString (HTStream * me, const char * s){ return HTXML_write(me, s, (int) strlen(s));}#ifdef HT_STRUCT_XML_STREAMPRIVATE BOOL set_attributes_values(HTTag *tag,BOOL *present,char **value, const char *nameatt,const char *valueatt){ if(tag && nameatt && valueatt) { int i; HTAttr *attributes= tag->attributes; for(i = 0; i< tag->number_of_attributes ; i++) { if(!strcasecomp(attributes[i].name,nameatt)) { present[i] = TRUE; value[i] = (char *)valueatt; return TRUE; } } } return FALSE;}PRIVATE void start_element(HTStream * me, const XML_Char *name, const XML_Char **atts){ int element_number = SGML_findElementNumber((SGML_dtd *)me->dtd,(char *)name); if(element_number >= 0) { HTTag *tag = SGML_findTag (me->dtd,element_number); int i = 0; BOOL present[XML_MAX_ATTRIBUTES]; const char *value[XML_MAX_ATTRIBUTES]; memset((void *) present, '\0', XML_MAX_ATTRIBUTES); memset((void *) value, '\0', XML_MAX_ATTRIBUTES*sizeof(char *)); while(atts[i]) { set_attributes_values(tag,present,(char **)value,atts[i],atts[i+1]); i+=2; /* attributes that are not in the dtd will be lost */ } (*me->actions->start_element) (me->starget,element_number,present,value); } else { /* elements that are not in the dtd will be lost */ }}PRIVATE void end_element(HTStream * me, const XML_Char *name){ int element_number = SGML_findElementNumber(me->dtd,(char *)name); if(element_number > 0) { (*me->actions->end_element)(me->starget, element_number); } else { /* elements that are not in the dtd will be lost */ }}PRIVATE void character_data(HTStream *me, const XML_Char *s, int len){ (*me->actions->put_block)(me->starget, s, len);}PRIVATE void default_handler(HTStream *me, const XML_Char *s, int len){ if(s[0] == '&' && s[len-1]==';') { (*me->actions->unparsed_entity)(me->starget, s,len); } else { /* characters that can not be parsed are lost */ }}#endif /* HT_STRUCT_XML_STREAM */PRIVATE const HTStreamClass HTXMLClass ={ "xml", HTXML_flush, HTXML_free, HTXML_abort, HTXML_putCharacter, HTXML_putString, HTXML_write}; PUBLIC HTStream * HTXML_new (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream){ HTStream * me = NULL; HTCharset charset = HTResponse_charset (HTRequest_response(request)); if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTXML_new"); me->isa = &HTXMLClass; me->state = HT_OK; me->request = request; me->target = output_stream ? output_stream : HTErrorStream(); /* Now create the XML parser instance */ if ((me->xmlstream = XML_ParserCreate(HTAtom_name(charset))) == NULL) { HT_FREE(me); return HTErrorStream(); } HTTRACE(XML_TRACE, "XML Parser.. Stream created\n"); /* Call the stream callback handler (if any) with this new stream */ if (XMLInstance) (*XMLInstance)(me, request, output_format, output_stream, me->xmlstream, XMLInstanceContext); return me;}PUBLIC BOOL HTXMLCallback_registerNew (HTXMLCallback_new * me, void * context){ XMLInstance = me; XMLInstanceContext = context; return YES;}#ifdef HT_STRUCT_XML_STREAMPRIVATE HTStream * HTXMLStructured_new (const SGML_dtd * dtd, HTStructured * starget){ HTStream * me = NULL; if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTXML_new"); me->isa = &HTXMLClass; me->state = HT_OK; me->starget = starget; me->dtd = (SGML_dtd *)dtd; me->actions = (HTStructuredClass*)(((HTStream*)starget)->isa); /* Now create the XML parser instance */ if ((me->xmlstream = XML_ParserCreate(NULL)) == NULL) { HT_FREE(me); return HTErrorStream(); } XML_SetUserData(me->xmlstream,me); XML_SetElementHandler(me->xmlstream, (XML_StartElementHandler)start_element, (XML_EndElementHandler)end_element); XML_SetCharacterDataHandler(me->xmlstream, (XML_CharacterDataHandler)character_data); XML_SetDefaultHandler(me->xmlstream, (XML_DefaultHandler)default_handler); HTTRACE(XML_TRACE, "XML Parser.. Stream created\n"); return me;}PRIVATE BOOL HTXMLStructured_setHandlers (HTStream * me, XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler char_data, XML_DefaultHandler def_handler){ if(me) { me->xml_start_element = start; me->xml_end_element = end; me->xml_character_data = char_data; me->xml_default_handler = def_handler; XML_SetElementHandler(me->xmlstream,start,end); XML_SetCharacterDataHandler(me->xmlstream,char_data); XML_SetDefaultHandler(me->xmlstream,def_handler); return YES; } return NO;} PRIVATE BOOL HTXMLStructured_setUserData(HTStream *me, void *user_data){ if(me) { me->xml_user_data = user_data; XML_SetUserData(me->xmlstream,me->xml_user_data); return YES; } return NO;}#endif /* HT_STRUCT_XML_STREAM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -