Commit 3cc3f8a6 authored by Michael R Sweet's avatar Michael R Sweet

Add new mxmlLoadFd() and mxmlSaveFd() functions.

parent 666dd318
CHANGES - 06/25/2004
-------------------
CHANGES - 07/11/2004
--------------------
CHANGES IN Mini-XML 2.1
- Added mxmlLoadFd() and mxmlSaveFd() functions.
CHANGES IN Mini-XML 2.0
......
......@@ -2,7 +2,7 @@
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<title>Documentation</title>
<meta name='creator' content='Mini-XML v2.0rc1'/>
<meta name='creator' content='Mini-XML v2.0'/>
<style><!--
h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
......@@ -56,6 +56,7 @@
<li><a href='#mxmlIndexFind'><tt>mxmlIndexFind()</tt></a></li>
<li><a href='#mxmlIndexNew'><tt>mxmlIndexNew()</tt></a></li>
<li><a href='#mxmlIndexReset'><tt>mxmlIndexReset()</tt></a></li>
<li><a href='#mxmlLoadFd'><tt>mxmlLoadFd()</tt></a></li>
<li><a href='#mxmlLoadFile'><tt>mxmlLoadFile()</tt></a></li>
<li><a href='#mxmlLoadString'><tt>mxmlLoadString()</tt></a></li>
<li><a href='#mxmlNewElement'><tt>mxmlNewElement()</tt></a></li>
......@@ -66,6 +67,7 @@
<li><a href='#mxmlNewTextf'><tt>mxmlNewTextf()</tt></a></li>
<li><a href='#mxmlRemove'><tt>mxmlRemove()</tt></a></li>
<li><a href='#mxmlSaveAllocString'><tt>mxmlSaveAllocString()</tt></a></li>
<li><a href='#mxmlSaveFd'><tt>mxmlSaveFd()</tt></a></li>
<li><a href='#mxmlSaveFile'><tt>mxmlSaveFile()</tt></a></li>
<li><a href='#mxmlSaveString'><tt>mxmlSaveString()</tt></a></li>
<li><a href='#mxmlSetElement'><tt>mxmlSetElement()</tt></a></li>
......@@ -424,6 +426,40 @@ mxmlIndexReset(
<h4>Returns</h4>
<p>First node or NULL if there is none</p>
<!-- NEW PAGE -->
<h3><a name='mxmlLoadFd'>mxmlLoadFd()</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>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 &lt;?xml&gt; 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.</p>
<h4>Syntax</h4>
<pre>
<a href='#mxml_node_t'>mxml_node_t</a> *
mxmlLoadFd(
<a href='#mxml_node_t'>mxml_node_t</a> * top,
int fd,
<a href='#mxml_type_t'>mxml_type_t</a> (*cb)(mxml_node_t *node));
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>fd</tt></td><td>File descriptor to read from</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node)</tt></td><td>Callback function or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>First node or NULL if the file could not be read.</p>
<!-- NEW PAGE -->
<h3><a name='mxmlLoadFile'>mxmlLoadFile()</a></h3>
<hr noshade/>
<h4>Description</h4>
......@@ -684,7 +720,13 @@ 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.</p>
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.</p>
<h4>Syntax</h4>
<pre>
char *
......@@ -702,13 +744,42 @@ mxmlSaveAllocString(
<h4>Returns</h4>
<p>Allocated string or NULL</p>
<!-- NEW PAGE -->
<h3><a name='mxmlSaveFd'>mxmlSaveFd()</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>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.</p>
<h4>Syntax</h4>
<pre>
int
mxmlSaveFd(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
int fd,
const char * (*cb)(mxml_node_t *node, int ws));
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>node</tt></td><td>Node to write</td></tr>
<tr><td><tt>fd</tt></td><td>File descriptor to write to</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node, int ws)</tt></td><td>Whitespace callback or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>0 on success, -1 on error.</p>
<!-- NEW PAGE -->
<h3><a name='mxmlSaveFile'>mxmlSaveFile()</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>Save an XML tree to a file.
The callback argument specifies a function that returns a whitespace
character or nul (0) before and after each element. If MXML_NO_CALLBACK
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.</p>
......@@ -738,7 +809,13 @@ mxmlSaveFile(
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.</p>
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.</p>
<h4>Syntax</h4>
<pre>
int
......@@ -980,6 +1057,7 @@ mxmlWalkPrev(
<h2><a name='_structures'>Structures</a></h2>
<ul>
<li><a href='#mxml_attr_s'><tt>mxml_attr_s</tt></a></li>
<li><a href='#mxml_fdbuf_s'><tt>mxml_fdbuf_s</tt></a></li>
<li><a href='#mxml_index_s'><tt>mxml_index_s</tt></a></li>
<li><a href='#mxml_node_s'><tt>mxml_node_s</tt></a></li>
<li><a href='#mxml_text_s'><tt>mxml_text_s</tt></a></li>
......@@ -1006,6 +1084,28 @@ struct mxml_attr_s
<tr><td><tt>value</tt></td><td>Attribute value</td></tr>
</tbody></table></p>
<!-- NEW PAGE -->
<h3><a name='mxml_fdbuf_s'>mxml_fdbuf_s</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>File descriptor buffer (@private)</p>
<h4>Definition</h4>
<pre>
struct mxml_fdbuf_s
{
end buffer[8192];
unsigned char * current;
int fd;
};
</pre>
<h4>Members</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>buffer[8192]</tt></td><td>Character buffer</td></tr>
<tr><td><tt>current</tt></td><td>Current position in buffer</td></tr>
<tr><td><tt>fd</tt></td><td>File descriptor</td></tr>
</tbody></table></p>
<!-- NEW PAGE -->
<h3><a name='mxml_index_s'>mxml_index_s</a></h3>
<hr noshade/>
<h4>Description</h4>
......@@ -1108,6 +1208,7 @@ struct mxml_value_s
<ul>
<li><a href='#mxml_attr_t'><tt>mxml_attr_t</tt></a></li>
<li><a href='#mxml_element_t'><tt>mxml_element_t</tt></a></li>
<li><a href='#mxml_fdbuf_t'><tt>mxml_fdbuf_t</tt></a></li>
<li><a href='#mxml_index_t'><tt>mxml_index_t</tt></a></li>
<li><a href='#mxml_node_t'><tt>mxml_node_t</tt></a></li>
<li><a href='#mxml_text_t'><tt>mxml_text_t</tt></a></li>
......@@ -1133,6 +1234,15 @@ typedef struct <a href='#mxml_attr_s'>mxml_attr_s</a> mxml_attr_t;
typedef struct <a href='#mxml_value_s'>mxml_value_s</a> mxml_element_t;
</pre>
<!-- NEW PAGE -->
<h3><a name='mxml_fdbuf_t'>mxml_fdbuf_t</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>File descriptor buffer (@private)</p>
<h4>Definition</h4>
<pre>
typedef struct <a href='#mxml_fdbuf_s'>mxml_fdbuf_s</a> mxml_fdbuf_t;
</pre>
<!-- NEW PAGE -->
<h3><a name='mxml_index_t'>mxml_index_t</a></h3>
<hr noshade/>
<h4>Description</h4>
......
......@@ -3,6 +3,14 @@
<h1 align='right'><a name='RELNOTES'>B - Release Notes</a></h1>
<h2>Changes in Mini-XML 2.1</h2>
<ul>
<li>Added mxmlLoadFd() and mxmlSaveFd() functions.
</ul>
<h2>Changes in Mini-XML 2.0</h2>
<ul>
......
This diff is collapsed.
/*
* "$Id: mxml.h,v 1.21 2004/06/01 20:19:34 mike Exp $"
* "$Id: mxml.h,v 1.22 2004/07/11 13:14:07 mike Exp $"
*
* Header file for Mini-XML, a small XML-like file parsing library.
*
......@@ -161,6 +161,8 @@ extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind,
extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element,
const char *attr);
extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind);
extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd,
mxml_type_t (*cb)(mxml_node_t *));
extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp,
mxml_type_t (*cb)(mxml_node_t *));
extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s,
......@@ -180,6 +182,8 @@ __attribute__ ((__format__ (__printf__, 3, 4)))
extern void mxmlRemove(mxml_node_t *node);
extern char *mxmlSaveAllocString(mxml_node_t *node,
const char *(*cb)(mxml_node_t *, int));
extern int mxmlSaveFd(mxml_node_t *node, int fd,
const char *(*cb)(mxml_node_t *, int));
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
const char *(*cb)(mxml_node_t *, int));
extern int mxmlSaveString(mxml_node_t *node, char *buffer,
......@@ -225,5 +229,5 @@ extern mxml_type_t mxml_real_cb(mxml_node_t *node);
/*
* End of "$Id: mxml.h,v 1.21 2004/06/01 20:19:34 mike Exp $".
* End of "$Id: mxml.h,v 1.22 2004/07/11 13:14:07 mike Exp $".
*/
......@@ -243,6 +243,36 @@ mxmlIndexFind() for the first time.</description>
<description>Index to reset</description>
</argument>
</function>
<function name="mxmlLoadFd">
<returnvalue>
<type>mxml_node_t *</type>
<description>First node or NULL if the file could not be read.</description>
</returnvalue>
<description>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 &lt;?xml&gt; 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.</description>
<argument name="top" direction="I">
<type>mxml_node_t *</type>
<description>Top node</description>
</argument>
<argument name="fd" direction="I">
<type>int</type>
<description>File descriptor to read from</description>
</argument>
<argument name="(*cb)(mxml_node_t *node)" direction="I">
<type>mxml_type_t</type>
<description>Callback function or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlLoadFile">
<returnvalue>
<type>mxml_node_t *</type>
......@@ -454,7 +484,13 @@ 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.</description>
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.</description>
<argument name="node" direction="I">
<type>mxml_node_t *</type>
<description>Node to write</description>
......@@ -464,6 +500,31 @@ allocated.</description>
<description>Whitespace callback or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlSaveFd">
<returnvalue>
<type>int</type>
<description>0 on success, -1 on error.</description>
</returnvalue>
<description>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.</description>
<argument name="node" direction="I">
<type>mxml_node_t *</type>
<description>Node to write</description>
</argument>
<argument name="fd" direction="I">
<type>int</type>
<description>File descriptor to write to</description>
</argument>
<argument name="(*cb)(mxml_node_t *node, int ws)" direction="I">
<type>const char *</type>
<description>Whitespace callback or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlSaveFile">
<returnvalue>
<type>int</type>
......@@ -472,7 +533,7 @@ allocated.</description>
<description>Save an XML tree to a file.
The callback argument specifies a function that returns a whitespace
character or nul (0) before and after each element. If MXML_NO_CALLBACK
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.</description>
......@@ -498,7 +559,13 @@ element tags.</description>
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.</description>
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.</description>
<argument name="node" direction="I">
<type>mxml_node_t *</type>
<description>Node to write</description>
......@@ -701,6 +768,25 @@ the walk to the node's children.</description>
<type>struct mxml_value_s</type>
<description>An XML element value.</description>
</typedef>
<struct name="mxml_fdbuf_s">
<description>File descriptor buffer (@private)</description>
<variable name="buffer[8192]">
<type>end</type>
<description>Character buffer</description>
</variable>
<variable name="current">
<type>unsigned char *</type>
<description>Current position in buffer</description>
</variable>
<variable name="fd">
<type>int</type>
<description>File descriptor</description>
</variable>
</struct>
<typedef name="mxml_fdbuf_t">
<type>struct mxml_fdbuf_s</type>
<description>File descriptor buffer (@private)</description>
</typedef>
<struct name="mxml_index_s">
<description>An XML node index.</description>
<variable name="alloc_nodes">
......
......@@ -3,7 +3,7 @@
<keyword type="opaque">InputSlot</keyword>
<default type="opaque">Auto</default>
<text>Media Source</text>
<order type="real">10.0</order>
<order type="real">10.000000</order>
<choice>
<keyword type="opaque">Auto</keyword>
<text>Auto Tray Selection</text>
......@@ -12,16 +12,13 @@
<choice>
<keyword type="opaque">Upper</keyword>
<text>Tray 1</text>
<code type="opaque">&lt;&lt;/MediaPosition 0>>setpagedevice</code>
<code type="opaque">&lt;&lt;/MediaPosition 0&gt;&gt;setpagedevice</code>
</choice>
<choice>
<keyword type="opaque">Lower</keyword>
<text>Tray 2</text>
<code type="opaque">&lt;&lt;/MediaPosition 1>>setpagedevice</code>
<code type="opaque">&lt;&lt;/MediaPosition 1&gt;&gt;setpagedevice</code>
</choice>
</option>
<integer>123</integer>
<string>Now is the time for all good men to come to the aid of
their country.</string>
<string>Now is the time for all good men to come to the aid of their country.</string>
/*
* "$Id: testmxml.c,v 1.17 2004/05/16 18:25:20 mike Exp $"
* "$Id: testmxml.c,v 1.18 2004/07/11 13:14:07 mike Exp $"
*
* Test program for Mini-XML, a small XML-like file parsing library.
*
......@@ -29,6 +29,12 @@
#include "config.h"
#include "mxml.h"
#ifdef WIN32
# include <io.h>
#else
# include <unistd.h>
# include <fcntl.h>
#endif /* WIN32 */
/*
......@@ -49,6 +55,7 @@ main(int argc, /* I - Number of command-line args */
{
int i; /* Looping var */
FILE *fp; /* File to read */
int fd; /* File descriptor */
mxml_node_t *tree, /* XML tree */
*node; /* Node which should be in test.xml */
mxml_index_t *ind; /* XML index */
......@@ -456,11 +463,67 @@ main(int argc, /* I - Number of command-line args */
fputs(buffer, stderr);
/*
* Delete the tree and return...
* Delete the tree...
*/
mxmlDelete(tree);
/*
* Read from/write to file descriptors...
*/
if (argv[1][0] != '<')
{
/*
* Open the file again...
*/
if ((fd = open(argv[1], O_RDONLY)) < 0)
{
perror(argv[1]);
return (1);
}
/*
* Read the file...
*/
tree = mxmlLoadFd(NULL, fd, type_cb);
close(fd);
/*
* Create filename.xmlfd...
*/
snprintf(buffer, sizeof(buffer), "%sfd", argv[1]);
if ((fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
{
perror(buffer);
mxmlDelete(tree);
return (1);
}
/*
* Write the file...
*/
mxmlSaveFd(tree, fd, whitespace_cb);
close(fd);
/*
* Delete the tree...
*/
mxmlDelete(tree);
}
/*
* Return...
*/
return (0);
}
......@@ -502,7 +565,12 @@ const char * /* O - Whitespace string or NULL */
whitespace_cb(mxml_node_t *node, /* I - Element node */
int where) /* I - Open or close tag? */
{
const char *name; /* Name of element */
mxml_node_t *parent; /* Parent node */
int level; /* Indentation level */
const char *name; /* Name of element */
static const char *tabs = "\t\t\t\t\t\t\t\t";
/* Tabs for indentation */
/*
* We can conditionally break to a new line before or after any element.
......@@ -542,6 +610,37 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
else if (where == MXML_WS_AFTER_CLOSE)
return ("\n");
}
else if (!strcmp(name, "?xml"))
{
return (NULL);
}
else if (!strcmp(name, "option"))
{
if (where == MXML_WS_AFTER_OPEN || where == MXML_WS_AFTER_CLOSE)
return ("\n");
}
else if (!strcmp(name, "choice"))
{
if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_BEFORE_CLOSE)
return ("\t");
else
return ("\n");
}
else if (where == MXML_WS_BEFORE_OPEN)
{
for (level = -1, parent = node->parent;
parent;
level ++, parent = parent->parent);
if (level > 8)
level = 8;
return (tabs + 8 - level);
}
else if (where == MXML_WS_AFTER_CLOSE)
return ("\n");
else if (!strcmp(name, "code") && where == MXML_WS_AFTER_OPEN && !node->child)
return ("\n");
/*
* Return NULL for no added whitespace...
......@@ -552,5 +651,5 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
/*
* End of "$Id: testmxml.c,v 1.17 2004/05/16 18:25:20 mike Exp $".
* End of "$Id: testmxml.c,v 1.18 2004/07/11 13:14:07 mike Exp $".
*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment