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

📄 mxml-file.c

📁 适用于嵌入式系统的XML解析库, 规模比libxml2小得多.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * "$Id: mxml-file.c 329 2008-01-13 00:42:35Z mike $" * * File loading code for Mini-XML, a small XML-like file parsing library. * * Copyright 2003-2008 by Michael Sweet. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2, or (at your option) any later version. * * This program 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 General Public License for more details. * * Contents: * *   mxmlLoadFd()            - Load a file descriptor into an XML node tree. *   mxmlLoadFile()          - Load a file into an XML node tree. *   mxmlLoadString()        - Load a string into an XML node tree. *   mxmlSaveAllocString()   - Save an XML node tree to an allocated string. *   mxmlSaveFd()            - Save an XML tree to a file descriptor. *   mxmlSaveFile()          - Save an XML tree to a file. *   mxmlSaveString()        - Save an XML node tree to a string. *   mxmlSAXLoadFd()         - Load a file descriptor into an XML node tree *                             using a SAX callback. *   mxmlSAXLoadFile()       - Load a file into an XML node tree *                             using a SAX callback. *   mxmlSAXLoadString()     - Load a string into an XML node tree *                             using a SAX callback. *   mxmlSetCustomHandlers() - Set the handling functions for custom data. *   mxmlSetErrorCallback()  - Set the error message callback. *   mxmlSetWrapMargin()     - Set the the wrap margin when saving XML data. *   mxml_add_char()         - Add a character to a buffer, expanding as needed. *   mxml_fd_getc()          - Read a character from a file descriptor. *   mxml_fd_putc()          - Write a character to a file descriptor. *   mxml_fd_read()          - Read a buffer of data from a file descriptor. *   mxml_fd_write()         - Write a buffer of data to a file descriptor. *   mxml_file_getc()        - Get a character from a file. *   mxml_file_putc()        - Write a character to a file. *   mxml_get_entity()       - Get the character corresponding to an entity... *   mxml_load_data()        - Load data into an XML node tree. *   mxml_parse_element()    - Parse an element for any attributes... *   mxml_string_getc()      - Get a character from a string. *   mxml_string_putc()      - Write a character to a string. *   mxml_write_name()       - Write a name string. *   mxml_write_node()       - Save an XML node to a file. *   mxml_write_string()     - Write a string, escaping & and < as needed. *   mxml_write_ws()         - Do whitespace callback... *//* * Include necessary headers... */#include "mxml-private.h"#ifdef WIN32#  include <io.h>#else#  include <unistd.h>#endif /* WIN32 *//* * Character encoding... */#define ENCODE_UTF8	0		/* UTF-8 */#define ENCODE_UTF16BE	1		/* UTF-16 Big-Endian */#define ENCODE_UTF16LE	2		/* UTF-16 Little-Endian *//* * Macro to test for a bad XML character... */#define mxml_bad_char(ch) ((ch) < ' ' && (ch) != '\n' && (ch) != '\r' && (ch) != '\t')/* * Types and structures... */typedef int (*_mxml_getc_cb_t)(void *, int *);typedef int (*_mxml_putc_cb_t)(int, void *);typedef struct _mxml_fdbuf_s		/**** File descriptor buffer ****/{  int		fd;			/* File descriptor */  unsigned char	*current,		/* Current position in buffer */		*end,			/* End of buffer */		buffer[8192];		/* Character buffer */} _mxml_fdbuf_t;/* * Local functions... */static int		mxml_add_char(int ch, char **ptr, char **buffer,			              int *bufsize);static int		mxml_fd_getc(void *p, int *encoding);static int		mxml_fd_putc(int ch, void *p);static int		mxml_fd_read(_mxml_fdbuf_t *buf);static int		mxml_fd_write(_mxml_fdbuf_t *buf);static int		mxml_file_getc(void *p, int *encoding);static int		mxml_file_putc(int ch, void *p);static int		mxml_get_entity(mxml_node_t *parent, void *p,			                int *encoding,					_mxml_getc_cb_t getc_cb);static inline int	mxml_isspace(int ch)			{			  return (ch == ' ' || ch == '\t' || ch == '\r' ||			          ch == '\n');			}static mxml_node_t	*mxml_load_data(mxml_node_t *top, void *p,			                mxml_load_cb_t cb,			                _mxml_getc_cb_t getc_cb,                                        mxml_sax_cb_t sax_cb, void *sax_data);static int		mxml_parse_element(mxml_node_t *node, void *p,			                   int *encoding,					   _mxml_getc_cb_t getc_cb);static int		mxml_string_getc(void *p, int *encoding);static int		mxml_string_putc(int ch, void *p);static int		mxml_write_name(const char *s, void *p,					_mxml_putc_cb_t putc_cb);static int		mxml_write_node(mxml_node_t *node, void *p,			                mxml_save_cb_t cb, int col,					_mxml_putc_cb_t putc_cb,					_mxml_global_t *global);static int		mxml_write_string(const char *s, void *p,					  _mxml_putc_cb_t putc_cb);static int		mxml_write_ws(mxml_node_t *node, void *p, 			              mxml_save_cb_t cb, int ws,				      int col, _mxml_putc_cb_t putc_cb);/* * 'mxmlLoadFd()' - Load a file descriptor into an XML node tree. * * The nodes in the specified file are added to the specified top node. * If no top node is provided, the XML file MUST be well-formed with a * single parent node like <?xml> for the entire file. The callback * function returns the value type that should be used for child nodes. * If MXML_NO_CALLBACK is specified then all child nodes will be either * MXML_ELEMENT or MXML_TEXT nodes. * * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading * child nodes of the specified type. */mxml_node_t *				/* O - First node or NULL if the file could not be read. */mxmlLoadFd(mxml_node_t    *top,		/* I - Top node */           int            fd,		/* I - File descriptor to read from */           mxml_load_cb_t cb)		/* I - Callback function or MXML_NO_CALLBACK */{  _mxml_fdbuf_t	buf;			/* File descriptor buffer */ /*  * Initialize the file descriptor buffer...  */  buf.fd      = fd;  buf.current = buf.buffer;  buf.end     = buf.buffer; /*  * Read the XML data...  */  return (mxml_load_data(top, &buf, cb, mxml_fd_getc, MXML_NO_CALLBACK, NULL));}/* * 'mxmlLoadFile()' - Load a file into an XML node tree. * * The nodes in the specified file are added to the specified top node. * If no top node is provided, the XML file MUST be well-formed with a * single parent node like <?xml> for the entire file. The callback * function returns the value type that should be used for child nodes. * If MXML_NO_CALLBACK is specified then all child nodes will be either * MXML_ELEMENT or MXML_TEXT nodes. * * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading * child nodes of the specified type. */mxml_node_t *				/* O - First node or NULL if the file could not be read. */mxmlLoadFile(mxml_node_t    *top,	/* I - Top node */             FILE           *fp,	/* I - File to read from */             mxml_load_cb_t cb)		/* I - Callback function or MXML_NO_CALLBACK */{ /*  * Read the XML data...  */  return (mxml_load_data(top, fp, cb, mxml_file_getc, MXML_NO_CALLBACK, NULL));}/* * 'mxmlLoadString()' - Load a string into an XML node tree. * * The nodes in the specified string are added to the specified top node. * If no top node is provided, the XML string MUST be well-formed with a * single parent node like <?xml> for the entire string. The callback * function returns the value type that should be used for child nodes. * If MXML_NO_CALLBACK is specified then all child nodes will be either * MXML_ELEMENT or MXML_TEXT nodes. * * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading * child nodes of the specified type. */mxml_node_t *				/* O - First node or NULL if the string has errors. */mxmlLoadString(mxml_node_t    *top,	/* I - Top node */               const char     *s,	/* I - String to load */               mxml_load_cb_t cb)	/* I - Callback function or MXML_NO_CALLBACK */{ /*  * Read the XML data...  */  return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, MXML_NO_CALLBACK,                         NULL));}/* * 'mxmlSaveAllocString()' - Save an XML node tree to an allocated string. * * This function returns a pointer to a string containing the textual * representation of the XML node tree.  The string should be freed * using the free() function when you are done with it.  NULL is returned * if the node would produce an empty string or if the string cannot be * allocated. * * The callback argument specifies a function that returns a whitespace * string or NULL before and after each element. If MXML_NO_CALLBACK * is specified, whitespace will only be added before MXML_TEXT nodes * with leading whitespace and before attribute names inside opening * element tags. */char *					/* O - Allocated string or NULL */mxmlSaveAllocString(    mxml_node_t    *node,		/* I - Node to write */    mxml_save_cb_t cb)			/* I - Whitespace callback or MXML_NO_CALLBACK */{  int	bytes;				/* Required bytes */  char	buffer[8192];			/* Temporary buffer */  char	*s;				/* Allocated string */ /*  * Write the node to the temporary buffer...  */  bytes = mxmlSaveString(node, buffer, sizeof(buffer), cb);  if (bytes <= 0)    return (NULL);  if (bytes < (int)(sizeof(buffer) - 1))  {   /*    * Node fit inside the buffer, so just duplicate that string and    * return...    */    return (strdup(buffer));  } /*  * Allocate a buffer of the required size and save the node to the  * new buffer...  */  if ((s = malloc(bytes + 1)) == NULL)    return (NULL);  mxmlSaveString(node, s, bytes + 1, cb); /*  * Return the allocated string...  */  return (s);}/* * 'mxmlSaveFd()' - Save an XML tree to a file descriptor. * * The callback argument specifies a function that returns a whitespace * string or NULL before and after each element. If MXML_NO_CALLBACK * is specified, whitespace will only be added before MXML_TEXT nodes * with leading whitespace and before attribute names inside opening * element tags. */int					/* O - 0 on success, -1 on error. */mxmlSaveFd(mxml_node_t    *node,	/* I - Node to write */           int            fd,		/* I - File descriptor to write to */	   mxml_save_cb_t cb)		/* I - Whitespace callback or MXML_NO_CALLBACK */{  int		col;			/* Final column */  _mxml_fdbuf_t	buf;			/* File descriptor buffer */  _mxml_global_t *global = _mxml_global();					/* Global data */ /*  * Initialize the file descriptor buffer...  */  buf.fd      = fd;  buf.current = buf.buffer;  buf.end     = buf.buffer + sizeof(buf.buffer) - 4; /*  * Write the node...  */  if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global)) < 0)    return (-1);  if (col > 0)    if (mxml_fd_putc('\n', &buf) < 0)      return (-1); /*  * Flush and return...  */  return (mxml_fd_write(&buf));}/* * 'mxmlSaveFile()' - Save an XML tree to a file. * * The callback argument specifies a function that returns a whitespace * string or NULL before and after each element. If MXML_NO_CALLBACK * is specified, whitespace will only be added before MXML_TEXT nodes * with leading whitespace and before attribute names inside opening * element tags. */int					/* O - 0 on success, -1 on error. */mxmlSaveFile(mxml_node_t    *node,	/* I - Node to write */             FILE           *fp,	/* I - File to write to */	     mxml_save_cb_t cb)		/* I - Whitespace callback or MXML_NO_CALLBACK */{  int	col;				/* Final column */  _mxml_global_t *global = _mxml_global();					/* Global data */ /*  * Write the node...  */  if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global)) < 0)    return (-1);  if (col > 0)    if (putc('\n', fp) < 0)      return (-1); /*  * Return 0 (success)...  */  return (0);}/* * 'mxmlSaveString()' - Save an XML node tree to a string. * * This function returns the total number of bytes that would be * required for the string but only copies (bufsize - 1) characters * into the specified buffer. * * The callback argument specifies a function that returns a whitespace * string or NULL before and after each element. If MXML_NO_CALLBACK * is specified, whitespace will only be added before MXML_TEXT nodes * with leading whitespace and before attribute names inside opening * element tags. */int					/* O - Size of string */mxmlSaveString(mxml_node_t    *node,	/* I - Node to write */               char           *buffer,	/* I - String buffer */               int            bufsize,	/* I - Size of string buffer */               mxml_save_cb_t cb)	/* I - Whitespace callback or MXML_NO_CALLBACK */{  int	col;				/* Final column */  char	*ptr[2];			/* Pointers for putc_cb */  _mxml_global_t *global = _mxml_global();					/* Global data */ /*  * Write the node...  */  ptr[0] = buffer;  ptr[1] = buffer + bufsize;  if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global)) < 0)    return (-1);  if (col > 0)    mxml_string_putc('\n', ptr); /*  * Nul-terminate the buffer...  */  if (ptr[0] >= ptr[1])    buffer[bufsize - 1] = '\0';  else    ptr[0][0] = '\0'; /*  * Return the number of characters...  */  return (ptr[0] - buffer);}/* * 'mxmlSAXLoadFd()' - Load a file descriptor into an XML node tree *                     using a SAX callback. * * The nodes in the specified file are added to the specified top node. * If no top node is provided, the XML file MUST be well-formed with a * single parent node like <?xml> for the entire file. The callback * function returns the value type that should be used for child nodes. * If MXML_NO_CALLBACK is specified then all child nodes will be either * MXML_ELEMENT or MXML_TEXT nodes. * * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading * child nodes of the specified type. * * The SAX callback must call mxmlRetain() for any nodes that need to * be kept for later use. Otherwise, nodes are deleted when the parent * node is closed or after each data, comment, CDATA, or directive node. * * @since Mini-XML 2.3@ */mxml_node_t *				/* O - First node or NULL if the file could not be read. */mxmlSAXLoadFd(mxml_node_t    *top,	/* I - Top node */              int            fd,	/* I - File descriptor to read from */              mxml_load_cb_t cb,	/* I - Callback function or MXML_NO_CALLBACK */              mxml_sax_cb_t  sax_cb,	/* I - SAX callback or MXML_NO_CALLBACK */              void           *sax_data)	/* I - SAX user data */{  _mxml_fdbuf_t	buf;			/* File descriptor buffer */ /*  * Initialize the file descriptor buffer...  */  buf.fd      = fd;  buf.current = buf.buffer;  buf.end     = buf.buffer; /*  * Read the XML data...  */  return (mxml_load_data(top, &buf, cb, mxml_fd_getc, sax_cb, sax_data));}/* * 'mxmlSAXLoadFile()' - Load a file into an XML node tree *                       using a SAX callback. * * The nodes in the specified file are added to the specified top node. * If no top node is provided, the XML file MUST be well-formed with a * single parent node like <?xml> for the entire file. The callback * function returns the value type that should be used for child nodes. * If MXML_NO_CALLBACK is specified then all child nodes will be either * MXML_ELEMENT or MXML_TEXT nodes. * * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading * child nodes of the specified type. * * The SAX callback must call mxmlRetain() for any nodes that need to * be kept for later use. Otherwise, nodes are deleted when the parent * node is closed or after each data, comment, CDATA, or directive node. * * @since Mini-XML 2.3@ */mxml_node_t *				/* O - First node or NULL if the file could not be read. */mxmlSAXLoadFile(    mxml_node_t    *top,		/* I - Top node */    FILE           *fp,			/* I - File to read from */    mxml_load_cb_t cb,			/* I - Callback function or MXML_NO_CALLBACK */    mxml_sax_cb_t  sax_cb,		/* I - SAX callback or MXML_NO_CALLBACK */    void           *sax_data)		/* I - SAX user data */{ /*  * Read the XML data...  */  return (mxml_load_data(top, fp, cb, mxml_file_getc, sax_cb, sax_data));}/* * 'mxmlSAXLoadString()' - Load a string into an XML node tree *                         using a SAX callback. * * The nodes in the specified string are added to the specified top node. * If no top node is provided, the XML string MUST be well-formed with a * single parent node like <?xml> for the entire string. The callback * function returns the value type that should be used for child nodes. * If MXML_NO_CALLBACK is specified then all child nodes will be either * MXML_ELEMENT or MXML_TEXT nodes. * * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading * child nodes of the specified type. * * The SAX callback must call mxmlRetain() for any nodes that need to * be kept for later use. Otherwise, nodes are deleted when the parent * node is closed or after each data, comment, CDATA, or directive node. * * @since Mini-XML 2.3@ */mxml_node_t *				/* O - First node or NULL if the string has errors. */mxmlSAXLoadString(    mxml_node_t    *top,		/* I - Top node */    const char     *s,			/* I - String to load */    mxml_load_cb_t cb,			/* I - Callback function or MXML_NO_CALLBACK */    mxml_sax_cb_t  sax_cb,		/* I - SAX callback or MXML_NO_CALLBACK */    void           *sax_data)		/* I - SAX user data */{ /*  * Read the XML data...  */  return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, sax_cb, sax_data));}/* * 'mxmlSetCustomHandlers()' - Set the handling functions for custom data. * * The load function accepts a node pointer and a data string and must * return 0 on success and non-zero on error. * * The save function accepts a node pointer and must return a malloc'd * string on success and NULL on error. *  */voidmxmlSetCustomHandlers(    mxml_custom_load_cb_t load,		/* I - Load function */    mxml_custom_save_cb_t save)		/* I - Save function */{  _mxml_global_t *global = _mxml_global();					/* Global data */  global->custom_load_cb = load;  global->custom_save_cb = save;}/* * 'mxmlSetErrorCallback()' - Set the error message callback. */voidmxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */{

⌨️ 快捷键说明

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