00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 module mango.io.UtfCodec;
00040
00041 private import mango.io.Buffer;
00042
00043 private import mango.convert.Unicode;
00044
00045 /+
00046
00047
00048
00049
00050 class RawCodec1 : ICodec
00051 {
00052 protected Buffer buffer;
00053
00054 this (Buffer buffer)
00055 {
00056 this.buffer = buffer;
00057 }
00058
00059 uint type()
00060 {
00061 return 0;
00062 }
00063
00064 private override uint importer1 (void* src, uint bytes, uint type)
00065 {
00066 void* end = src + bytes;
00067
00068 uint convert (void[] dst)
00069 {
00070 int len = end - src;
00071 if (len > dst.length)
00072 len = dst.length;
00073 src[0..len] = dst[0..len];
00074 src += len;
00075 return len;
00076 }
00077
00078 buffer.write (&convert);
00079 while (src < end)
00080 {
00081 buffer.makeRoom (end - src);
00082 buffer.write (&convert);
00083 }
00084 return 0;
00085 }
00086
00087
00088 private override uint exporter1 (void* dst, uint bytes, uint type)
00089 {
00090 void* end = dst + bytes;
00091
00092 uint convert (void[] src)
00093 {
00094 int len = end - dst;
00095 if (len > src.length)
00096 len = src.length;
00097 dst[0..len] = src[0..len];
00098 dst += len;
00099 return len;
00100 }
00101
00102 buffer.read (&convert);
00103 while (dst < end)
00104 {
00105 buffer.fill ();
00106 buffer.read (&convert);
00107 }
00108 return 0;
00109 }
00110
00111
00112 uint exporter (void* dst, uint bytes, uint type)
00113 {
00114 while (bytes)
00115 {
00116
00117 uint available = buffer.readable();
00118
00119
00120 if (available > bytes)
00121 available = bytes;
00122
00123
00124 dst[0..available] = buffer.get (available);
00125
00126
00127 dst += available;
00128 bytes -= available;
00129
00130
00131 if (bytes)
00132 if (buffer.fill () == -1)
00133 buffer.error ("end of input");
00134 }
00135 return 0;
00136 }
00137
00138 uint importer (void* src, uint bytes, uint type)
00139 {
00140 buffer.append (src [0..bytes]);
00141 }
00142 }
00143
00144 +/
00145
00146
00147
00148
00149
00150 class UtfCodec(T) : RawCodec
00151 {
00152
00153
00154
00155
00156 this (Buffer buffer)
00157 {
00158 super (buffer);
00159
00160
00161 }
00162
00163 override uint type ()
00164 {
00165 return From!(T).type;
00166 }
00167 /+
00168
00169 private override uint importer1 (void* src, uint bytes, uint type)
00170 {
00171 uint ate;
00172 uint eaten;
00173
00174 uint convert (void[] dst)
00175 {
00176 return Into!(T).convert (dst, type, src[eaten..bytes], &ate).length;
00177 }
00178
00179
00180 if (type == Into!(T).type)
00181 return super.importer (src, bytes, type);
00182
00183 buffer.write (&convert);
00184 while ((eaten += ate) < bytes)
00185 {
00186 buffer.makeRoom (1);
00187 buffer.write (&convert);
00188 }
00189 return eaten;
00190 }
00191
00192
00193 private override uint exporter1 (void* dst, uint bytes, uint type)
00194 {
00195 int written;
00196
00197 uint convert (void[] src)
00198 {
00199 uint ate;
00200 written += From!(T).convert (src, type, dst[written..bytes], &ate).length;
00201 return ate;
00202 }
00203
00204 if (type == From!(T).type)
00205 return super.exporter (dst, bytes, type);
00206
00207 buffer.read (&convert);
00208 while (written < bytes)
00209 {
00210 buffer.fill ();
00211 buffer.read (&convert);
00212 }
00213 return written;
00214 }
00215 +/
00216
00217 private override uint importer (void* src, uint bytes, uint type)
00218 {
00219 uint ate;
00220 uint eaten;
00221
00222 uint convert (void[] dst)
00223 {
00224 return Into!(T).convert (dst, type, src[eaten..bytes], &ate).length;
00225 }
00226
00227
00228 if (type == Into!(T).type)
00229 return super.importer (src, bytes, type);
00230
00231 buffer.write (&convert);
00232 while ((eaten += ate) < bytes)
00233 {
00234 buffer.makeRoom (1);
00235 buffer.write (&convert);
00236 }
00237 return eaten;
00238 }
00239
00240
00241 private override uint exporter (void* dst, uint bytes, uint type)
00242 {
00243 int written;
00244
00245 uint convert (void[] src)
00246 {
00247 uint ate;
00248 written += From!(T).convert (src, type, dst[written..bytes], &ate).length;
00249 return ate;
00250 }
00251
00252 if (type == From!(T).type)
00253 return super.exporter (dst, bytes, type);
00254
00255 buffer.read (&convert);
00256 while (written < bytes)
00257 {
00258 buffer.fill ();
00259 buffer.read (&convert);
00260 }
00261 return written;
00262 }
00263 /+
00264
00265 private uint into (void[] dst, void* src, uint bytes, uint type, uint *ate)
00266 {
00267
00268 switch (type)
00269 {
00270 static if (is (T == char))
00271 {
00272 case Type.Utf8:
00273 return cast(char[]) x;
00274 case Type.Utf16:
00275 return Utf.toUtf8 (cast(wchar[]) x, cast(char[]) tmp);
00276 case Type.Utf32:
00277 return Utf.toUtf8 (cast(dchar[]) x, cast(char[]) tmp);
00278 }
00279
00280 static if (is (T == wchar))
00281 {
00282 case Type.Utf8:
00283 return Utf.toUtf16 (cast(char[]) src[0..bytes], cast(wchar[]) dst, ate).length;
00284 case Type.Utf16:
00285 return super.importer (src, bytes, type);
00286 case Type.Utf32:
00287 return Utf.toUtf16 (cast(dchar[]) src[0..bytes], cast(wchar[]) dst, ate).length;
00288 }
00289
00290 static if (is (T == dchar))
00291 {
00292 case Type.Utf8:
00293 return update (Utf.toUtf32 (cast(char[]) x, cast(dchar[]) tmp));
00294 case Type.Utf16:
00295 return update (Utf.toUtf32 (cast(wchar[]) x, cast(dchar[]) tmp));
00296 case Type.Utf32:
00297 return cast(dchar[]) x;
00298 }
00299 default:
00300 break;
00301 }
00302 }
00303
00304
00305 private uint from (void[] src, void* dst, uint bytes, uint type, uint *ate)
00306 {
00307 switch (type)
00308 {
00309 static if (is (T == char))
00310 {
00311 case Type.Utf8:
00312 return src;
00313 case Type.Utf16:
00314 return update (Utf.toUtf16 (cast(char[]) src, cast(wchar[]) dst, ate));
00315 case Type.Utf32:
00316 return update (Utf.toUtf32 (cast(char[]) src, cast(dchar[]) dst, ate));
00317 }
00318
00319 static if (is (T == wchar))
00320 {
00321 case Type.Utf8:
00322 return Utf.toUtf8 (cast(wchar[]) src, cast(char[]) dst[0..bytes], ate).length;
00323 case Type.Utf16:
00324 return super.exporter (dst, bytes, type);
00325 case Type.Utf32:
00326 return Utf.toUtf32 (cast(wchar[]) src, cast(dchar[]) dst[0..bytes], ate).length;
00327 }
00328
00329 static if (is (T == dchar))
00330 {
00331 case Type.Utf8:
00332 return update (Utf.toUtf8 (cast(dchar[]) src, cast(char[]) dst, ate));
00333 case Type.Utf16:
00334 return update (Utf.toUtf16 (cast(dchar[]) src, cast(wchar[]) dst, ate));
00335 case Type.Utf32:
00336 return src;
00337 }
00338 default:
00339 break;
00340 }
00341 }
00342 +/
00343 }
00344
00345