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

Generated on Sat Apr 9 20:11:25 2005 for Mango by doxygen 1.3.6