Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Sprint.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file Sprint.d
00004         
00005         Copyright (c) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032         
00033         @version        Initial version; Nov 2005
00034 
00035         @author         Kris
00036 
00037 
00038 *******************************************************************************/
00039 
00040 module mango.convert.Sprint;
00041 
00042 private import  std.stdarg;
00043 
00044 private import  mango.convert.Type,
00045                 mango.convert.Format,
00046                 mango.convert.Unicode;
00047 
00048 /******************************************************************************
00049 
00050         Constructs sprintf-style output. This is a replacement for the 
00051         vsprintf() family of functions, and writes it's output into a 
00052         lookaside buffer. 
00053 
00054         This is the stack-based version, used when heap allocation must
00055         be avoided ~ see Sprint for the class version
00056 
00057         @code
00058         // output buffer
00059         char[100]    tmp;
00060 
00061         SprintStruct sprint;
00062         sprint.ctor (tmp);
00063 
00064         // write text to the console
00065         Cout (sprint ("%d green bottles, sitting on a wall\n", 10));
00066         @endcode
00067 
00068         State is maintained on the stack only, making this thread-safe. 
00069         You may supply a workspace buffer as an optional initialization 
00070         argument, which should typically also be allocated on the stack.
00071 
00072         Note that Sprint is templated, and can be instantiated for wide
00073         chars through a SprintStructTemplate!(dchar) or wchar. The wide
00074         versions differ in that both the output and the format-string
00075         are of the target type. Variadic string arguments are transcoded 
00076         appropriately.
00077 
00078         Floating-point support is optional. The second ctor argument is
00079         for hooking up an appropriate formatter, such as Double.format
00080         or DGDouble.format.
00081 
00082         See Format.parse() for the list of format specifiers.
00083 
00084 ******************************************************************************/
00085 
00086 struct SprintStructTemplate(T)
00087 {
00088         package alias FormatStructTemplate!(T) Format;
00089 
00090         private   Unicode.Into!(T) into;
00091         protected Format           format;
00092         protected T[128]           tmp;
00093         protected T[]              buffer;
00094         protected T*               p, limit;
00095 
00096         mixin Type.TextType!(T);
00097 
00098         /**********************************************************************
00099 
00100         **********************************************************************/
00101 
00102         void ctor (T[] dst, Format.DblFormat df = null, T[] workspace = null)
00103         {
00104                 format.ctor (&sink, null, workspace.length ? workspace : tmp, df);
00105                 p = buffer = dst;
00106                 limit = p + buffer.length;
00107         }
00108 
00109         /**********************************************************************
00110 
00111         **********************************************************************/
00112 
00113         private uint sink (void[] v, uint type)   
00114         {
00115                 auto s = cast(T[]) into.convert (v, type);
00116 
00117 //                if (type != TextType)
00118 //                    format.error ("Sprint.sink : struct version does not transcode");
00119 //                auto s = cast(T[]) v;
00120 
00121                 int len = s.length;
00122                 if (p+len >= limit)
00123                     format.error ("Sprint.sink : output buffer too small");
00124                 
00125                 p[0..len] = s[0..len];
00126                 p += len;       
00127                 return len;
00128         }
00129 
00130         /**********************************************************************
00131 
00132         **********************************************************************/
00133 
00134         T[] opCall (T[] fmt, ...)
00135         {
00136                 p = buffer;
00137                 return buffer [0 .. format (fmt, _arguments, _argptr)];
00138         }
00139 }
00140 
00141 
00142 alias SprintStructTemplate!(char) SprintStruct;
00143 
00144 
00145 
00146 /******************************************************************************
00147 
00148         Constructs sprintf-style output. This is a replacement for the 
00149         vsprintf() family of functions, and writes it's output into a 
00150         lookaside buffer. 
00151 
00152         This is the class-based version, used when convenience is a
00153         factor ~ see SprintStruct for the stack-based version
00154 
00155         @code
00156         // create a Sprint instance
00157         Sprint sprint = new Sprint (100);
00158 
00159         // write text to the console
00160         Cout (sprint ("%d green bottles, sitting on a wall\n", 10));
00161         @endcode
00162 
00163         This can be really handy when you wish to format text for 
00164         a Logger. Please note that the class itself is stateful, and 
00165         therefore a single instance is not shareable across multiple 
00166         threads. 
00167         
00168         Note that Sprint is templated, and can be instantiated for wide
00169         chars through a SprintStructTemplate!(dchar) or wchar. The wide
00170         versions differ in that both the output and the format-string
00171         are of the target type. Variadic string arguments are transcoded 
00172         appropriately.
00173 
00174         Floating-point support is optional. The second ctor argument is
00175         for hooking up an appropriate formatter, such as Double.format
00176         or DGDouble.format.
00177 
00178         See Format.parse() for the list of format specifiers.
00179 
00180 ******************************************************************************/
00181 
00182 class SprintClassTemplate(T)
00183 {
00184         package alias FormatStructTemplate!(T) Format;
00185 
00186         private Unicode.Into!(T) into;
00187         private Format           format;
00188         private T[128]           tmp;
00189         private T[]              buffer;
00190         private T*               p, limit;
00191 
00192         /**********************************************************************
00193 
00194         **********************************************************************/
00195 
00196         this (int size, Format.DblFormat df = null, T[] workspace = null)
00197         {
00198                 format.ctor (&sink, null, workspace.length ? workspace : tmp, df);
00199                 p = buffer = new T[size];
00200                 limit = p + buffer.length;
00201         }
00202 
00203         /**********************************************************************
00204 
00205         **********************************************************************/
00206 
00207         private uint sink (void[] v, uint type)   
00208         {
00209                 auto s = cast(T[]) into.convert (v, type);
00210 
00211                 int len = s.length;
00212                 if (p+len >= limit)
00213                     format.error ("Sprint.sink : output buffer too small");
00214 
00215                 p[0..len] = s[0..len];
00216                 p += len;       
00217                 return len;
00218         }
00219 
00220         /**********************************************************************
00221 
00222         **********************************************************************/
00223 
00224         T[] opCall (T[] fmt, ...)
00225         {
00226                 p = buffer;
00227                 return buffer [0 .. format (fmt, _arguments, _argptr)];
00228         }
00229 }
00230 
00231 alias SprintClassTemplate!(char) Sprint;
00232 

Generated on Sat Dec 24 17:28:33 2005 for Mango by  doxygen 1.4.0