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

AbstractWriter.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file AbstractWriter.d
00004         
00005 
00006         Copyright (C) 2004 Kris Bell
00007         
00008         This software is provided 'as-is', without any express or implied
00009         warranty. In no event will the authors be held liable for damages
00010         of any kind arising from the use of this software.
00011         
00012         Permission is hereby granted to anyone to use this software for any 
00013         purpose, including commercial applications, and to alter it and/or 
00014         redistribute it freely, subject to the following restrictions:
00015         
00016         1. The origin of this software must not be misrepresented; you must 
00017            not claim that you wrote the original software. If you use this 
00018            software in a product, an acknowledgment within documentation of 
00019            said product would be appreciated but is not required.
00020 
00021         2. Altered source versions must be plainly marked as such, and must 
00022            not be misrepresented as being the original software.
00023 
00024         3. This notice may not be removed or altered from any distribution
00025            of the source.
00026 
00027 
00028                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00029 
00030 
00031         @version        Initial version, October 2004      
00032         @author         Kris
00033 
00034 *******************************************************************************/
00035 
00036 module mango.io.AbstractWriter;
00037 
00038 private import  mango.io.Exception;
00039 
00040 public  import  mango.io.model.IWriter,
00041                 mango.io.model.IBuffer,
00042                 mango.io.model.IConduit;
00043 
00044 /*******************************************************************************
00045 
00046         Writer base-class. Writers provide the means to append formatted 
00047         data to an IBuffer, and expose a convenient method of handling a
00048         variety of data types. In addition to writing native types such
00049         as integer and char[], writers also process any class which has
00050         implemented the IWritable interface (one method).
00051 
00052         Writers support both a C++ iostream type syntax, along with a put()
00053         syntax. Operations may be chained back-to-back.
00054 
00055         All writers support the full set of native data types, plus a
00056         selection of array types. The latter can be configured to produce
00057         either a copy (.dup) of the buffer content, or a slice. See class
00058         SimpleAllocator, BufferAllocator and SliceAllocator for more on 
00059         this topic.
00060 
00061         The code below illustrates basic operation upon a memory buffer:
00062         
00063         @code
00064         Buffer buf = new Buffer (256);
00065 
00066         // map same buffer into both reader and writer
00067         IReader r = new Reader(buf);
00068         IWriter w = new Writer(buf);
00069 
00070         int i = 10;
00071         long j = 20;
00072         double d = 3.14159;
00073         char[] c = "fred";
00074 
00075         // write data types out
00076         w << c << i << j << d;
00077 
00078         // read them back again
00079         r >> c >> i >> j >> d;
00080 
00081         // reset
00082         buf.clear();
00083 
00084         // same thing again, but using put() syntax instead
00085         w.put(c).put(i).put(j).put(d);
00086         r.get(c).get(i).get(j).get(d);
00087 
00088         @endcode
00089 
00090         Writers may also be used with any class implementing the IWritable
00091         interface. See PickleReader for an example of how this can be put
00092         to good use.
00093         
00094 *******************************************************************************/
00095 
00096 class AbstractWriter : IWriter
00097 {       
00098         /***********************************************************************
00099 
00100         ***********************************************************************/
00101 
00102         struct NumericEncoder
00103         {
00104                 BufferConverter         int1,
00105                                         int8,
00106                                         int16,
00107                                         int32,
00108                                         int64,
00109                                         int8u,
00110                                         int16u,
00111                                         int32u,
00112                                         int64u,
00113                                         float32,
00114                                         float64,
00115                                         float80;
00116         }
00117 
00118         /***********************************************************************
00119 
00120         ***********************************************************************/
00121 
00122         struct StringEncoder
00123         {
00124                 BufferConverter         char8,
00125                                         char16,
00126                                         char32;
00127         }
00128 
00129         // public newline adaptor
00130         static INewlineWriter           newline;                
00131 
00132         // a couple of pre-constructed exceptions 
00133         protected static IOException    ovf;
00134         protected static EofException   eof;
00135 
00136         protected IBuffer               buffer;
00137 
00138         protected StringEncoder         string;
00139 
00140         protected NumericEncoder        numeric;
00141 
00142         private bool                    prefixArray = true;
00143 
00144         /***********************************************************************
00145         
00146                 Return the name of this writer
00147 
00148         ***********************************************************************/
00149 
00150         abstract char[] toString ();
00151 
00152         /***********************************************************************
00153         
00154                 Construct some static exception instances, and create the
00155                 public 'newline' instance.
00156 
00157         ***********************************************************************/
00158 
00159         static this ()
00160         {
00161                 newline = new NewlineWriter;
00162 
00163                 eof = new EofException ("eof during write");
00164                 ovf = new IOException  ("output buffer too small");
00165         }
00166 
00167         /***********************************************************************
00168         
00169                 Construct a Writer upon the provided IBuffer. All formatted
00170                 output will be appended to this buffer.
00171 
00172         ***********************************************************************/
00173 
00174         this (IBuffer buffer)
00175         {
00176                 this.buffer = buffer;
00177         }
00178      
00179         /***********************************************************************
00180         
00181                 Return the associated buffer
00182 
00183         ***********************************************************************/
00184 
00185         final IBuffer getBuffer ()
00186         {     
00187                 return buffer;
00188         }
00189 
00190         /***********************************************************************
00191         
00192                 Set the configured IStringEncoder. These are intended to
00193                 be used as a conversion mechanism between various character
00194                 representations. They are also expected to be used for the
00195                 process of applying character encodings.
00196 
00197                 See IStringEncoder.
00198 
00199         ***********************************************************************/
00200 
00201         final void setStringEncoder (IStringEncoder s) 
00202         {
00203                 string.char8  = &s.char8;
00204                 string.char16 = &s.char16;
00205                 string.char32 = &s.char32;
00206         }
00207 
00208         /***********************************************************************
00209         
00210                 Flush the output of this writer. Returns false if the 
00211                 operation failed, true otherwise.
00212 
00213         ***********************************************************************/
00214 
00215         IWriter flush ()
00216         {  
00217                 buffer.flush ();
00218                 return this;
00219         }
00220 
00221         /***********************************************************************
00222         
00223                 Output a newline. Do this indirectly so that it can be 
00224                 intercepted by subclasses.
00225 
00226         ***********************************************************************/
00227 
00228         IWriter cr ()
00229         {
00230                 return put (newline);
00231         }
00232 
00233         /***********************************************************************
00234 
00235         ***********************************************************************/
00236 
00237         void enableArrayPrefix (bool on)
00238         {
00239                 prefixArray = on;
00240         }
00241 
00242         /***********************************************************************
00243         
00244                 Write a class to the current buffer-position
00245                 
00246         ***********************************************************************/
00247 
00248         private final uint length (uint len)
00249         {
00250                 if (prefixArray)
00251                     put (len);
00252                 return len;
00253         }
00254 
00255         /***********************************************************************
00256         
00257                 Write a class to the current buffer-position
00258                 
00259         ***********************************************************************/
00260 
00261         IWriter put (IWritable x) 
00262         {
00263                 assert (x);
00264                 x.write (this); 
00265                 return this;
00266         }
00267 
00268         /***********************************************************************
00269         
00270                 Write a char value to the current buffer-position
00271                 
00272         ***********************************************************************/
00273 
00274         IWriter put (char x)
00275         {
00276                 string.char8 (&x, x.sizeof);
00277                 return this;
00278         }
00279 
00280         /***********************************************************************
00281         
00282                 Write a wide char value to the current buffer-position
00283                 
00284         ***********************************************************************/
00285 
00286         IWriter put (wchar x)
00287         {
00288                 string.char16 (&x, x.sizeof);
00289                 return this;
00290         }
00291 
00292         /***********************************************************************
00293         
00294                 Write a double char value to the current buffer-position
00295                 
00296         ***********************************************************************/
00297 
00298         IWriter put (dchar x)
00299         {
00300                 string.char32 (&x, x.sizeof);
00301                 return this;
00302         }
00303 
00304         /***********************************************************************
00305         
00306                 Write a char array to the current buffer-position
00307                 
00308         ***********************************************************************/
00309 
00310         IWriter put (char[] x) 
00311         {
00312                 string.char8 (x, length (x.length * char.sizeof));
00313                 return this;
00314         }
00315 
00316         /***********************************************************************
00317         
00318                 Write a char array to the current buffer-position
00319                 
00320         ***********************************************************************/
00321 
00322         IWriter putw (wchar[] x) 
00323         {
00324                 string.char16 (x, length (x.length * wchar.sizeof));
00325                 return this;
00326         }
00327 
00328         /***********************************************************************
00329         
00330                 Write a char array to the current buffer-position
00331                 
00332         ***********************************************************************/
00333 
00334         IWriter putd (dchar[] x)
00335         {
00336                 string.char32 (x, length (x.length * dchar.sizeof));
00337                 return this;
00338         }
00339 
00340         /***********************************************************************
00341         
00342                 Write a boolean value to the current buffer-position    
00343                 
00344         ***********************************************************************/
00345 
00346         IWriter put (bool x)
00347         {
00348                 numeric.int1 (&x, x.sizeof);
00349                 return this;
00350         }
00351 
00352         /***********************************************************************
00353         
00354                 Write an unsigned byte value to the current buffer-position     
00355                                 
00356         ***********************************************************************/
00357 
00358         IWriter put (ubyte x)
00359         {
00360                 numeric.int8u (&x, x.sizeof);
00361                 return this;
00362         }
00363 
00364         /***********************************************************************
00365         
00366                 Write a byte value to the current buffer-position
00367                 
00368         ***********************************************************************/
00369 
00370         IWriter put (byte x)
00371         {
00372                 numeric.int8 (&x, x.sizeof);
00373                 return this;
00374         }
00375 
00376         /***********************************************************************
00377         
00378                 Write an unsigned short value to the current buffer-position
00379                 
00380         ***********************************************************************/
00381 
00382         IWriter put (ushort x)
00383         {
00384                 numeric.int16u (&x, x.sizeof);
00385                 return this;
00386         }
00387 
00388         /***********************************************************************
00389         
00390                 Write a short value to the current buffer-position
00391                 
00392         ***********************************************************************/
00393 
00394         IWriter put (short x)
00395         {
00396                 numeric.int16 (&x, x.sizeof);
00397                 return this;
00398         }
00399 
00400         /***********************************************************************
00401         
00402                 Write a unsigned int value to the current buffer-position
00403                 
00404         ***********************************************************************/
00405 
00406         IWriter put (uint x)
00407         {
00408                 numeric.int32u (&x, x.sizeof);
00409                 return this;
00410         }
00411 
00412         /***********************************************************************
00413         
00414                 Write an int value to the current buffer-position
00415                 
00416         ***********************************************************************/
00417 
00418         IWriter put (int x)
00419         {
00420                 numeric.int32 (&x, x.sizeof);
00421                 return this;
00422         }
00423 
00424         /***********************************************************************
00425         
00426                 Write an unsigned long value to the current buffer-position
00427                 
00428         ***********************************************************************/
00429 
00430         IWriter put (ulong x)
00431         {
00432                 numeric.int64u (&x, x.sizeof);
00433                 return this;
00434         }
00435 
00436         /***********************************************************************
00437         
00438                 Write a long value to the current buffer-position
00439                 
00440         ***********************************************************************/
00441 
00442         IWriter put (long x)
00443         {
00444                 numeric.int64 (&x, x.sizeof);
00445                 return this;
00446         }
00447 
00448         /***********************************************************************
00449         
00450                 Write a float value to the current buffer-position
00451                 
00452         ***********************************************************************/
00453 
00454         IWriter put (float x)
00455         {
00456                 numeric.float32 (&x, x.sizeof);
00457                 return this;
00458         }
00459 
00460         /***********************************************************************
00461         
00462                 Write a double value to the current buffer-position
00463                 
00464         ***********************************************************************/
00465 
00466         IWriter put (double x)
00467         {
00468                 numeric.float64 (&x, x.sizeof);
00469                 return this;
00470         }
00471 
00472         /***********************************************************************
00473         
00474                 Write a real value to the current buffer-position
00475                 
00476         ***********************************************************************/
00477 
00478         IWriter put (real x)
00479         {
00480                 numeric.float80 (&x, x.sizeof);
00481                 return this;
00482         }
00483 
00484 
00485         /**********************************************************************/
00486         /*************** opShl() is just an alias for put *********************/
00487         /**********************************************************************/
00488 
00489 
00490         version (UseShiftOperators)
00491         {      
00492                 /***************************************************************
00493 
00494                 ***************************************************************/
00495 
00496                 IWriter opShl (bit x)
00497                 {
00498                         return put (x);
00499                 }
00500 
00501                 /***************************************************************
00502 
00503                 ***************************************************************/
00504 
00505                 IWriter opShl (ubyte x)
00506                 {
00507                         return put (x);
00508                 }
00509 
00510                 /***************************************************************
00511 
00512                 ***************************************************************/
00513 
00514                 IWriter opShl (byte x)
00515                 {
00516                         return put (x);
00517                 }
00518 
00519                 /***************************************************************
00520 
00521                 ***************************************************************/
00522 
00523                 IWriter opShl (ushort x)
00524                 {
00525                         return put (x);
00526                 }
00527 
00528                 /***************************************************************
00529 
00530                 ***************************************************************/
00531 
00532                 IWriter opShl (short x)
00533                 {
00534                         return put (x);
00535                 }
00536 
00537                 /***************************************************************
00538 
00539                 ***************************************************************/
00540 
00541                 IWriter opShl (uint x)
00542                 {
00543                         return put (x);
00544                 }
00545 
00546                 /***************************************************************
00547 
00548                 ***************************************************************/
00549 
00550                 IWriter opShl (int x)
00551                 {
00552                         return put (x);
00553                 }
00554 
00555                 /***************************************************************
00556 
00557                 ***************************************************************/
00558 
00559                 IWriter opShl (ulong x)
00560                 {
00561                         return put (x);
00562                 }
00563 
00564                 /***************************************************************
00565 
00566                 ***************************************************************/
00567 
00568                 IWriter opShl (long x)
00569                 {
00570                         return put (x);
00571                 }
00572 
00573                 /***************************************************************
00574 
00575                 ***************************************************************/
00576 
00577                 IWriter opShl (float x)
00578                 {
00579                         return put (x);
00580                 }
00581 
00582                 /***************************************************************
00583 
00584                 ***************************************************************/
00585 
00586                 IWriter opShl (double x)
00587                 {
00588                         return put (x);
00589                 }
00590 
00591                 /***************************************************************
00592 
00593                 ***************************************************************/
00594 
00595                 IWriter opShl (real x)
00596                 {
00597                         return put (x);
00598                 }
00599 
00600                 /***************************************************************
00601 
00602                 ***************************************************************/
00603 
00604                 IWriter opShl (IWritable x) 
00605                 {
00606                         return put (x);
00607                 }
00608 
00609                 /***************************************************************
00610 
00611                 ***************************************************************/
00612 
00613                 IWriter opShl (char x)
00614                 {
00615                         return put (x);
00616                 }
00617 
00618                 /***************************************************************
00619 
00620                 ***************************************************************/
00621 
00622                 IWriter opShl (wchar x)
00623                 {
00624                         return put (x);
00625                 }
00626 
00627                 /***************************************************************
00628 
00629                 ***************************************************************/
00630 
00631                 IWriter opShl (dchar x)
00632                 {
00633                         return put (x);
00634                 }
00635 
00636                 /***************************************************************
00637 
00638                 ***************************************************************/
00639 
00640                 IWriter opShl (char[] x)
00641                 {
00642                         return put (x);
00643                 }
00644 
00645                 /***************************************************************
00646 
00647                 ***************************************************************/
00648 
00649                 IWriter opShl (wchar[] x) 
00650                 {
00651                         return putw (x);
00652                 }
00653 
00654                 /***************************************************************
00655 
00656                 ***************************************************************/
00657 
00658                 IWriter opShl (dchar[] x)
00659                 {
00660                         return putd (x);
00661                 }
00662         }
00663 }
00664 
00665 
00666 /*******************************************************************************
00667 
00668         A class to handle newline output. One might reasonable expect to 
00669         emit a char[] for newlines; FileSystem.NewlineString for example.
00670         Turns out that it's much more efficient to intercept line-breaks
00671         when they're implemented in a more formal manner (such as this).
00672 
00673         For example, ColumnWriter() and TextWriter() both must intercept 
00674         newline output so they can adjust formatting appropriately. It is 
00675         much more efficient for such writers to intercept the IWritable 
00676         put() method instead of scanning each char[] for the various \\n 
00677         combinations.
00678         
00679         Please use the INewlineWriter interface for emitting newlines.
00680 
00681 *******************************************************************************/
00682 
00683 private import mango.io.FileSystem;
00684 
00685 class NewlineWriter : INewlineWriter
00686 {
00687         private char[]  fmt;
00688 
00689         /***********************************************************************
00690 
00691                 Construct a default newline, using the char[] defined 
00692                 by FileSystem.NewlineString
00693         
00694         ***********************************************************************/
00695 
00696         this ()
00697         {
00698                 this (FileSystem.NewlineString);
00699         }
00700 
00701         /***********************************************************************
00702         
00703                 Construct a newline using the provided character array
00704 
00705         ***********************************************************************/
00706 
00707         this (char[] fmt)
00708         {
00709                 this.fmt = fmt;
00710         }
00711 
00712         /***********************************************************************
00713         
00714                 Write this newline through the provided writer. This makes
00715                 NewlineWriter IWritable compatible.
00716 
00717         ***********************************************************************/
00718 
00719         void write (IWriter w)
00720         {
00721                 w.put (fmt);
00722         }     
00723 }

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