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.Utf;
00044 private import mango.convert.Type;
00045
00046
00047
00048
00049
00050
00051 class UtfCodec(T) : RawCodec
00052 {
00053
00054
00055
00056
00057 this (Buffer buffer)
00058 {
00059 super (buffer);
00060
00061
00062 }
00063
00064 override uint type ()
00065 {
00066
00067 }
00068
00069
00070 private uint into (void[] dst, void* src, uint bytes, uint type, uint *ate)
00071 {
00072
00073 switch (type)
00074 {
00075 static if (is (T == char))
00076 {
00077 case Type.Utf8:
00078 return cast(char[]) x;
00079 case Type.Utf16:
00080 return Utf.toUtf8 (cast(wchar[]) x, cast(char[]) tmp);
00081 case Type.Utf32:
00082 return Utf.toUtf8 (cast(dchar[]) x, cast(char[]) tmp);
00083 }
00084
00085 static if (is (T == wchar))
00086 {
00087 case Type.Utf8:
00088 return Utf.toUtf16 (cast(char[]) src[0..bytes], cast(wchar[]) dst, ate).length;
00089 case Type.Utf16:
00090 return super.importer (src, bytes, type);
00091 case Type.Utf32:
00092 return Utf.toUtf16 (cast(dchar[]) src[0..bytes], cast(wchar[]) dst, ate).length;
00093 }
00094
00095 static if (is (T == dchar))
00096 {
00097 case Type.Utf8:
00098 return update (Utf.toUtf32 (cast(char[]) x, cast(dchar[]) tmp));
00099 case Type.Utf16:
00100 return update (Utf.toUtf32 (cast(wchar[]) x, cast(dchar[]) tmp));
00101 case Type.Utf32:
00102 return cast(dchar[]) x;
00103 }
00104 default:
00105 break;
00106 }
00107 }
00108
00109
00110 private override uint importer (void* src, uint bytes, uint type)
00111 {
00112 uint ate;
00113 uint eaten;
00114
00115 uint convert (void[] dst)
00116 {
00117 return into (dst, src, bytes, type, &ate);
00118 }
00119
00120
00121 buffer.write (&convert);
00122 while ((eaten += ate) < bytes)
00123 {
00124 buffer.drain ();
00125 buffer.write (&convert);
00126 }
00127 return eaten;
00128 }
00129
00130
00131 private uint from (void[] src, void* dst, uint bytes, uint type, uint *ate)
00132 {
00133 switch (type)
00134 {
00135 static if (is (T == char))
00136 {
00137 case Type.Utf8:
00138 return src;
00139 case Type.Utf16:
00140 return update (Utf.toUtf16 (cast(char[]) src, cast(wchar[]) dst, ate));
00141 case Type.Utf32:
00142 return update (Utf.toUtf32 (cast(char[]) src, cast(dchar[]) dst, ate));
00143 }
00144
00145 static if (is (T == wchar))
00146 {
00147 case Type.Utf8:
00148 return Utf.toUtf8 (cast(wchar[]) src, cast(char[]) dst[0..bytes], ate).length;
00149 case Type.Utf16:
00150 return super.exporter (dst, bytes, type);
00151 case Type.Utf32:
00152 return Utf.toUtf32 (cast(wchar[]) src, cast(dchar[]) dst[0..bytes], ate).length;
00153 }
00154
00155 static if (is (T == dchar))
00156 {
00157 case Type.Utf8:
00158 return update (Utf.toUtf8 (cast(dchar[]) src, cast(char[]) dst, ate));
00159 case Type.Utf16:
00160 return update (Utf.toUtf16 (cast(dchar[]) src, cast(wchar[]) dst, ate));
00161 case Type.Utf32:
00162 return src;
00163 }
00164 default:
00165 break;
00166 }
00167 }
00168
00169 private override uint exporter (void* dst, uint bytes, uint type)
00170 {
00171 int written;
00172
00173 uint convert (void[] src)
00174 {
00175 uint ate;
00176 written += from (src, dst, bytes, type, &ate);
00177 return ate;
00178 }
00179
00180
00181 buffer.read (&convert);
00182 while (written < bytes)
00183 {
00184 buffer.fill (buffer.getConduit);
00185 buffer.read (&convert);
00186 }
00187 return written;
00188 }
00189 }