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 Reader base-class. 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 integral 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 method 00052 setMapped() for more on this topic. 00053 00054 The code below illustrates basic operation upon a memory buffer: 00055 00056 @code 00057 Buffer buf = new Buffer (256); 00058 00059 // map same buffer into both reader and writer 00060 Reader r = new Reader(buf); 00061 Writer w = new Writer(buf); 00062 00063 int i = 10; 00064 long j = 20; 00065 double d = 3.14159; 00066 00067 // write data types out 00068 w << i << j << d; 00069 00070 // read them back again 00071 r >> i >> j >> d; 00072 00073 // reset 00074 buf.clear(); 00075 00076 // same thing again, but using get() syntax instead 00077 w.put(i).put(j).put(d); 00078 r.get(i).get(j).get(d); 00079 00080 @endcode 00081 00082 Readers may also be used with any class implementing the IReadable 00083 interface. See CompositeReader for an example of how this can be 00084 put to good use. 00085 00086 *******************************************************************************/ 00087 00088 class Reader : AbstractReader 00089 { 00090 /*********************************************************************** 00091 00092 Construct a reader on the provided buffer. 00093 00094 ***********************************************************************/ 00095 00096 this (IBuffer buffer) 00097 { 00098 super (buffer); 00099 00100 numeric.int1 = 00101 numeric.int8 = 00102 numeric.int8u = 00103 numeric.int16 = 00104 numeric.int16u = 00105 numeric.int32 = 00106 numeric.int32u = 00107 numeric.int64 = 00108 numeric.int64u = 00109 numeric.float32 = 00110 numeric.float64 = 00111 numeric.float80 = 00112 string.char8 = 00113 string.char16 = 00114 string.char32 = &read; 00115 } 00116 00117 /*********************************************************************** 00118 00119 Construct a reader on the buffer belonging to the given 00120 conduit. 00121 00122 ***********************************************************************/ 00123 00124 this (IConduit conduit) 00125 { 00126 this (conduit.createBuffer); 00127 } 00128 00129 /*********************************************************************** 00130 00131 ***********************************************************************/ 00132 00133 override char[] toString() 00134 { 00135 return "binary reader"; 00136 } 00137 00138 /*********************************************************************** 00139 00140 ***********************************************************************/ 00141 00142 final void read (void *dst, uint count) 00143 { 00144 while (count) 00145 { 00146 // get as much as there is available in the buffer 00147 uint available = buffer.readable(); 00148 00149 // cap bytes read 00150 if (available > count) 00151 available = count; 00152 00153 // copy them over 00154 dst[0..available] = buffer.get (available); 00155 00156 // bump counters 00157 dst += available; 00158 count -= available; 00159 00160 // if we need more input, get it 00161 if (count) 00162 if (! buffer.get(1, false).length) 00163 throw (buffer.getConduit) ? eof : udf; 00164 } 00165 } 00166 } 00167