00001 /******************************************************************************* 00002 00003 @file TextReader.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.TextReader; 00037 00038 private import mango.io.Token, 00039 mango.io.Tokenizer, 00040 mango.io.Exception, 00041 mango.io.AbstractReader; 00042 00043 /******************************************************************************* 00044 00045 Grok readable input from a stream. All input is tokenized from the 00046 associated buffer, and converted as necessary into the destination 00047 location. A SpaceTokenizer is used by default, but you can choose 00048 an alternative (such as a comma-delimiting tokenizer). 00049 00050 *******************************************************************************/ 00051 00052 class TextReader : AbstractReader 00053 { 00054 // an individual token 00055 private Token token; 00056 00057 // internal tokenizer instance 00058 private ITokenizer tokenizer; 00059 00060 /*********************************************************************** 00061 00062 Construct a TextReader on the provided buffer, using the 00063 specified Tokenizer instead of the default one. 00064 00065 ***********************************************************************/ 00066 00067 this (IBuffer buffer, ITokenizer tokenizer) 00068 { 00069 super (buffer); 00070 this.token = new Token; 00071 this.tokenizer = tokenizer; 00072 00073 numeric.int1 = &int1; 00074 numeric.int8 = 00075 numeric.int8u = &int8; 00076 numeric.int16 = 00077 numeric.int16u = &int16; 00078 numeric.int32 = 00079 numeric.int32u = &int32; 00080 numeric.int64 = 00081 numeric.int64u = &int64; 00082 00083 numeric.float32 = &float32; 00084 numeric.float64 = &float64; 00085 numeric.float80 = &float80; 00086 } 00087 00088 /*********************************************************************** 00089 00090 Construct a TextReader on the given buffer 00091 00092 ***********************************************************************/ 00093 00094 this (IBuffer buffer) 00095 { 00096 this (buffer, Tokenizers.space); 00097 } 00098 00099 /*********************************************************************** 00100 00101 Construct a TextReader upon the buffer associated with the 00102 given conduit. 00103 00104 ***********************************************************************/ 00105 00106 this (IConduit conduit) 00107 { 00108 this (conduit.createBuffer); 00109 } 00110 00111 /*********************************************************************** 00112 00113 ***********************************************************************/ 00114 00115 override char[] toString() 00116 { 00117 return "text reader"; 00118 } 00119 00120 /*********************************************************************** 00121 00122 Internal method to isolate the next token. 00123 00124 ***********************************************************************/ 00125 00126 private final Token next () 00127 { 00128 if (tokenizer.next (buffer, token) && token.getLength > 0) 00129 return token; 00130 throw new TokenException ("unexpected end of input"); 00131 } 00132 00133 /*********************************************************************** 00134 00135 ***********************************************************************/ 00136 00137 void int1 (void* src, uint count) 00138 { 00139 while (count) 00140 { 00141 * cast(bool*) src = (next.toString == "true"); 00142 ++src; 00143 --count; 00144 } 00145 } 00146 00147 /*********************************************************************** 00148 00149 ***********************************************************************/ 00150 00151 void int8 (void* src, uint count) 00152 { 00153 while (count) 00154 { 00155 * cast(byte*) src = next.toInt(); 00156 src += byte.sizeof; 00157 count -= byte.sizeof; 00158 } 00159 } 00160 00161 /*********************************************************************** 00162 00163 ***********************************************************************/ 00164 00165 void int16 (void* src, uint count) 00166 { 00167 while (count) 00168 { 00169 * cast(short*) src = next.toInt(); 00170 src += short.sizeof; 00171 count -= short.sizeof; 00172 } 00173 } 00174 00175 /*********************************************************************** 00176 00177 ***********************************************************************/ 00178 00179 void int32 (void* src, uint count) 00180 { 00181 while (count) 00182 { 00183 * cast(int*) src = next.toInt(); 00184 src += int.sizeof; 00185 count -= int.sizeof; 00186 } 00187 } 00188 00189 /*********************************************************************** 00190 00191 ***********************************************************************/ 00192 00193 void int64 (void* src, uint count) 00194 { 00195 while (count) 00196 { 00197 * cast(long*) src = next.toLong(); 00198 src += long.sizeof; 00199 count -= long.sizeof; 00200 } 00201 } 00202 00203 /*********************************************************************** 00204 00205 ***********************************************************************/ 00206 00207 void float32 (void* src, uint count) 00208 { 00209 while (count) 00210 { 00211 * cast(float*) src = next.toReal(); 00212 src += float.sizeof; 00213 count -= float.sizeof; 00214 } 00215 } 00216 00217 /*********************************************************************** 00218 00219 ***********************************************************************/ 00220 00221 void float64 (void* src, uint count) 00222 { 00223 while (count) 00224 { 00225 * cast(double*) src = next.toReal(); 00226 src += double.sizeof; 00227 count -= double.sizeof; 00228 } 00229 } 00230 00231 /*********************************************************************** 00232 00233 ***********************************************************************/ 00234 00235 void float80 (void* src, uint count) 00236 { 00237 while (count) 00238 { 00239 * cast(real*) src = next.toReal(); 00240 src += real.sizeof; 00241 count -= real.sizeof; 00242 } 00243 } 00244 00245 /*********************************************************************** 00246 00247 ***********************************************************************/ 00248 00249 override IReader get (inout char[] x) 00250 { 00251 // dup the input string, to avoid surprises 00252 x = next.toString (false); 00253 return this; 00254 } 00255 00256 /*********************************************************************** 00257 00258 @todo - Tokenizer needs to handle wchar[] before this will 00259 operate correctly 00260 00261 ***********************************************************************/ 00262 00263 override IReader get (inout wchar[] x) 00264 { 00265 assert (0); 00266 return this; 00267 } 00268 00269 /*********************************************************************** 00270 00271 @todo - Tokenizer needs to handle dchar[] before this will 00272 operate correctly 00273 00274 ***********************************************************************/ 00275 00276 override IReader get (inout dchar[] x) 00277 { 00278 assert (0); 00279 return this; 00280 } 00281 }