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 *******************************************************************************/
00053 
00054 class AbstractWriter : IWriter
00055 {       
00056         /***********************************************************************
00057 
00058         ***********************************************************************/
00059 
00060         struct NumericEncoder
00061         {
00062                 BufferConverter         int1,
00063                                         int8,
00064                                         int16,
00065                                         int32,
00066                                         int64,
00067                                         int8u,
00068                                         int16u,
00069                                         int32u,
00070                                         int64u,
00071                                         float32,
00072                                         float64,
00073                                         float80;
00074         }
00075 
00076         /***********************************************************************
00077 
00078         ***********************************************************************/
00079 
00080         struct StringEncoder
00081         {
00082                 BufferConverter         char8,
00083                                         char16,
00084                                         char32;
00085         }
00086 
00087         // public newline adaptor
00088         static INewlineWriter           newline;                
00089 
00090         // a couple of pre-constructed exceptions 
00091         protected static IOException    ovf;
00092         protected static EofException   eof;
00093 
00094         protected IBuffer               buffer;
00095 
00096         protected StringEncoder         string;
00097 
00098         protected NumericEncoder        numeric;
00099 
00100         private bool                    prefixArray = true;
00101 
00102         /***********************************************************************
00103         
00104                 Return the name of this writer
00105 
00106         ***********************************************************************/
00107 
00108         abstract char[] toString ();
00109 
00110         /***********************************************************************
00111         
00112                 Construct some static exception instances, and create the
00113                 public 'newline' instance.
00114 
00115         ***********************************************************************/
00116 
00117         static this ()
00118         {
00119                 newline = new NewlineWriter;
00120 
00121                 eof = new EofException ("eof during write");
00122                 ovf = new IOException  ("output buffer too small");
00123         }
00124 
00125         /***********************************************************************
00126         
00127                 Construct a Writer upon the provided IBuffer. All formatted
00128                 output will be appended to this buffer.
00129 
00130         ***********************************************************************/
00131 
00132         this (IBuffer buffer)
00133         {
00134                 this.buffer = buffer;
00135         }
00136      
00137         /***********************************************************************
00138         
00139                 Return the associated buffer
00140 
00141         ***********************************************************************/
00142 
00143         final IBuffer getBuffer ()
00144         {     
00145                 return buffer;
00146         }
00147 
00148         /***********************************************************************
00149         
00150                 Set the configured IStringEncoder. These are intended to
00151                 be used as a conversion mechanism between various character
00152                 representations. They are also expected to be used for the
00153                 process of applying character encodings.
00154 
00155                 See IStringEncoder.
00156 
00157         ***********************************************************************/
00158 
00159         final void setStringEncoder (IStringEncoder s) 
00160         {
00161                 string.char8  = &s.char8;
00162                 string.char16 = &s.char16;
00163                 string.char32 = &s.char32;
00164         }
00165 
00166         /***********************************************************************
00167         
00168                 Flush the output of this writer. Returns false if the 
00169                 operation failed, true otherwise.
00170 
00171         ***********************************************************************/
00172 
00173         IWriter flush ()
00174         {  
00175                 buffer.flush ();
00176                 return this;
00177         }
00178 
00179         /***********************************************************************
00180         
00181                 Output a newline. Do this indirectly so that it can be 
00182                 intercepted by subclasses.
00183 
00184         ***********************************************************************/
00185 
00186         IWriter cr ()
00187         {
00188                 return put (newline);
00189         }
00190 
00191         /***********************************************************************
00192 
00193         ***********************************************************************/
00194 
00195         void enableArrayPrefix (bool on)
00196         {
00197                 prefixArray = on;
00198         }
00199 
00200         /***********************************************************************
00201         
00202                 Write a class to the current buffer-position
00203                 
00204         ***********************************************************************/
00205 
00206         private final uint length (uint len)
00207         {
00208                 if (prefixArray)
00209                     put (len);
00210                 return len;
00211         }
00212 
00213         /***********************************************************************
00214         
00215                 Write a class to the current buffer-position
00216                 
00217         ***********************************************************************/
00218 
00219         IWriter put (IWritable x) 
00220         {
00221                 assert (x);
00222                 x.write (this); 
00223                 return this;
00224         }
00225 
00226         /***********************************************************************
00227         
00228                 Write a char value to the current buffer-position
00229                 
00230         ***********************************************************************/
00231 
00232         IWriter put (char x)
00233         {
00234                 string.char8 (&x, x.sizeof);
00235                 return this;
00236         }
00237 
00238         /***********************************************************************
00239         
00240                 Write a wide char value to the current buffer-position
00241                 
00242         ***********************************************************************/
00243 
00244         IWriter put (wchar x)
00245         {
00246                 string.char16 (&x, x.sizeof);
00247                 return this;
00248         }
00249 
00250         /***********************************************************************
00251         
00252                 Write a double char value to the current buffer-position
00253                 
00254         ***********************************************************************/
00255 
00256         IWriter put (dchar x)
00257         {
00258                 string.char32 (&x, x.sizeof);
00259                 return this;
00260         }
00261 
00262         /***********************************************************************
00263         
00264                 Write a char array to the current buffer-position
00265                 
00266         ***********************************************************************/
00267 
00268         IWriter put (char[] x) 
00269         {
00270                 string.char8 (x, length (x.length * char.sizeof));
00271                 return this;
00272         }
00273 
00274         /***********************************************************************
00275         
00276                 Write a char array to the current buffer-position
00277                 
00278         ***********************************************************************/
00279 
00280         IWriter putw (wchar[] x) 
00281         {
00282                 string.char16 (x, length (x.length * wchar.sizeof));
00283                 return this;
00284         }
00285 
00286         /***********************************************************************
00287         
00288                 Write a char array to the current buffer-position
00289                 
00290         ***********************************************************************/
00291 
00292         IWriter putd (dchar[] x)
00293         {
00294                 string.char32 (x, length (x.length * dchar.sizeof));
00295                 return this;
00296         }
00297 
00298         /***********************************************************************
00299         
00300                 Write a boolean value to the current buffer-position    
00301                 
00302         ***********************************************************************/
00303 
00304         IWriter put (bool x)
00305         {
00306                 numeric.int1 (&x, x.sizeof);
00307                 return this;
00308         }
00309 
00310         /***********************************************************************
00311         
00312                 Write an unsigned byte value to the current buffer-position     
00313                                 
00314         ***********************************************************************/
00315 
00316         IWriter put (ubyte x)
00317         {
00318                 numeric.int8u (&x, x.sizeof);
00319                 return this;
00320         }
00321 
00322         /***********************************************************************
00323         
00324                 Write a byte value to the current buffer-position
00325                 
00326         ***********************************************************************/
00327 
00328         IWriter put (byte x)
00329         {
00330                 numeric.int8 (&x, x.sizeof);
00331                 return this;
00332         }
00333 
00334         /***********************************************************************
00335         
00336                 Write an unsigned short value to the current buffer-position
00337                 
00338         ***********************************************************************/
00339 
00340         IWriter put (ushort x)
00341         {
00342                 numeric.int16u (&x, x.sizeof);
00343                 return this;
00344         }
00345 
00346         /***********************************************************************
00347         
00348                 Write a short value to the current buffer-position
00349                 
00350         ***********************************************************************/
00351 
00352         IWriter put (short x)
00353         {
00354                 numeric.int16 (&x, x.sizeof);
00355                 return this;
00356         }
00357 
00358         /***********************************************************************
00359         
00360                 Write a unsigned int value to the current buffer-position
00361                 
00362         ***********************************************************************/
00363 
00364         IWriter put (uint x)
00365         {
00366                 numeric.int32u (&x, x.sizeof);
00367                 return this;
00368         }
00369 
00370         /***********************************************************************
00371         
00372                 Write an int value to the current buffer-position
00373                 
00374         ***********************************************************************/
00375 
00376         IWriter put (int x)
00377         {
00378                 numeric.int32 (&x, x.sizeof);
00379                 return this;
00380         }
00381 
00382         /***********************************************************************
00383         
00384                 Write an unsigned long value to the current buffer-position
00385                 
00386         ***********************************************************************/
00387 
00388         IWriter put (ulong x)
00389         {
00390                 numeric.int64u (&x, x.sizeof);
00391                 return this;
00392         }
00393 
00394         /***********************************************************************
00395         
00396                 Write a long value to the current buffer-position
00397                 
00398         ***********************************************************************/
00399 
00400         IWriter put (long x)
00401         {
00402                 numeric.int64 (&x, x.sizeof);
00403                 return this;
00404         }
00405 
00406         /***********************************************************************
00407         
00408                 Write a float value to the current buffer-position
00409                 
00410         ***********************************************************************/
00411 
00412         IWriter put (float x)
00413         {
00414                 numeric.float32 (&x, x.sizeof);
00415                 return this;
00416         }
00417 
00418         /***********************************************************************
00419         
00420                 Write a double value to the current buffer-position
00421                 
00422         ***********************************************************************/
00423 
00424         IWriter put (double x)
00425         {
00426                 numeric.float64 (&x, x.sizeof);
00427                 return this;
00428         }
00429 
00430         /***********************************************************************
00431         
00432                 Write a real value to the current buffer-position
00433                 
00434         ***********************************************************************/
00435 
00436         IWriter put (real x)
00437         {
00438                 numeric.float80 (&x, x.sizeof);
00439                 return this;
00440         }
00441 
00442 
00443         /**********************************************************************/
00444         /*************** opShl() is just an alias for put *********************/
00445         /**********************************************************************/
00446 
00447 
00448         version (UseShiftOperators)
00449         {      
00450                 /***************************************************************
00451 
00452                 ***************************************************************/
00453 
00454                 IWriter opShl (bit x)
00455                 {
00456                         return put (x);
00457                 }
00458 
00459                 /***************************************************************
00460 
00461                 ***************************************************************/
00462 
00463                 IWriter opShl (ubyte x)
00464                 {
00465                         return put (x);
00466                 }
00467 
00468                 /***************************************************************
00469 
00470                 ***************************************************************/
00471 
00472                 IWriter opShl (byte x)
00473                 {
00474                         return put (x);
00475                 }
00476 
00477                 /***************************************************************
00478 
00479                 ***************************************************************/
00480 
00481                 IWriter opShl (ushort x)
00482                 {
00483                         return put (x);
00484                 }
00485 
00486                 /***************************************************************
00487 
00488                 ***************************************************************/
00489 
00490                 IWriter opShl (short x)
00491                 {
00492                         return put (x);
00493                 }
00494 
00495                 /***************************************************************
00496 
00497                 ***************************************************************/
00498 
00499                 IWriter opShl (uint x)
00500                 {
00501                         return put (x);
00502                 }
00503 
00504                 /***************************************************************
00505 
00506                 ***************************************************************/
00507 
00508                 IWriter opShl (int x)
00509                 {
00510                         return put (x);
00511                 }
00512 
00513                 /***************************************************************
00514 
00515                 ***************************************************************/
00516 
00517                 IWriter opShl (ulong x)
00518                 {
00519                         return put (x);
00520                 }
00521 
00522                 /***************************************************************
00523 
00524                 ***************************************************************/
00525 
00526                 IWriter opShl (long x)
00527                 {
00528                         return put (x);
00529                 }
00530 
00531                 /***************************************************************
00532 
00533                 ***************************************************************/
00534 
00535                 IWriter opShl (float x)
00536                 {
00537                         return put (x);
00538                 }
00539 
00540                 /***************************************************************
00541 
00542                 ***************************************************************/
00543 
00544                 IWriter opShl (double x)
00545                 {
00546                         return put (x);
00547                 }
00548 
00549                 /***************************************************************
00550 
00551                 ***************************************************************/
00552 
00553                 IWriter opShl (real x)
00554                 {
00555                         return put (x);
00556                 }
00557 
00558                 /***************************************************************
00559 
00560                 ***************************************************************/
00561 
00562                 IWriter opShl (IWritable x) 
00563                 {
00564                         return put (x);
00565                 }
00566 
00567                 /***************************************************************
00568 
00569                 ***************************************************************/
00570 
00571                 IWriter opShl (char x)
00572                 {
00573                         return put (x);
00574                 }
00575 
00576                 /***************************************************************
00577 
00578                 ***************************************************************/
00579 
00580                 IWriter opShl (wchar x)
00581                 {
00582                         return put (x);
00583                 }
00584 
00585                 /***************************************************************
00586 
00587                 ***************************************************************/
00588 
00589                 IWriter opShl (dchar x)
00590                 {
00591                         return put (x);
00592                 }
00593 
00594                 /***************************************************************
00595 
00596                 ***************************************************************/
00597 
00598                 IWriter opShl (char[] x)
00599                 {
00600                         return put (x);
00601                 }
00602 
00603                 /***************************************************************
00604 
00605                 ***************************************************************/
00606 
00607                 IWriter opShl (wchar[] x) 
00608                 {
00609                         return putw (x);
00610                 }
00611 
00612                 /***************************************************************
00613 
00614                 ***************************************************************/
00615 
00616                 IWriter opShl (dchar[] x)
00617                 {
00618                         return putd (x);
00619                 }
00620         }
00621 }
00622 
00623 
00624 /*******************************************************************************
00625 
00626         A class to handle newline output. One might reasonable expect to 
00627         emit a char[] for newlines; FileSystem.NewlineString for example.
00628         Turns out that it's much more efficient to intercept line-breaks
00629         when they're implemented in a more formal manner (such as this).
00630 
00631         For example, ColumnWriter() and TextWriter() both must intercept 
00632         newline output so they can adjust formatting appropriately. It is 
00633         much more efficient for such writers to intercept the IWritable 
00634         put() method instead of scanning each char[] for the various \\n 
00635         combinations.
00636         
00637         Please use the INewlineWriter interface for emitting newlines.
00638 
00639 *******************************************************************************/
00640 
00641 private import mango.io.FileSystem;
00642 
00643 class NewlineWriter : INewlineWriter
00644 {
00645         private char[]  fmt;
00646 
00647         /***********************************************************************
00648 
00649                 Construct a default newline, using the char[] defined 
00650                 by FileSystem.NewlineString
00651         
00652         ***********************************************************************/
00653 
00654         this ()
00655         {
00656                 this (FileSystem.NewlineString);
00657         }
00658 
00659         /***********************************************************************
00660         
00661                 Construct a newline using the provided character array
00662 
00663         ***********************************************************************/
00664 
00665         this (char[] fmt)
00666         {
00667                 this.fmt = fmt;
00668         }
00669 
00670         /***********************************************************************
00671         
00672                 Write this newline through the provided writer. This makes
00673                 NewlineWriter IWritable compatible.
00674 
00675         ***********************************************************************/
00676 
00677         void write (IWriter w)
00678         {
00679                 w.put (fmt);
00680         }     
00681 }

Generated on Sun Oct 24 22:31:12 2004 for Mango by doxygen 1.3.6