00001 /******************************************************************************* 00002 00003 @file Reader.d 00004 00005 Copyright (C) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 00027 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00028 00029 00030 @version Initial version, March 2004 00031 @author Kris 00032 00033 00034 *******************************************************************************/ 00035 00036 module mango.io.Reader; 00037 00038 public import mango.io.AbstractReader; 00039 00040 /******************************************************************************* 00041 00042 Binary data Reader. Each reader operates upon an IBuffer, which is 00043 provided at construction time. Said buffer is intended to remain 00044 consistent over the reader lifetime. 00045 00046 Readers support both a C++ iostream type syntax, along with a get() 00047 syntax. Operations may be chained back-to-back. 00048 00049 All readers support the full set of native data types, plus a 00050 selection of array types. The latter can be configured to produce 00051 either a copy (.dup) of the buffer content, or a slice. See class 00052 SimpleAllocator, BufferAllocator and SliceAllocator for more on 00053 this topic. 00054 00055 The code below illustrates basic operation upon a memory buffer: 00056 00057 @code 00058 Buffer buf = new Buffer (256); 00059 00060 // map same buffer into both reader and writer 00061 IReader r = new Reader(buf); 00062 IWriter w = new Writer(buf); 00063 00064 int i = 10; 00065 long j = 20; 00066 double d = 3.14159; 00067 char[] c = "fred"; 00068 00069 // write data types out 00070 w << c << i << j << d; 00071 00072 // read them back again 00073 r >> c >> i >> j >> d; 00074 00075 // reset 00076 buf.clear(); 00077 00078 // same thing again, but using get() syntax instead 00079 w.put(c).put(i).put(j).put(d); 00080 r.get(c).get(i).get(j).get(d); 00081 00082 @endcode 00083 00084 Readers may also be used with any class implementing the IReadable 00085 interface. See PickleReader for an example of how this can be put 00086 to good use. 00087 00088 *******************************************************************************/ 00089 00090 class Reader : AbstractReader 00091 { 00092 /*********************************************************************** 00093 00094 Construct a reader on the provided buffer. 00095 00096 ***********************************************************************/ 00097 00098 this (IBuffer buffer) 00099 { 00100 super (buffer); 00101 00102 numeric.int1 = 00103 numeric.int8 = 00104 numeric.int8u = 00105 numeric.int16 = 00106 numeric.int16u = 00107 numeric.int32 = 00108 numeric.int32u = 00109 numeric.int64 = 00110 numeric.int64u = 00111 numeric.float32 = 00112 numeric.float64 = 00113 numeric.float80 = 00114 string.char8 = 00115 string.char16 = 00116 string.char32 = &read; 00117 } 00118 00119 /*********************************************************************** 00120 00121 Construct a reader on the buffer belonging to the given 00122 conduit. 00123 00124 ***********************************************************************/ 00125 00126 this (IConduit conduit) 00127 { 00128 this (conduit.createBuffer); 00129 } 00130 00131 /*********************************************************************** 00132 00133 ***********************************************************************/ 00134 00135 override char[] toString() 00136 { 00137 return "binary reader"; 00138 } 00139 00140 /*********************************************************************** 00141 00142 ***********************************************************************/ 00143 00144 final void read (void *dst, uint count) 00145 { 00146 while (count) 00147 { 00148 // get as much as there is available in the buffer 00149 uint available = buffer.readable(); 00150 00151 // cap bytes read 00152 if (available > count) 00153 available = count; 00154 00155 // copy them over 00156 dst[0..available] = buffer.get (available); 00157 00158 // bump counters 00159 dst += available; 00160 count -= available; 00161 00162 // if we need more input, get it 00163 if (count) 00164 if (! buffer.get(1, false).length) 00165 throw (buffer.getConduit) ? eof : udf; 00166 } 00167 } 00168 } 00169