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

📄 nxml_parser.c

📁 libnxml-no-curl-简化版2007-07-01,一个别很不错的XML生成和解析程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* nXml - Copyright (C) 2005 bakunin - Andrea Marchesini  *                                <bakunin@autistici.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include <config.h>#else# error Use configure; make; make install#endif#include "nxml.h"#include "nxml_internal.h"static int__nxml_parse_unique_attribute (nxml_attr_t * attr, char *name){  /*    * Rule [40] - Well-formedness contraint: Unique Att Spec   */  while (attr)    {      if (!strcmp (attr->name, name))	return 1;      attr = attr->next;    }  return 0;}static int__nxml_atoi (char *str){  int ret;  sscanf (str, "%x", &ret);  return ret;}static char *__nxml_parse_string (nxml_t * doc, char *buffer, int size){  char *ret, *real;  int i, j;  int q;  if (!(ret = (char *) malloc (sizeof (char) * ((size * 4) + 1))))    return NULL;  for (q = i = j = 0; i < size; i++)    {      if (*(buffer + i) == 0xd)	continue;      if (*(buffer + i) == 0xa || *(buffer + i) == 0x9	  || *(buffer + i) == 0x20)	{	  if (!q)	    {	      q = 1;	      ret[j++] = *(buffer + i);	    }	}      else if (*(buffer + i) == '&')	{	  if (!strncmp (buffer + i, "&lt;", 4))	    {	      ret[j++] = '<';	      i += 3;	      q = 0;	    }	  else if (!strncmp (buffer + i, "&gt;", 4))	    {	      ret[j++] = '>';	      i += 3;	      q = 0;	    }	  else if (!strncmp (buffer + i, "&amp;", 5))	    {	      ret[j++] = '&';	      i += 4;	      q = 0;	    }	  else if (!strncmp (buffer + i, "&apos;", 6))	    {	      ret[j++] = '\'';	      i += 5;	      q = 0;	    }	  else if (!strncmp (buffer + i, "&quot;", 6))	    {	      ret[j++] = '"';	      i += 5;	      q = 0;	    }	  else if (*(buffer + i + 1) == '#')	    {	      char buf[1024];	      int k = i;	      int last;	      while (*(buffer + k) != ';')		k++;	      last = k - (i + 2) > sizeof (buf) ? sizeof (buf) : k - (i + 2);	      strncpy (buf, buffer + i + 2, last);	      buf[last] = 0;	      if (buf[0] != 'x')		last = atoi (buf);	      else		last = __nxml_atoi (&buf[1]);	      if ((last =		   __nxml_int_charset (last, (unsigned char *) (ret + j),				       doc->encoding)) > 0)		j += last;	      i += k - i;	      q = 0;	    }	  else	    {	      q = 0;	      ret[j++] = *(buffer + i);	    }	}      else	{	  q = 0;	  ret[j++] = *(buffer + i);	}    }  ret[j] = 0;  real = strdup (ret);  free (ret);  return real;}static char *__nxml_parse_get_attr (nxml_t * doc, char **buffer, size_t * size){  char attr[1024];  int i;  int byte;  int64_t ch;  if (!*size)    return NULL;  if (!__NXML_NAMESTARTCHARS)    return NULL;  memcpy (&attr[0], *buffer, byte);  i = byte;  (*buffer) += byte;  (*size) -= byte;  while (__NXML_NAMECHARS && *size && i < sizeof (attr) - 1)    {      memcpy (&attr[i], *buffer, byte);      i += byte;      (*buffer) += byte;      (*size) -= byte;    }  if (**buffer != 0x20 && **buffer != 0x9 && **buffer != 0xa      && **buffer != 0xd && **buffer != '=')    {      (*buffer) -= i;      (*size) += i;      return NULL;    }  i += __nxml_escape_spaces (doc, buffer, size);  if (**buffer != '=')    {      (*buffer) -= i;      (*size) += i;      return NULL;    }  (*buffer)++;  (*size)--;  __nxml_escape_spaces (doc, buffer, size);  attr[i] = 0;  return strdup (attr);}static nxml_error_t__nxml_parse_get_attribute (nxml_t * doc, char **buffer, size_t * size,			    nxml_attr_t ** attr){  /*    * Rule [41] - Attribute ::= Name Eq AttValue   * Rule [25] - Eq ::= S? '=' S?   * Rule [5]  - Name ::= NameStartChar (NameChar)*   * Rule [4]  - NameStartChar ::= ":" | [A-Z] | ["_"] | [a-z] | Unicode...   * Rule [4a] - NameChar ::= NameStarChar | "-" | "." | [0-9] | Unicode...   * Rule [10] - AttValue ::= '"' ([^<&"] | Reference)* '"' |   *                          "'" ([^<&'] | Reference)* "'"   */  char *tag, *value;  if (!*size)    return NXML_OK;  *attr = NULL;  __nxml_escape_spaces (doc, buffer, size);  if (!(tag = __nxml_parse_get_attr (doc, buffer, size)))    return NXML_OK;  if (!(value = __nxml_get_value (doc, buffer, size)))    {      free (tag);      if (doc->priv.func)	doc->priv.func ("%s: expected value of attribute (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      return NXML_ERR_PARSER;    }  __nxml_escape_spaces (doc, buffer, size);  if (!(*attr = (nxml_attr_t *) malloc (sizeof (nxml_attr_t))))    {      free (tag);      free (value);      return NXML_ERR_POSIX;    }  memset (*attr, 0, sizeof (nxml_attr_t));  (*attr)->name = tag;  (*attr)->value = value;  return NXML_OK;}static nxml_error_t__nxml_parse_cdata (nxml_t * doc, char **buffer, size_t * size,		    nxml_data_t ** data){  /*   * Rule [18] - CDSect ::= CDStart CData CDEnd    * Rule [19] - CDStart ::= '<![CDATA['   * Rule [20] - CData ::= (Char * - (Char * ']]>' Char *))   * Rule [21] - CDEnd ::= ']]>'   */  int i = 0;  nxml_data_t *t;  char *value;  while (i < *size)    {      if (!strncmp (*buffer + i, "]]>", 3))	break;      if (*(*buffer + i) == 0xa && doc->priv.func)	doc->priv.line++;      i++;    }  if (strncmp (*buffer + i, "]]>", 3))    {      if (doc->priv.func)	doc->priv.func ("%s: expected ']]>' as close of a CDATA (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      return NXML_ERR_PARSER;    }  if (!(t = (nxml_data_t *) malloc (sizeof (nxml_data_t))))    return NXML_ERR_POSIX;  memset (t, 0, sizeof (nxml_data_t));  t->doc = doc;  if (!(value = (char *) malloc (sizeof (char) * (i + 1))))    {      free (t);      return NXML_ERR_POSIX;    }  strncpy (value, *buffer, i);  value[i] = 0;  t->value = value;  t->type = NXML_TYPE_TEXT;  (*buffer) += i + 3;  (*size) -= i + 3;  *data = t;  return NXML_OK;}static nxml_error_t__nxml_parse_doctype (nxml_t * doc, char **buffer, size_t * size,		      int *doctype){  /*   * Rule [28] - doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?    *                             ('[' intSubset '] S?)? '>'   */  nxml_doctype_t *t;  nxml_doctype_t *tmp;  char str[1024];  char *value;  int i;  int byte;  int64_t ch;  int q = 0;  __nxml_escape_spaces (doc, buffer, size);  if (!__NXML_NAMESTARTCHARS)    {      if (doc->priv.func)	doc->priv.func ("%s: abnormal char '%c' (line %d)\n",			doc->file ? doc->file : "", **buffer, doc->priv.line);      return NXML_ERR_PARSER;    }  memcpy (&str[0], *buffer, byte);  i = byte;  (*buffer) += byte;  (*size) -= byte;  while (__NXML_NAMECHARS && *size && i < sizeof (str) - 1)    {      memcpy (&str[i], *buffer, byte);      i += byte;      (*buffer) += byte;      (*size) -= byte;    }  str[i] = 0;  if (!(t = (nxml_doctype_t *) malloc (sizeof (nxml_doctype_t))))    return NXML_ERR_POSIX;  memset (t, 0, sizeof (nxml_doctype_t));  t->doc = doc;  if (!(t->name = strdup (str)))    {      free (t);      return NXML_ERR_POSIX;    }  __nxml_escape_spaces (doc, buffer, size);  i = 0;  while ((*(*buffer + i) != '>' || q) && i < *size)    {      if (*(*buffer + i) == '<')	q++;      else if (*(*buffer + i) == '>')	q--;      if (*(*buffer + i) == 0xa && doc->priv.func)	doc->priv.line++;      i++;    }  if (*(*buffer + i) != '>')    {      if (doc->priv.func)	doc->priv.func ("%s: expected '>' as close of a doctype (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      free (t->value);      free (t);      return NXML_ERR_PARSER;    }  if (!(value = (char *) malloc (sizeof (char) * (i + 1))))    {      free (t->value);      free (t);      return NXML_ERR_POSIX;    }  strncpy (value, *buffer, i);  value[i] = 0;  t->value = value;  (*buffer) += i + 1;  (*size) -= i + 1;  tmp = doc->doctype;  if (!tmp)    doc->doctype = t;  else    {      while (tmp->next)	tmp = tmp->next;      tmp->next = t;    }  *doctype = 1;  return NXML_OK;}static nxml_error_t__nxml_parse_comment (nxml_t * doc, char **buffer, size_t * size,		      nxml_data_t ** data){  /*    * Rule [15] - Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'   */  int i = 0;  nxml_data_t *t;  char *value;  while (strncmp (*buffer + i, "-->", 3) && i < *size)    {      if (*(*buffer + i) == 0xa && doc->priv.func)	doc->priv.line++;      i++;    }  if (strncmp (*buffer + i, "-->", 3))    {      if (doc->priv.func)	doc->priv.func ("%s: expected '--' as close comment (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      return NXML_ERR_PARSER;    }  if (!(t = (nxml_data_t *) malloc (sizeof (nxml_data_t))))    return NXML_ERR_POSIX;  memset (t, 0, sizeof (nxml_data_t));  t->doc = doc;  if (!(value = (char *) malloc (sizeof (char) * (i + 1))))    {      free (t);      return NXML_ERR_POSIX;    }  strncpy (value, *buffer, i);  value[i] = 0;  t->value = value;  (*buffer) += i + 3;  (*size) -= i + 3;  t->type = NXML_TYPE_COMMENT;  *data = t;  return NXML_OK;}static nxml_error_t__nxml_parse_pi (nxml_t * doc, char **buffer, size_t * size,		 nxml_data_t ** data){  /*    * Rule [16] - PI ::= '<?' PITarget (S (Char * - (Char * '?>' Char *)))?    *                    '?>'   * Rule [17] - PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))   */  int i = 0;  nxml_data_t *t;  char *value;  if (!*size)    return NXML_OK;  *data = NULL;  (*buffer) += 1;  (*size) -= 1;  while (strncmp (*buffer + i, "?>", 2) && i < *size)    {      if (*(*buffer + i) == 0xa && doc->priv.func)	doc->priv.line++;      i++;    }  if (strncmp (*buffer + i, "?>", 2))    {      if (doc->priv.func)	doc->priv.func ("%s: expected '?' as close pi tag (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      return NXML_ERR_PARSER;    }  if (!strncasecmp (*buffer, "?xml", 4))    {      if (doc->priv.func)	doc->priv.func ("%s: pi xml is reserved! (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      return NXML_ERR_PARSER;    }  if (!(t = (nxml_data_t *) malloc (sizeof (nxml_data_t))))    return NXML_ERR_POSIX;  memset (t, 0, sizeof (nxml_data_t));  t->doc = doc;  if (!(value = (char *) malloc (sizeof (char) * (i + 1))))    {      free (t);      return NXML_ERR_POSIX;    }  strncpy (value, *buffer, i);  value[i] = 0;  t->value = value;  (*buffer) += i + 2;  (*size) -= i + 2;  t->type = NXML_TYPE_PI;  *data = t;  return NXML_OK;}static nxml_error_t__nxml_parse_other (nxml_t * doc, char **buffer, size_t * size,		    nxml_data_t ** data, int *doctype){  /* Tags '<!'... */  *data = NULL;  *doctype = 0;  if (!*size)    return NXML_OK;  (*buffer) += 1;  (*size) -= 1;  __nxml_escape_spaces (doc, buffer, size);  if (!strncmp (*buffer, "[CDATA[", 7))    {      (*buffer) += 7;      (*size) -= 7;      return __nxml_parse_cdata (doc, buffer, size, data);    }  else if (!strncmp (*buffer, "--", 2))    {      (*buffer) += 2;      (*size) -= 2;      return __nxml_parse_comment (doc, buffer, size, data);    }  else if (!strncmp (*buffer, "DOCTYPE", 7))    {      (*buffer) += 7;      (*size) -= 7;      return __nxml_parse_doctype (doc, buffer, size, doctype);    }  else    {      if (doc->priv.func)	doc->priv.func ("%s: abnormal tag (line %d)\n",			doc->file ? doc->file : "", doc->priv.line);      return NXML_ERR_PARSER;    }}static nxml_error_t__nxml_parse_text (nxml_t * doc, char **buffer, size_t * size,		   nxml_data_t ** data){  int i = 0;  nxml_data_t *t;  char *value;  char *value_new;  *data = NULL;  if (!*size)    return NXML_OK;  while (*(*buffer + i) != '<' && i < *size)    {      if (*(*buffer + i) == 0xa && doc->priv.func)	doc->priv.line++;      i++;    }  if (!(t = (nxml_data_t *) malloc (sizeof (nxml_data_t))))    return NXML_ERR_POSIX;  memset (t, 0, sizeof (nxml_data_t));  t->doc = doc;  if (!(value = __nxml_parse_string (doc, *buffer, i)))    {      free (t);      return NXML_ERR_POSIX;    }

⌨️ 快捷键说明

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