--- libxds.tex 2001/08/02 13:58:07 1.1
+++ libxds.tex 2001/08/07 14:07:25 1.2
@@ -1,6 +1,6 @@
% -*- mode: LaTeX; fill-column: 75; -*-
%
-% $Id: libxds.tex,v 1.1 2001/08/02 13:58:07 simons Exp $
+% $Id: libxds.tex,v 1.2 2001/08/07 14:07:25 simons Exp $
%
\documentclass[a4paper,10pt,pointlessnumbers,bibtotoc]{scrartcl}
\usepackage[dvips,xdvi]{graphicx}
@@ -548,16 +548,237 @@
\section{Extending the XDS library}
\label{meta engines}
-
\section{The XDS Framework}
\label{xds}
+\subsection{xds\_t* xds\_init(xds\_mode\_t~\underline{mode});}
+
+This routine creates and initializes a context for use with the XDS
+library. The ``mode'' parameter may be either \textsf{XDS\_ENCODE} or
+\textsf{XDS\_DECODE}, depending on whether you want to encode or to decode
+data. If successful, xds\_init() returns a pointer to the XDS context
+structure. In case of failure, though, xds\_init() will return
+\textsf{NULL} and set \textsf{errno} to ENOMEM (failed to allocate internal
+memory buffers) or EINVAL (``mode'' parameter was invalid).
+
+A context obtained from xds\_init() should be destroyed by calling
+xds\_destroy() when it is not needed any more.
+
+\subsection{void xds\_destroy(xds\_t*~\underline{xds});}
+
+xds\_destroy() will destroy an XDS context created by xds\_init(). Doing so
+will return all resources associated with this context --- most notably the
+memory used to buffer the results of encoding or decoding any values. A
+context may not be used anymore after it has been destroyed.
+
+\subsection{int xds\_register(xds\_t*~\underline{xds}, const~char*~\underline{name}, xds\_engine\_t~\underline{engine}, void*~\underline{engine\_context});}
+
+This routine will register a formatting engine in the provided XDS context.
+A ``formatting engine'' is potentially any function that fullfils the
+following interface:
+
+\begin{quote}
+\begin{verbatim}
+int engine(xds_t* xds, void* engine_context,
+ void* buffer, size_t buffer_size, size_t* used_buffer_size,
+ va_list* args);
+\end{verbatim}
+\end{quote}
+
+By calling xds\_register(), the formatting engine ``engine'' will be
+registered under the name ``name'' in the XDS context ``xds''. The last
+parameter ``engine\_context'' may be specified as the user sees fit: It
+will be passed when the engine is actually called and may be used to
+implement an engine-specific context. Most engines will not need a context
+of their own, in which case \textsf{NULL} should be used here.
+
+Please note that until the user calls xds\_register() for an XDS context he
+obtained from xds\_init(), no engines are registered for that context. Even
+the engines included in the library distribution are not registered
+automatically.
+
+For engine names, any combination of the characters ``a--z'', ``A--Z'',
+``0--9'', ``-'', and ``\_'' may be used; anything else is not a legal
+engine name component.
+
+xds\_register() may return the following return codes: \textsf{XDS\_OK}
+ (everything went fine; the engine is registered now),
+\textsf{XDS\_ERR\_INVALID\_ARG} (either ``xds'', ``name'', or ``engine''
+ are \textsf{NULL} or ``name'' contains illegal characters for an engine
+ name), or
+\textsf{XDS\_ERR\_NO\_MEM} (failed to allocate internally required
+ buffers).
+
+\subsection{int xds\_unregister(xds\_t*~\underline{xds}, const~char*~\underline{name});}
+
+xds\_unregister() will remove the formatting engine ``name'' from XDS
+context ``xds''. The function will return \textsf{XDS\_OK} in case
+everything went fine, \textsf{XDS\_ERR\_UNKNOWN\_ENGINE} in case the engine
+``name'' is not registered in ``xds'', or \textsf{XDS\_ERR\_INVALID\_ARG}
+if either ``xds'' or ``name'' are \textsf{NULL} or ``name'' contains
+illegal characters for an engine name.
+
+\subsection{int xds\_setbuffer(xds\_t*~\underline{xds}, xds\_scope\_t~\underline{flag}, void*~\underline{buffer}, size\_t~\underline{buffer\_len});}
+
+\begin{figure}[tbh]
+ \begin{center}
+ \includegraphics[width=\textwidth]{setbuffer-logic.eps}
+ \caption{xds\_setbuffer() modes of operation}
+ \label{setbuffer logic}
+ \end{center}
+\end{figure}
+
+This routine allows the user to control XDS' buffer handling: Calling it
+will replace the buffer currently used in ``xds''. The address and size of
+that buffer are passed to xds\_setbuffer() via the ``buffer'' and
+``buffer\_len'' parameters. The ``xds'' parameter determines for which XDS
+context the new buffer will be set. Furthermore, you can set ``flag'' to
+either \textsf{XDS\_GIFT} or \textsf{XDS\_LOAN}.
+
+A setting of \textsf{XDS\_GIFT} will tell libxds that the provided buffer
+is now owned by the library and that it may be resized by calling
+\textsf{realloc(3)}. Furthermore, the buffer is \textsf{free(3)}ed when
+``xds'' is destroyed. If ``flag'' is \textsf{XDS\_GIFT} and ``buffer'' is
+\textsf{NULL}, the xds\_setbuffer will simply allocate a buffer of its own
+to be set in ``xds''. Please note that a buffer given to libxds as gift
+\emph{must} have been allocated using \textsf{malloc(3)} --- it may not
+life on the stack because libxds will try to free or to resize the buffer
+as it sees fit.
+
+Passing \textsf{XDS\_LOAN} via ``flag'' tells xds\_setbuffer() that the
+buffer is owned by the application and that libxds should not free nor
+resize the buffer in any case. In this mode, passing a buffer \textsf{NULL}
+will result in an invalid-argument error.
+
+\subsection{int xds\_getbuffer(xds\_t*~\underline{xds}, xds\_scope\_t~\underline{flag}, void**~\underline{buffer}, size\_t*~\underline{buffer\_len});}
+
+This routine is the counterpart to xds\_setbuffer(): It will get the buffer
+currently used in the XDS context ``xds''. The address of that buffer is
+stored in the location ``buffer'' points to; the length of the buffer's
+content will be stored in the location ``buffer\_len'' points to.
+
+The ``flag'' argument may be set to either \textsf{XDS\_GIFT} or
+\textsf{XDS\_LOAN}. The first setting means that the buffer is now owned by
+the application and that libxds must not use it after this xds\_getbuffer()
+call anymore; the library will instead allocate a new buffer for itself. Of
+course this also means that the buffer will not be freed in xds\_destroy():
+The application has to \textsf{free(3)} the buffer itself when it is not
+needed anymore.
+
+Setting ``flag'' to \textsf{XDS\_LOAN} tells libxds that the application
+just wishes to peek into the buffer and will not modify it. The buffer is
+still owned (and used) by libxds. Please note that the loaned address
+returned by xds\_getbuffer() may become invalid change after any other
+xds\_xxx() function call! If you need a reliable address, use
+\textsf{XDS\_GIFT} mode.
+
+The routine will return \textsf{XDS\_OK} (everything went fine) or
+\textsf{XDS\_ERR\_INVALID\_ARG} (``xds'', ``buffer'' or ``buffer\_len'' are
+\textsf{NULL} or ``flag'' is invalid) signifying success or failure
+respectively.
+
+Please note: It is perfectly legal for xds\_getbuffer() to return a buffer
+of \textsf{NULL} and a buffer length of 0! This happens when
+xds\_getbuffer() is called for an XDS context before a buffer has been
+allocated.
+
+\subsection{int xds\_vencode(xds\_t*~\underline{xds}, const~char*~\underline{fmt}, va\_list~\underline{args});}
+
+This routine will encode one or several values using the apropriate
+formatting engines registered in XDS context ``xds''. The parameter ``fmt''
+contains a \textsf{sprintf(3)}-alike descriptions of the values to be
+encoded; the actual values are provided in the varadic parameter ``args''.
+
+The format for ``fmt'' is simple: Just provide the names of the engines to
+be used for encode the apropriate value in ``args''. Any non-legal
+engine-name character may be used as a delimiter. In order to encode two
+32-bit integers followed by a 64-bit integer, the format string
+\begin{quote}
+\begin{verbatim}
+int32 int32 int64
+\end{verbatim}
+\end{quote}
+could be used. In case you don't like the blank, use the colon instead:
+\begin{quote}
+\begin{verbatim*}
+int32:int32:int64
+\end{verbatim*}
+\end{quote}
+
+Of course the names to be used here have to correspond to the names used to
+register the formatting engines in ``xds'' earlier.
+
+Every time xds\_vencode() is called, it will append the encoded data at the
+end of the internal buffer stored in ``xds''. Thus, you can call
+xds\_vencode() several times in order to encode several values, but you'll
+still get all encoded values stored in one buffer. Calling xds\_setbuffer()
+or xds\_getbuffer() at any point during the encoding will re-set the buffer
+to the beginning. All values that have been encoded into that buffer
+already will eventually be overwritten when xds\_encode() is called again.
+Hence: Don't call xds\_setbuffer() or xds\_getbuffer() unless you actually
+want to access the data stored in the buffer.
+
+Also it should be noted that the data you have to provide for ``args''
+depends entirely on what the deployed engines expect to find on the stack
+--- there is no ``standard'' on what should be put on the stack here. The
+XML and XDR engines included in the distribution will simply expect the
+value to be encoded to be found on the stack, but other engines may act
+differently. See section~\ref{meta engines} for an example of such an
+engine.
+
+xds\_vencode() will return any of the following return codes:
+\textsf{XDS\_OK} (everything worked fine), \textsf{XDS\_ERR\_NO\_MEM}
+(failed to allocate or to resize the internal buffer),
+\textsf{XDS\_ERR\_OVER\-FLOW} (the internal buffer is too small but is not
+owned by us), \textsf{XDS\_ERR\_INVALID\_ARG} (``xds'' or ``fmt'' are
+\textsf{NULL}), \textsf{XDS\_ERR\_UNKNOWN\_ENGINE} (an engine name
+specified in ``fmt'' is not registered in ``xds''),
+\textsf{XDS\_ERR\_INVALID\_MODE} (``xds'' is initialized in decode mode),
+or \textsf{XDS\_ERR\_UNKNOWN} (the formatting engine returned an
+unspecified error).
+
+\subsection{int xds\_encode(xds\_t*~\underline{xds}, const~char*~\underline{fmt}, \dots{});}
+
+This routine is basically identical to xds\_vencode(), only that it uses a
+different prototype syntax.
+
+\subsection{int xds\_vdecode(xds\_t*~\underline{xds}, const~char*~\underline{fmt}, va\_list~\underline{args});}
+
+This routine is almost identical to xds\_vencode(): It expects an XDS
+context, a format string and a set of parameters for the formatting
+engines, but xds\_vdecode() does not encode any data, it decodes the data
+back into the native format. The format string again determines which
+engines are to be called by the framework in order to decode the values
+contained in the buffer. The native values will then be stored at the
+locations found in the corresponding ``args'' entry. But please note that
+the exact behavior of the decoding engines is not specified! The XML and
+XDR engines included in this distribution expect a pointer to a location
+where to store the decoded value, but other engines may vary.
+
+xds\_vdecode() may return any of the following return codes:
+\textsf{XDS\_OK} (everything went fine), \textsf{XDS\_ERR\_INVALID\_ARG}
+(``xds'' or ``fmt'' are \textsf{NULL}), \textsf{XDS\_ERR\_TYPE\_MISMATCH}
+(the format string says the next value is of type $A$, but that's not what
+we found in the buffer), \textsf{XDS\_ERR\_UNKNOWN\_ENGINE} (an engine name
+specified in ``fmt'' is not registered in ``xds''),
+\textsf{XDS\_ERR\_INVALID\_MODE} (``xds'' has been initialized in encode
+mode), \textsf{XDS\_ERR\_UNDER\-FLOW} (an engine tried to read $n$ byte from
+the buffer, but we don't have that much data left), or
+\textsf{XDS\_ERR\_UNKNOWN} (an engine returned an unspecified error).
+
+
+\subsection{int xds\_decode(xds\_t*~\underline{xds}, const~char*~\underline{fmt}, \dots{});}
+
+This routine is basically identical to xds\_vdecode(), only that it uses a
+different prototype syntax.
+
\section{The XDR Engines}
\label{xdr}
\section{The XML Engines}
\label{xml}
+\newpage
\begin{thebibliography}{xxx}
\bibitem{xdr} RFC 1832: ``XDR: External Data Representation Standard'',
@@ -565,7 +786,6 @@
\bibitem{xml} {\sf http://www.ossp.org/pkg/xds/xds-xml.dtd}
-
\end{thebibliography}
\end{document}
|