⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparse.c

📁 web browser
💻 C
📖 第 1 页 / 共 5 页
字号:
	    if (!tag->buf)	      return XML_ERROR_NO_MEMORY;	    tag->bufEnd = tag->buf + bufSize;	  }	  memcpy(tag->buf, tag->rawName, tag->rawNameLength);	  tag->rawName = tag->buf;	}	++tagLevel;	if (startElementHandler) {	  enum XML_Error result;	  XML_Char *toPtr;	  for (;;) {	    const char *rawNameEnd = tag->rawName + tag->rawNameLength;	    const char *fromPtr = tag->rawName;	    int bufSize;	    if (nextPtr)	      toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));	    else	      toPtr = (XML_Char *)tag->buf;	    tag->name = toPtr;	    XmlConvert(enc,		       &fromPtr, rawNameEnd,		       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);	    if (fromPtr == rawNameEnd)	      break;	    bufSize = (tag->bufEnd - tag->buf) << 1;	    tag->buf = realloc(tag->buf, bufSize);	    if (!tag->buf)	      return XML_ERROR_NO_MEMORY;	    tag->bufEnd = tag->buf + bufSize;	    if (nextPtr)	      tag->rawName = tag->buf;	  }	  *toPtr = XML_T('\0');	  result = storeAtts(parser, enc, tag->name, s);	  if (result)	    return result;	  startElementHandler(handlerArg, tag->name, (const XML_Char **)atts);	  poolClear(&tempPool);	}	else {	  tag->name = 0;	  if (defaultHandler)	    reportDefault(parser, enc, s, next);	}	break;      }    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:      if (!startElementHandler) {	enum XML_Error result = storeAtts(parser, enc, 0, s);	if (result)	  return result;      }      /* fall through */    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:      if (startElementHandler || endElementHandler) {	const char *rawName = s + enc->minBytesPerChar;	const XML_Char *name = poolStoreString(&tempPool, enc, rawName,					       rawName					       + XmlNameLength(enc, rawName));	if (!name)	  return XML_ERROR_NO_MEMORY;	poolFinish(&tempPool);	if (startElementHandler) {	  enum XML_Error result = storeAtts(parser, enc, name, s);	  if (result)	    return result;	  startElementHandler(handlerArg, name, (const XML_Char **)atts);	}	if (endElementHandler) {	  if (startElementHandler)	    *eventPP = *eventEndPP;	  endElementHandler(handlerArg, name);	}	poolClear(&tempPool);      }      else if (defaultHandler)	reportDefault(parser, enc, s, next);      if (tagLevel == 0)	return epilogProcessor(parser, next, end, nextPtr);      break;    case XML_TOK_END_TAG:      if (tagLevel == startTagLevel)        return XML_ERROR_ASYNC_ENTITY;      else {	int len;	const char *rawName;	TAG *tag = tagStack;	tagStack = tag->parent;	tag->parent = freeTagList;	freeTagList = tag;	rawName = s + enc->minBytesPerChar*2;	len = XmlNameLength(enc, rawName);	if (len != tag->rawNameLength	    || memcmp(tag->rawName, rawName, len) != 0) {	  *eventPP = rawName;	  return XML_ERROR_TAG_MISMATCH;	}	--tagLevel;	if (endElementHandler) {	  if (tag->name)	    endElementHandler(handlerArg, tag->name);	  else {	    const XML_Char *name = poolStoreString(&tempPool, enc, rawName,	                                           rawName + len);	    if (!name)	      return XML_ERROR_NO_MEMORY;	    endElementHandler(handlerArg, name);	    poolClear(&tempPool);	  }	}	else if (defaultHandler)	  reportDefault(parser, enc, s, next);	if (tagLevel == 0)	  return epilogProcessor(parser, next, end, nextPtr);      }      break;    case XML_TOK_CHAR_REF:      {	int n = XmlCharRefNumber(enc, s);	if (n < 0)	  return XML_ERROR_BAD_CHAR_REF;	if (characterDataHandler) {	  XML_Char buf[XML_ENCODE_MAX];	  characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));	}	else if (defaultHandler)	  reportDefault(parser, enc, s, next);      }      break;    case XML_TOK_XML_DECL:      return XML_ERROR_MISPLACED_XML_PI;    case XML_TOK_DATA_NEWLINE:      if (characterDataHandler) {	XML_Char c = XML_T('\n');	characterDataHandler(handlerArg, &c, 1);      }      else if (defaultHandler)	reportDefault(parser, enc, s, next);      break;    case XML_TOK_CDATA_SECT_OPEN:      {	enum XML_Error result;	if (characterDataHandler)  	  characterDataHandler(handlerArg, dataBuf, 0);	else if (defaultHandler)	  reportDefault(parser, enc, s, next);	result = doCdataSection(parser, enc, &next, end, nextPtr);	if (!next) {	  processor = cdataSectionProcessor;	  return result;	}      }      break;    case XML_TOK_TRAILING_RSQB:      if (nextPtr) {	*nextPtr = s;	return XML_ERROR_NONE;      }      if (characterDataHandler) {	if (MUST_CONVERT(enc, s)) {	  ICHAR *dataPtr = (ICHAR *)dataBuf;	  XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);	  characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);	}	else	  characterDataHandler(handlerArg,		  	       (XML_Char *)s,			       (XML_Char *)end - (XML_Char *)s);      }      else if (defaultHandler)	reportDefault(parser, enc, s, end);      if (startTagLevel == 0) {        *eventPP = end;	return XML_ERROR_NO_ELEMENTS;      }      if (tagLevel != startTagLevel) {	*eventPP = end;	return XML_ERROR_ASYNC_ENTITY;      }      return XML_ERROR_NONE;    case XML_TOK_DATA_CHARS:      if (characterDataHandler) {	if (MUST_CONVERT(enc, s)) {	  for (;;) {	    ICHAR *dataPtr = (ICHAR *)dataBuf;	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);	    *eventEndPP = s;	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);	    if (s == next)	      break;	    *eventPP = s;	  }	}	else	  characterDataHandler(handlerArg,			       (XML_Char *)s,			       (XML_Char *)next - (XML_Char *)s);      }      else if (defaultHandler)	reportDefault(parser, enc, s, next);      break;    case XML_TOK_PI:      if (!reportProcessingInstruction(parser, enc, s, next))	return XML_ERROR_NO_MEMORY;      break;    default:      if (defaultHandler)	reportDefault(parser, enc, s, next);      break;    }    *eventPP = s = next;  }  /* not reached */}/* If tagName is non-null, build a real list of attributes,otherwise just check the attributes for well-formedness. */static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,				const XML_Char *tagName, const char *s){  ELEMENT_TYPE *elementType = 0;  int nDefaultAtts = 0;  const XML_Char **appAtts;  int i;  int n;  if (tagName) {    elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagName, 0);    if (elementType)      nDefaultAtts = elementType->nDefaultAtts;  }    n = XmlGetAttributes(enc, s, attsSize, atts);  if (n + nDefaultAtts > attsSize) {    int oldAttsSize = attsSize;    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;    atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));    if (!atts)      return XML_ERROR_NO_MEMORY;    if (n > oldAttsSize)      XmlGetAttributes(enc, s, n, atts);  }  appAtts = (const XML_Char **)atts;  for (i = 0; i < n; i++) {    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,					  atts[i].name					  + XmlNameLength(enc, atts[i].name));    if (!attId)      return XML_ERROR_NO_MEMORY;    if ((attId->name)[-1]) {      if (enc == encoding)	eventPtr = atts[i].name;      return XML_ERROR_DUPLICATE_ATTRIBUTE;    }    (attId->name)[-1] = 1;    appAtts[i << 1] = attId->name;    if (!atts[i].normalized) {      enum XML_Error result;      int isCdata = 1;      if (attId->maybeTokenized) {	int j;	for (j = 0; j < nDefaultAtts; j++) {	  if (attId == elementType->defaultAtts[j].id) {	    isCdata = elementType->defaultAtts[j].isCdata;	    break;	  }	}      }      result = storeAttributeValue(parser, enc, isCdata,				   atts[i].valuePtr, atts[i].valueEnd,			           &tempPool);      if (result)	return result;      if (tagName) {	appAtts[(i << 1) + 1] = poolStart(&tempPool);	poolFinish(&tempPool);      }      else	poolDiscard(&tempPool);    }    else if (tagName) {      appAtts[(i << 1) + 1] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);      if (appAtts[(i << 1) + 1] == 0)	return XML_ERROR_NO_MEMORY;      poolFinish(&tempPool);    }  }  if (tagName) {    int j;    for (j = 0; j < nDefaultAtts; j++) {      const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;      if (!(da->id->name)[-1] && da->value) {	(da->id->name)[-1] = 1;	appAtts[i << 1] = da->id->name;	appAtts[(i << 1) + 1] = da->value;	i++;      }    }    appAtts[i << 1] = 0;  }  while (i-- > 0)    ((XML_Char *)appAtts[i << 1])[-1] = 0;  return XML_ERROR_NONE;}/* The idea here is to avoid using stack for each CDATA section whenthe whole file is parsed with one call. */staticenum XML_Error cdataSectionProcessor(XML_Parser parser,				     const char *start,			    	     const char *end,				     const char **endPtr){  enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);  if (start) {    processor = contentProcessor;    return contentProcessor(parser, start, end, endPtr);  }  return result;}/* startPtr gets set to non-null is the section is closed, and to null ifthe section is not yet closed. */staticenum XML_Error doCdataSection(XML_Parser parser,			      const ENCODING *enc,			      const char **startPtr,			      const char *end,			      const char **nextPtr){  const char *s = *startPtr;  const char *dummy;  const char **eventPP;  const char **eventEndPP;  if (enc == encoding) {    eventPP = &eventPtr;    *eventPP = s;    eventEndPP = &eventEndPtr;  }  else    eventPP = eventEndPP = &dummy;  *startPtr = 0;  for (;;) {    const char *next;    int tok = XmlCdataSectionTok(enc, s, end, &next);    *eventEndPP = next;    switch (tok) {    case XML_TOK_CDATA_SECT_CLOSE:      if (characterDataHandler)	characterDataHandler(handlerArg, dataBuf, 0);      else if (defaultHandler)	reportDefault(parser, enc, s, next);      *startPtr = next;      return XML_ERROR_NONE;    case XML_TOK_DATA_NEWLINE:      if (characterDataHandler) {	XML_Char c = XML_T('\n');	characterDataHandler(handlerArg, &c, 1);      }      else if (defaultHandler)	reportDefault(parser, enc, s, next);      break;    case XML_TOK_DATA_CHARS:      if (characterDataHandler) {	if (MUST_CONVERT(enc, s)) {	  for (;;) {  	    ICHAR *dataPtr = (ICHAR *)dataBuf;	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);	    *eventEndPP = next;	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);	    if (s == next)	      break;	    *eventPP = s;	  }	}	else	  characterDataHandler(handlerArg,		  	       (XML_Char *)s,			       (XML_Char *)next - (XML_Char *)s);      }      else if (defaultHandler)	reportDefault(parser, enc, s, next);      break;    case XML_TOK_INVALID:      *eventPP = next;      return XML_ERROR_INVALID_TOKEN;    case XML_TOK_PARTIAL_CHAR:      if (nextPtr) {	*nextPtr = s;	return XML_ERROR_NONE;      }      return XML_ERROR_PARTIAL_CHAR;    case XML_TOK_PARTIAL:    case XML_TOK_NONE:      if (nextPtr) {	*nextPtr = s;	return XML_ERROR_NONE;      }      return XML_ERROR_UNCLOSED_CDATA_SECTION;    default:      abort();    }    *eventPP = s = next;  }  /* not reached */}static enum XML_ErrorinitializeEncoding(XML_Parser parser){  const char *s;#ifdef XML_UNICODE  char encodingBuf[128];  if (!protocolEncodingName)    s = 0;  else {    int i;    for (i = 0; protocolEncodingName[i]; i++) {      if (i == sizeof(encodingBuf) - 1	  || protocolEncodingName[i] >= 0x80	  || protocolEncodingName[i] < 0) {	encodingBuf[0] = '\0';	break;      }      encodingBuf[i] = (char)protocolEncodingName[i];    }    encodingBuf[i] = '\0';    s = encodingBuf;  }#else  s = protocolEncodingName;#endif  if (XmlInitEncoding(&initEncoding, &encoding, s))    return XML_ERROR_NONE;  return handleUnknownEncoding(parser, protocolEncodingName);}static enum XML_ErrorprocessXmlDecl(XML_Parser parser, int isGeneralTextEntity,	       const char *s, const char *next){  const char *encodingName = 0;  const ENCODING *newEncoding = 0;  const char *version;  int standalone = -1;  if (!XmlParseXmlDecl(isGeneralTextEntity,		       encoding,		       s,		       next,		       &eventPtr,		       &version,		       &encodingName,		       &newEncoding,		       &standalone))    return XML_ERROR_SYNTAX;  if (!isGeneralTextEntity && standalone == 1)    dtd.standalone = 1;  if (defaultHandler)    reportDefault(parser, encoding, s, next);  if (!protocolEncodingName) {    if (newEncoding) {      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {	eventPtr = encodingName;	return XML_ERROR_INCORRECT_ENCODING;      }      encoding = newEncoding;    }    else if (encodingName) {      enum XML_Error result;      const XML_Char *s = poolStoreString(&tempPool,					  encoding,					  encodingName,					  encodingName					  + XmlNameLength(encoding, encodingName));

⌨️ 快捷键说明

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