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

ColumnWriter.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file ColumnWriter.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 
00027                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00028 
00029 
00030         @version        Initial version, March 2004      
00031         @author         Kris
00032 
00033 
00034 *******************************************************************************/
00035 
00036 module mango.io.ColumnWriter;
00037 
00038 private import  mango.io.Exception;
00039 
00040 public  import  mango.io.DisplayWriter;
00041 
00042 /*******************************************************************************
00043 
00044         Print readable output to an IWriter, distributed across a set of
00045         columns. Columns start at zero rather than one, so adjust counts
00046         appropriately. All output is currently left-aligned. 
00047 
00048         This is how one might use ColumnWriter:
00049         
00050         @code
00051         static int[] columns = [0, 4, 14, 24];
00052 
00053         // map a ColumnWriter directly onto Stdout
00054         ColumnWriter cw = new ColumnWriter (Stdout.getBuffer(), new ColumnList(columns));
00055 
00056         // set 2 digits of precision
00057         cw.setPrecision (2);
00058 
00059         // opShl style     
00060         cw << 1 << 20.34944 << "test" << cw.newline;
00061         
00062         // put() style
00063         cw.put(1).put(20.34944).put("test").cr();
00064         @endcode
00065 
00066         Note that ColumnWriter may be used with files, sockets, or any other
00067         buffer-oriented construct.
00068 
00069 *******************************************************************************/
00070 
00071 class ColumnWriter : DisplayWriter
00072 {
00073         private int             output;
00074         private ColumnList      columns;
00075         private static ubyte    spaces[256];
00076 
00077         alias DisplayWriter.put put;
00078 
00079         /***********************************************************************
00080         
00081                 Construct a ColumnWriter upon the given IBuffer, with the
00082                 specified set of columns.
00083                 
00084         ***********************************************************************/
00085 
00086         this (IBuffer buffer, ColumnList columns)
00087         in {
00088            assert (buffer);
00089            assert (columns);
00090            }
00091         body
00092         {
00093                 super (buffer);
00094                 
00095                 this.columns = columns;
00096                 reset ();
00097         }
00098      
00099         /***********************************************************************
00100         
00101                 Populate the space padding with valid spaces.
00102 
00103         ***********************************************************************/
00104 
00105         static this ()
00106         {
00107                 spaces[] = ' ';
00108         }
00109      
00110         /***********************************************************************
00111         
00112         ***********************************************************************/
00113         
00114         override char[] toString()
00115         {
00116                 return "column writer";
00117         }
00118 
00119         /***********************************************************************
00120         
00121                 Reset everything back to zero. Typical usage will invoke
00122                 this whenever a Newline is emitted. 
00123                 
00124                 Note that we maintain our own internal count of how many 
00125                 bytes have been output: this is because we cannot depend 
00126                 on the Buffer to provide that for us if (a) the buffer is 
00127                 very small, or (b) the buffer is flushed after each write 
00128                 (Stdout etc).
00129 
00130         ***********************************************************************/
00131 
00132         void reset ()
00133         {
00134                 output = 0;
00135                 columns.reset ();
00136         }
00137 /+     
00138         /***********************************************************************
00139         
00140                 Return the width of the current column.
00141 
00142         ***********************************************************************/
00143 
00144         override int getWidth ()
00145         {
00146                 return columns.getWidth;
00147         }
00148 +/
00149         /***********************************************************************
00150         
00151                 Intercept the IWritable type so we can reset our columns
00152                 when a newline is emitted.
00153 
00154         ***********************************************************************/
00155 
00156         override IWriter put (IWritable x)
00157         {                       
00158                // have superclass print the IWritable
00159                 super.put (x);
00160 
00161                 // reset columns on a newline
00162                 if (cast (INewlineWriter) x)
00163                     reset ();
00164 
00165                 return this;
00166         }
00167      
00168         /***********************************************************************
00169         
00170                 Intercept the output so we can write some spaces first. 
00171                 Note that our superclass (DisplayWriter) converts each
00172                 of its arguments to a char[] first, so this override is
00173                 able to catch everything emitted.
00174 
00175                 @todo - add the equivalent intercepts for both wchar[] 
00176                         and dchar[] methods.
00177 
00178         ***********************************************************************/
00179 
00180         override IWriter put (char[] x)
00181         {    
00182                 pad ();
00183                 output += x.length;
00184                 return super.put (x);
00185         }
00186 
00187         /***********************************************************************
00188 
00189                 Pad the output with spaces to reach the next column
00190                 position. This should be invoked before anything is
00191                 written to the buffer.
00192         
00193         ***********************************************************************/
00194 
00195         private final void pad ()
00196         {    
00197                 int padding = columns.next() - output;
00198 
00199                 // pad output to next column position?
00200                 if (padding > 0)
00201                    if (padding <= spaces.sizeof)
00202                       {
00203                       // yep - write a set of spaces
00204                       string.char8 (spaces, padding);
00205                       output += padding;
00206                       }
00207                    else
00208                       throw new IOException ("Invalid column step (> 256)");
00209         }
00210 }
00211 
00212 
00213 /*******************************************************************************
00214 
00215         A list of columns for the ColumnWriter to utilize.
00216 
00217 *******************************************************************************/
00218 
00219 class ColumnList
00220 {
00221         private int     index;
00222         private int[]   columns;
00223 
00224         private bool    rightAlign;  // this needs to be per column instead
00225 
00226         /***********************************************************************
00227         
00228                 Construct a ColumnList via an array of integers.
00229 
00230         ***********************************************************************/
00231 
00232         this (int[] columns)
00233         in {
00234            assert (columns);
00235            }
00236         body
00237         {
00238                 reset ();
00239                 this.columns = columns;
00240         }
00241 
00242         /***********************************************************************
00243         
00244                 Start returning columns from the beginning.
00245 
00246         ***********************************************************************/
00247 
00248         void reset ()
00249         {
00250                 index = 0;
00251         }
00252 
00253         /***********************************************************************
00254         
00255                 Return width of the current column
00256 
00257         ***********************************************************************/
00258 
00259         int getWidth ()
00260         {
00261                 if (rightAlign)
00262                    {
00263                    int i = index;
00264                 
00265                    if (i == 0)
00266                        ++i;
00267 
00268                    if (i < columns.length)
00269                        return columns[i] - columns[i-1];
00270                    }
00271                 return 0;
00272         }
00273 
00274         /***********************************************************************
00275         
00276                 Returns next column in the sequence. Assume that we'll be
00277                 invoked (quasi-legally) when there's no more columns left.
00278 
00279         ***********************************************************************/
00280 
00281         int next ()
00282         {
00283                 if (index < columns.length)
00284                     ++index;
00285 
00286                 return columns [index-1];
00287         }
00288 }
00289 

Generated on Sun Nov 7 19:06:50 2004 for Mango by doxygen 1.3.6