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
00040 module mango.io.BufferCodec;
00041
00042 private import mango.io.Buffer;
00043
00044 private import mango.convert.Type,
00045 mango.convert.Unicode;
00046
00047
00048
00049
00050
00051
00052 private class Importer : AbstractEncoder
00053 {
00054 protected IBuffer buffer;
00055
00056 abstract uint type();
00057
00058 void bind (IBuffer buffer)
00059 {
00060 this.buffer = buffer;
00061 }
00062
00063 uint encoder (void* src, uint bytes, uint type)
00064 {
00065 buffer.append (src [0..bytes]);
00066 return bytes;
00067 }
00068 }
00069
00070
00071
00072
00073
00074
00075 private class Exporter : AbstractDecoder
00076 {
00077 protected IBuffer buffer;
00078
00079 abstract uint type();
00080
00081 void bind (IBuffer buffer)
00082 {
00083 this.buffer = buffer;
00084 }
00085
00086 uint decoder (void* dst, uint bytes, uint type)
00087 {
00088 uint length = bytes;
00089
00090 while (length)
00091 {
00092
00093 uint available = buffer.readable();
00094
00095
00096 if (available > length)
00097 available = length;
00098
00099
00100 dst[0..available] = buffer.get (available);
00101
00102
00103 dst += available;
00104 length -= available;
00105
00106
00107 if (length)
00108 if (buffer.fill() == uint.max)
00109 buffer.error ("end of input");
00110 }
00111 return bytes;
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 class UnicodeImporter(T) : Importer
00122 {
00123 Unicode.Into!(T) into;
00124
00125 this (IBuffer buffer = null)
00126 {
00127 bind (buffer);
00128 }
00129
00130 override uint type ()
00131 {
00132 return into.type;
00133 }
00134
00135 override uint encoder (void* src, uint bytes, uint type)
00136 {
00137 uint ate;
00138 uint eaten;
00139
00140 uint convert (void[] dst)
00141 {
00142 return into.convert (src[eaten..bytes], type, dst, &ate).length;
00143 }
00144
00145
00146 if (type == into.type)
00147 return super.encoder (src, bytes, type);
00148
00149 buffer.write (&convert);
00150 while ((eaten += ate) < bytes)
00151 {
00152 buffer.makeRoom (bytes - eaten);
00153 buffer.write (&convert);
00154 }
00155 return eaten;
00156 }
00157 }
00158
00159
00160
00161
00162
00163
00164 class UnicodeExporter(T) : Exporter
00165 {
00166 Unicode.From!(T) from;
00167
00168 this (IBuffer buffer = null)
00169 {
00170 bind (buffer);
00171 }
00172
00173 override uint type ()
00174 {
00175 return from.type;
00176 }
00177
00178 override uint decoder (void* dst, uint bytes, uint type)
00179 {
00180 int written;
00181
00182 uint convert (void[] src)
00183 {
00184 uint ate;
00185 written += from.convert (src, type, dst[written..bytes], &ate).length;
00186 return ate;
00187 }
00188
00189 if (type == from.type)
00190 return super.decoder (dst, bytes, type);
00191
00192 buffer.read (&convert);
00193 while (written < bytes)
00194 {
00195 buffer.fill ();
00196 buffer.read (&convert);
00197 }
00198 return written;
00199 }
00200 }
00201
00202
00203