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

AbstractReader.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file AbstractReader.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, October 2004      
00034         @author         Kris, Ivan Senji (the "alias opShr get" idea)
00035 
00036 
00037 *******************************************************************************/
00038 
00039 module mango.io.AbstractReader;
00040 
00041 private import  mango.io.Exception,
00042                 mango.io.ArrayAllocator;
00043 
00044 public  import  mango.io.model.IReader,
00045                 mango.io.model.IBuffer,
00046                 mango.io.model.IConduit;
00047 
00048 
00049 /*******************************************************************************
00050 
00051         Reader base-class. Each reader operates upon an IBuffer, which is
00052         provided at construction time. Said buffer is intended to remain 
00053         consistent over the reader lifetime.
00054 
00055         Readers support both a C++ iostream type syntax, along with a get()
00056         syntax. Operations may be chained back-to-back.
00057 
00058         All readers support the full set of native data types, plus a full
00059         selection of array types. The latter can be configured to produce
00060         either a copy (.dup) of the buffer content, or a slice. See class
00061         SimpleAllocator, BufferAllocator and SliceAllocator for more on 
00062         this topic.
00063 
00064         The code below illustrates basic operation upon a memory buffer:
00065         
00066         @code
00067         Buffer buf = new Buffer (256);
00068 
00069         // map same buffer into both reader and writer
00070         IReader r = new Reader(buf);
00071         IWriter w = new Writer(buf);
00072 
00073         int i = 10;
00074         long j = 20;
00075         double d = 3.14159;
00076         char[] c = "fred";
00077 
00078         // write data types out
00079         w << c << i << j << d;
00080 
00081         // read them back again
00082         r >> c >> i >> j >> d;
00083 
00084         // reset
00085         buf.clear();
00086 
00087         // same thing again, but using get() syntax instead
00088         w.put(c).put(i).put(j).put(d);
00089         r.get(c).get(i).get(j).get(d);
00090 
00091         @endcode
00092 
00093         Readers may also be used with any class implementing the IReadable
00094         interface. See PickleReader for an example of how this can be put
00095         to good use.
00096         
00097 *******************************************************************************/
00098 
00099 class AbstractReader : SimpleAllocator, IReader
00100 {       
00101         alias opShr get;
00102           
00103         /***********************************************************************
00104 
00105         ***********************************************************************/
00106 
00107         union Decoder
00108         {
00109                 struct {
00110                        BufferDecoder    int1,
00111                                         int8,
00112                                         int16,
00113                                         int32,
00114                                         int64,
00115                                         int8u,
00116                                         int16u,
00117                                         int32u,
00118                                         int64u,
00119                                         float32,
00120                                         float64,
00121                                         float80,
00122                                         char8,
00123                                         char16,
00124                                         char32;
00125                        }
00126                 BufferDecoder[15]       decoders;
00127         }
00128 
00129         // the buffer associated with this reader. Note that this
00130         // must not change for the lifetime of the reader, since
00131         // it is assumed to be immutable elsewhere (subclass may
00132         // keep its own copy).
00133         protected IBuffer               buffer;         
00134 
00135         // buffer decoders
00136         protected Decoder               decode;
00137 
00138         // memory-manager for array requests
00139         private IArrayAllocator         memory;
00140 
00141         // size for client-specified allocations
00142         private uint                    pushed = uint.max;
00143 
00144         /***********************************************************************
00145         
00146                 Return the buffer associated with this reader
00147 
00148         ***********************************************************************/
00149 
00150         this (IBuffer buffer)
00151         {
00152                 this.buffer = buffer;
00153                 setAllocator (this);
00154         }
00155 
00156         /***********************************************************************
00157         
00158                 Return the buffer associated with this reader
00159 
00160         ***********************************************************************/
00161 
00162         final IBuffer getBuffer ()
00163         {
00164                 return buffer;
00165         }
00166 
00167         /***********************************************************************
00168         
00169                 Return the allocator associated with this reader.See 
00170                 ArrayAllocator for more information.
00171 
00172         ***********************************************************************/
00173 
00174         final IArrayAllocator getAllocator ()
00175         {
00176                 return memory;
00177         }
00178 
00179         /***********************************************************************
00180         
00181                 Set the allocator to use for array management. Arrays are
00182                 always allocated by the IReader. That is, you cannot read
00183                 data into an array slice (for example). Instead, a number
00184                 of IArrayAllocator classes are available to manage memory
00185                 allocation when reading array content. 
00186 
00187                 By default, an IReader will allocate each array from the 
00188                 heap. You can change that behavior by calling this method
00189                 with an IArrayAllocator of choice. For instance, there 
00190                 is a BufferAllocator which will slice an array directly 
00191                 from the buffer where possible. Also available is the 
00192                 record-oriented SliceAllocator, which slices memory from 
00193                 within a pre-allocated heap area, and should be reset by
00194                 the client code after each record has been read (to avoid 
00195                 unnecessary growth).
00196 
00197                 See ArrayAllocator for more information.
00198 
00199         ***********************************************************************/
00200 
00201         final void setAllocator (IArrayAllocator memory) 
00202         {
00203                 memory.bind (this);
00204                 this.memory = memory;
00205         }
00206 
00207         /***********************************************************************
00208         
00209                 Bind an IDecoder to the writer. Decoders are intended to
00210                 be used as a conversion mechanism between various character
00211                 representations (encodings), or the translation of any data
00212                 type from one representation to another. Each data type may
00213                 be configured with a distinct decoder, covering all native
00214                 types (15 in total).
00215 
00216                 An appropriate decoder set should be attached to each 
00217                 IReader, and thus be available for subsequent use. A raw 
00218                 binary implementation is attached by default (no encoding).
00219 
00220                 See module mango.icu.UMango for an example of decoder 
00221                 implementation -- those classes bind the ICU converters 
00222                 to this IO package.
00223 
00224         ***********************************************************************/
00225 
00226         final void setDecoder (IDecoder d) 
00227         {
00228                 decode.decoders[d.type] = d.bind (this);
00229         }
00230 
00231         /***********************************************************************
00232         
00233                 Push the size (in bytes) to use for the next array-read.
00234                 By default, array sizes are read from the input stream, 
00235                 so this is the means by which one may specify the size
00236                 where the stream is not formatted in such a manner.
00237 
00238                 @code
00239                         char[]  x;
00240                         int     size;
00241                         IReader reader;
00242 
00243                         reader.push(size).get(x);
00244                 @endcode
00245                 
00246         ***********************************************************************/
00247 
00248         final IReader push (uint size)
00249         {
00250                 if (pushed == uint.max)
00251                     pushed = size;
00252                 else
00253                    throw new IOException ("invalid IReader push-sequence");
00254                 return this;
00255         }
00256 
00257         /***********************************************************************
00258         
00259                 Read and return an integer from the input stream. This can
00260                 be used to extract the length of a subsequent array.
00261 
00262         ***********************************************************************/
00263 
00264         final uint length ()
00265         {
00266                 uint len = pushed;
00267 
00268                 if (len != uint.max)
00269                     pushed = uint.max;
00270                 else
00271                    get (len);
00272                 return len;
00273         }
00274 
00275         /***********************************************************************
00276         
00277                 Wait for something to arrive in the buffer. This may stall
00278                 the current thread forever, although usage of SocketConduit 
00279                 will take advantage of the timeout facilities provided there.
00280 
00281         ***********************************************************************/
00282 
00283         final void wait ()
00284         {       
00285                 buffer.get (1, false);
00286         }
00287 
00288         /***********************************************************************
00289         
00290                 Extract a readable class from the current read-position
00291                 
00292         ***********************************************************************/
00293 
00294         final IReader opShr (IReadable x) 
00295         {
00296                 assert (x);
00297                 x.read (this); 
00298                 return this;
00299         }
00300 
00301         /***********************************************************************
00302 
00303                 Extract a boolean value from the current read-position  
00304                 
00305         ***********************************************************************/
00306 
00307         IReader opShr (inout bool x)
00308         {
00309                 decode.int1 (&x, x.sizeof);
00310                 return this;
00311         }
00312 
00313         /***********************************************************************
00314 
00315                 Extract an unsigned byte value from the current read-position   
00316                                 
00317         ***********************************************************************/
00318 
00319         IReader opShr (inout ubyte x) 
00320         {       
00321                 decode.int8u (&x, x.sizeof);
00322                 return this;
00323         }
00324 
00325         /***********************************************************************
00326         
00327                 Extract a byte value from the current read-position
00328                 
00329         ***********************************************************************/
00330 
00331         IReader opShr (inout byte x)
00332         {
00333                 decode.int8 (&x, x.sizeof);
00334                 return this;
00335         }
00336 
00337         /***********************************************************************
00338         
00339                 Extract an unsigned short value from the current read-position
00340                 
00341         ***********************************************************************/
00342 
00343         IReader opShr (inout ushort x)
00344         {
00345                 //xx (*cast(void[]*)&(&x)[0..1]);
00346                 decode.int16u (&x, x.sizeof);
00347                 return this;
00348         }
00349 
00350         /***********************************************************************
00351         
00352                 Extract a short value from the current read-position
00353                 
00354         ***********************************************************************/
00355 
00356         IReader opShr (inout short x)
00357         {
00358                 decode.int16 (&x, x.sizeof);
00359                 return this;
00360         }
00361 
00362         /***********************************************************************
00363         
00364                 Extract a unsigned int value from the current read-position
00365                 
00366         ***********************************************************************/
00367 
00368         IReader opShr (inout uint x)
00369         {
00370                 decode.int32u (&x, x.sizeof);
00371                 return this;
00372         }
00373 
00374         /***********************************************************************
00375         
00376                 Extract an int value from the current read-position
00377                 
00378         ***********************************************************************/
00379 
00380         IReader opShr (inout int x)
00381         {
00382                 decode.int32 (&x, x.sizeof);
00383                 return this;
00384         }
00385 
00386         /***********************************************************************
00387         
00388                 Extract an unsigned long value from the current read-position
00389                 
00390         ***********************************************************************/
00391 
00392         IReader opShr (inout ulong x)
00393         {
00394                 decode.int64u (&x, x.sizeof);
00395                 return this;
00396         }
00397 
00398         /***********************************************************************
00399         
00400                 Extract a long value from the current read-position
00401                 
00402         ***********************************************************************/
00403 
00404         IReader opShr (inout long x)
00405         {
00406                 decode.int64 (&x, x.sizeof);
00407                 return this;
00408         }
00409 
00410         /***********************************************************************
00411         
00412                 Extract a float value from the current read-position
00413                 
00414         ***********************************************************************/
00415 
00416         IReader opShr (inout float x)
00417         {
00418                 decode.float32 (&x, x.sizeof);
00419                 return this;
00420         }
00421 
00422         /***********************************************************************
00423         
00424                 Extract a double value from the current read-position
00425                 
00426         ***********************************************************************/
00427 
00428         IReader opShr (inout double x)
00429         {
00430                 decode.float64 (&x, x.sizeof);
00431                 return this;
00432         }
00433 
00434         /***********************************************************************
00435         
00436                 Extract a real value from the current read-position
00437                 
00438         ***********************************************************************/
00439 
00440         IReader opShr (inout real x)
00441         {
00442                 decode.float80 (&x, x.sizeof);
00443                 return this;
00444         }
00445 
00446         /***********************************************************************
00447         
00448                 Extract a char value from the current read-position
00449                 
00450         ***********************************************************************/
00451 
00452         IReader opShr (inout char x)
00453         {
00454                 decode.char8 (&x, x.sizeof);
00455                 return this;
00456         }
00457 
00458         /***********************************************************************
00459         
00460                 Extract a wide char value from the current read-position
00461                 
00462         ***********************************************************************/
00463 
00464         IReader opShr (inout wchar x)
00465         {
00466                 decode.char16 (&x, x.sizeof);
00467                 return this;
00468         }
00469 
00470         /***********************************************************************
00471         
00472                 Extract a double char value from the current read-position
00473                 
00474         ***********************************************************************/
00475 
00476         IReader opShr (inout dchar x)
00477         {
00478                 decode.char32 (&x, x.sizeof);
00479                 return this;
00480         }
00481 
00482         /***********************************************************************
00483 
00484                 Extract an unsigned byte value from the current read-position   
00485                                 
00486         ***********************************************************************/
00487 
00488         IReader opShr (inout ubyte[] x) 
00489         {
00490                 memory.allocate (cast(void[]*) &x, length(), ubyte.sizeof, decode.int8u);
00491                 return this;
00492         }
00493 
00494         /***********************************************************************
00495         
00496                 Extract a byte value from the current read-position
00497                 
00498         ***********************************************************************/
00499 
00500         IReader opShr (inout byte[] x)
00501         {
00502                 memory.allocate (cast(void[]*) &x, length(), byte.sizeof, decode.int8);
00503                 return this;
00504         }
00505 
00506         /***********************************************************************
00507         
00508                 Extract an unsigned short value from the current read-position
00509                 
00510         ***********************************************************************/
00511 
00512         IReader opShr (inout ushort[] x)
00513         {
00514                 memory.allocate (cast(void[]*) &x, length(), ushort.sizeof, decode.int16u);
00515                 return this;
00516         }
00517 
00518         /***********************************************************************
00519         
00520                 Extract a short value from the current read-position
00521                 
00522         ***********************************************************************/
00523 
00524         IReader opShr (inout short[] x)
00525         {
00526                 memory.allocate (cast(void[]*) &x, length(), short.sizeof, decode.int16);
00527                 return this;
00528         }
00529 
00530         /***********************************************************************
00531         
00532                 Extract a unsigned int value from the current read-position
00533                 
00534         ***********************************************************************/
00535 
00536         IReader opShr (inout uint[] x)
00537         {
00538                 memory.allocate (cast(void[]*) &x, length(), uint.sizeof, decode.int32u);
00539                 return this;
00540         }
00541 
00542         /***********************************************************************
00543         
00544                 Extract an int value from the current read-position
00545                 
00546         ***********************************************************************/
00547 
00548         IReader opShr (inout int[] x)
00549         {
00550                 memory.allocate (cast(void[]*) &x, length(), int.sizeof, decode.int32);
00551                 return this;
00552         }
00553 
00554         /***********************************************************************
00555         
00556                 Extract an unsigned long value from the current read-position
00557                 
00558         ***********************************************************************/
00559 
00560         IReader opShr (inout ulong[] x)
00561         {
00562                 memory.allocate (cast(void[]*) &x, length(), ulong.sizeof, decode.int64u);
00563                 return this;
00564         }
00565 
00566         /***********************************************************************
00567         
00568                 Extract a long value from the current read-position
00569                 
00570         ***********************************************************************/
00571 
00572         IReader opShr (inout long[] x)
00573         {
00574                 memory.allocate (cast(void[]*) &x, length(), long.sizeof, decode.int64);
00575                 return this;
00576         }
00577 
00578         /***********************************************************************
00579         
00580                 Extract a float value from the current read-position
00581                 
00582         ***********************************************************************/
00583 
00584         IReader opShr (inout float[] x)
00585         {
00586                 memory.allocate (cast(void[]*) &x, length(), float.sizeof, decode.float32);
00587                 return this;
00588         }
00589 
00590         /***********************************************************************
00591         
00592                 Extract a double value from the current read-position
00593                 
00594         ***********************************************************************/
00595 
00596         IReader opShr (inout double[] x)
00597         {
00598                 memory.allocate (cast(void[]*) &x, length(), double.sizeof, decode.float64);
00599                 return this;
00600         }
00601 
00602         /***********************************************************************
00603         
00604                 Extract a real value from the current read-position
00605                 
00606         ***********************************************************************/
00607 
00608         IReader opShr (inout real[] x)
00609         {
00610                 memory.allocate (cast(void[]*) &x, length(), real.sizeof, decode.float80);
00611                 return this;
00612         }
00613 
00614         /***********************************************************************
00615         
00616         ***********************************************************************/
00617 
00618         IReader opShr (inout char[] x)
00619         {
00620                 memory.allocate (cast(void[]*) &x, length(), char.sizeof, decode.char8);
00621                 return this;
00622         }
00623 
00624         /***********************************************************************
00625         
00626         ***********************************************************************/
00627 
00628         IReader opShr (inout wchar[] x)
00629         {
00630                 memory.allocate (cast(void[]*) &x, length(), wchar.sizeof, decode.char16);
00631                 return this;
00632         }
00633 
00634         /***********************************************************************
00635         
00636         ***********************************************************************/
00637 
00638         IReader opShr (inout dchar[] x)
00639         {
00640                 memory.allocate (cast(void[]*) &x, length(), dchar.sizeof, decode.char32);
00641                 return this;
00642         }
00643 }
00644 
00645 
00646 /+
00647         /***********************************************************************
00648 
00649         ***********************************************************************/
00650 
00651         template Get (T, alias decoder)
00652         {
00653                 IReader opShr (inout T x)
00654                 {
00655                         decoder.get (&x, x.sizeof);
00656                         return this;
00657                 }
00658         }
00659 
00660         template GetArray (T, alias decoder)
00661         {
00662                 IReader opShr (inout T x)
00663                 {
00664                         memory.allocate (cast(void[]*) &x, decoder);
00665                         return this;
00666                 }
00667         }
00668 
00669         mixin Get!(byte, decode.int8);
00670         //mixin GetArray!(byte[], decode.int8);
00671 +/

Generated on Tue Jan 25 21:18:19 2005 for Mango by doxygen 1.3.6