vappendf.hpp

Go to the documentation of this file.
00001 #ifndef S11N_NET_VAPPENDF_H_INCLUDED_
00002 #define S11N_NET_VAPPENDF_H_INCLUDED_ 1
00003 #include <stdarg.h>
00004 #include <ostream>
00005 namespace s11n {
00006 
00007 /**
00008    This code implements a printf-like implementation which supports
00009    aribtrary data destinations.
00010 
00011    Authors: many, probably. This code supposedly goes back to the
00012    early 1980's.
00013 
00014    License: Public Domain.
00015 */
00016 
00017 /**
00018    The vappendf_appender typedef is used to provide vappendf()
00019    with a flexible output routine, so that it can be easily
00020    send its output to arbitrary targets.
00021 
00022    The policies which implementations need to follow are:
00023 
00024    - arg is an implementation-specific pointer (may be 0) which is
00025    passed to vappendf. vappendf() doesn't know what this argument is
00026    but passes it to its vappendf_appender. Typically it will be an
00027    object or resource handle to which string data is pushed or output.
00028 
00029    - The 'data' parameter is the data to append. If it contains
00030    embedded nulls, this function will stop at the first one. Thus
00031    it is not binary-safe.
00032 
00033    - n is the number of bytes to read from data. If n<0 then
00034    strlen(data) should be used.
00035 
00036    - Returns, on success, the number of bytes appended (may be 0).
00037 
00038    - Returns, on error, an implementation-specified negative number.
00039    Returning a negative error code will cause vappendf() to stop the
00040    processing of that string. Note that 0 is a success value (some
00041    printf format specifiers do not add anything to the output).
00042 */
00043 typedef long (*vappendf_appender)( void * arg,
00044                    char const * data,
00045                    long n );
00046 
00047 
00048 /*
00049   This function works similarly to classical printf implementations,
00050   but instead of outputing somewhere specific, it uses a callback
00051   function to push its output somewhere. This allows it to be used for
00052   arbitrary external representations. It can be used, for example, to
00053   output to an external string, a UI widget, or file handle (it can
00054   also emulate printf by outputing to stdout this way).
00055 
00056  INPUTS:
00057 
00058  pfAppend : The is a vappendf_appender function which is responsible
00059  for accumulating the output. If pfAppend returns a negative integer
00060  then processing stops immediately.
00061 
00062  pfAppendArg : is ignored by this function but passed as the first
00063  argument to pfAppend. pfAppend will presumably use it as a data
00064  store for accumulating its string.
00065 
00066  fmt : This is the format string, as in the usual printf().
00067 
00068  ap : This is a pointer to a list of arguments.  Same as in
00069  vprintf() and friends.
00070 
00071 
00072  OUTPUTS:
00073 
00074  The return value is the total number of characters sent to the
00075  function "func", or a negative number on a pre-output error. If this
00076  function returns an integer greater than 1 it is in general
00077  impossible to know if all of the elements were output. As such
00078  failure can only happen if the callback function returns an error,
00079  and this type of error is very rare in a printf-like context, this is
00080  not considered to be a significant problem. (The same is true for any
00081  classical printf implementations, as far as i'm aware.)
00082 
00083 
00084  CURRENT (documented) PRINTF EXTENSIONS:
00085 
00086  %z works like %s, but takes a non-const (char *) in the va_list, and
00087  vappendf deletes the string (using free()) after appending it to the
00088  output.
00089 
00090  %h (HTML) works like %s but converts certain characters (like '<' and '&' to
00091  their HTML escaped equivalents.
00092 
00093  %t (URL encode) works like %s but converts certain characters into a representation
00094  suitable for use in an HTTP URL. (e.g. ' ' gets converted to %20)
00095 
00096  %T (URL decode) does the opposite of %t - it decodes URL-encoded
00097  strings.
00098 
00099  %n requires an (int*) in the va_list, which gets assigned
00100  the number of bytes this function has appended to cb so far.
00101 
00102  %r requires an int and renders it in "ordinal form". That is,
00103  the number 1 converts to "1st" and 398 converts to "398th".
00104 
00105  %q quotes a string as required for SQL. That is, '\'' characters get doubled.
00106 
00107  %Q as %q, but includes the outer '\'' characters and null pointers
00108  replaced by SQL NULL.
00109 
00110  (The %q and %Q specifiers are options inherited from this printf
00111  implementation's sqlite3 genes.)
00112 
00113 */
00114 long vappendf(
00115   vappendf_appender pfAppend,          /* Accumulate results here */
00116   void * pfAppendArg,                /* Passed as first arg to pfAppend. */
00117   const char *fmt,                   /* Format string */
00118   va_list ap                         /* arguments */
00119   );
00120 
00121 /**
00122    Identical to vappendf() but does not take a va_list.
00123 */
00124 long appendf(vappendf_appender pfAppend,
00125          void * pfAppendArg,
00126          const char *fmt,
00127          ... );
00128 
00129 /**
00130    An overload which sends its output to the given ostream.
00131 */
00132 long vappendf( std::ostream & target,
00133            const char *fmt,
00134            va_list ap
00135            );
00136 
00137 /**
00138    An overload which sends its output to the given ostream.
00139 */
00140 long appendf( std::ostream & target,
00141           const char *fmt,
00142           ... );
00143 
00144 } /* extern "C" || namespace */
00145 #endif // S11N_NET_VAPPENDF_H_INCLUDED_

Generated on Wed Jun 4 21:45:18 2008 for libs11n by  doxygen 1.5.3