1 9 package javolution.io; 10 11 import j2me.lang.CharSequence; 12 import j2me.lang.IllegalStateException; 13 import j2me.io.CharConversionException; 14 import java.io.IOException; 15 import java.io.OutputStream; 16 import java.io.Writer; 17 18 import javolution.lang.Reusable; 19 20 40 public final class Utf8StreamWriter extends Writer implements Reusable { 41 42 45 private OutputStream _outputStream; 46 47 50 private final byte[] _bytes; 51 52 55 private int _index; 56 57 60 public Utf8StreamWriter() { 61 _bytes = new byte[2048]; 62 } 63 64 69 public Utf8StreamWriter(int capacity) { 70 _bytes = new byte[capacity]; 71 } 72 73 86 public Utf8StreamWriter setOutputStream(OutputStream out) { 87 if (_outputStream != null) 88 throw new IllegalStateException("Writer not closed or reset"); 89 _outputStream = out; 90 return this; 91 } 92 93 101 public void write(char c) throws IOException { 102 if ((c < 0xd800) || (c > 0xdfff)) { 103 write((int) c); 104 } else if (c < 0xdc00) { _highSurrogate = c; 106 } else { int code = ((_highSurrogate - 0xd800) << 10) + (c - 0xdc00) 108 + 0x10000; 109 write(code); 110 } 111 } 112 113 private char _highSurrogate; 114 115 121 public void write(int code) throws IOException { 122 if ((code & 0xffffff80) == 0) { 123 _bytes[_index] = (byte) code; 124 if (++_index >= _bytes.length) { 125 flushBuffer(); 126 } 127 } else { write2(code); 129 } 130 } 131 132 private void write2(int c) throws IOException { 133 if ((c & 0xfffff800) == 0) { _bytes[_index] = (byte) (0xc0 | (c >> 6)); 135 if (++_index >= _bytes.length) { 136 flushBuffer(); 137 } 138 _bytes[_index] = (byte) (0x80 | (c & 0x3f)); 139 if (++_index >= _bytes.length) { 140 flushBuffer(); 141 } 142 } else if ((c & 0xffff0000) == 0) { _bytes[_index] = (byte) (0xe0 | (c >> 12)); 144 if (++_index >= _bytes.length) { 145 flushBuffer(); 146 } 147 _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3f)); 148 if (++_index >= _bytes.length) { 149 flushBuffer(); 150 } 151 _bytes[_index] = (byte) (0x80 | (c & 0x3f)); 152 if (++_index >= _bytes.length) { 153 flushBuffer(); 154 } 155 } else if ((c & 0xff200000) == 0) { _bytes[_index] = (byte) (0xf0 | (c >> 18)); 157 if (++_index >= _bytes.length) { 158 flushBuffer(); 159 } 160 _bytes[_index] = (byte) (0x80 | ((c >> 12) & 0x3f)); 161 if (++_index >= _bytes.length) { 162 flushBuffer(); 163 } 164 _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3f)); 165 if (++_index >= _bytes.length) { 166 flushBuffer(); 167 } 168 _bytes[_index] = (byte) (0x80 | (c & 0x3f)); 169 if (++_index >= _bytes.length) { 170 flushBuffer(); 171 } 172 } else if ((c & 0xf4000000) == 0) { _bytes[_index] = (byte) (0xf8 | (c >> 24)); 174 if (++_index >= _bytes.length) { 175 flushBuffer(); 176 } 177 _bytes[_index] = (byte) (0x80 | ((c >> 18) & 0x3f)); 178 if (++_index >= _bytes.length) { 179 flushBuffer(); 180 } 181 _bytes[_index] = (byte) (0x80 | ((c >> 12) & 0x3f)); 182 if (++_index >= _bytes.length) { 183 flushBuffer(); 184 } 185 _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3f)); 186 if (++_index >= _bytes.length) { 187 flushBuffer(); 188 } 189 _bytes[_index] = (byte) (0x80 | (c & 0x3f)); 190 if (++_index >= _bytes.length) { 191 flushBuffer(); 192 } 193 } else if ((c & 0x80000000) == 0) { _bytes[_index] = (byte) (0xfc | (c >> 30)); 195 if (++_index >= _bytes.length) { 196 flushBuffer(); 197 } 198 _bytes[_index] = (byte) (0x80 | ((c >> 24) & 0x3f)); 199 if (++_index >= _bytes.length) { 200 flushBuffer(); 201 } 202 _bytes[_index] = (byte) (0x80 | ((c >> 18) & 0x3f)); 203 if (++_index >= _bytes.length) { 204 flushBuffer(); 205 } 206 _bytes[_index] = (byte) (0x80 | ((c >> 12) & 0x3F)); 207 if (++_index >= _bytes.length) { 208 flushBuffer(); 209 } 210 _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3F)); 211 if (++_index >= _bytes.length) { 212 flushBuffer(); 213 } 214 _bytes[_index] = (byte) (0x80 | (c & 0x3F)); 215 if (++_index >= _bytes.length) { 216 flushBuffer(); 217 } 218 } else { 219 throw new CharConversionException("Illegal character U+" 220 + Integer.toHexString(c)); 221 } 222 } 223 224 232 public void write(char cbuf[], int off, int len) throws IOException { 233 final int off_plus_len = off + len; 234 for (int i = off; i < off_plus_len;) { 235 char c = cbuf[i++]; 236 if (c < 0x80) { 237 _bytes[_index] = (byte) c; 238 if (++_index >= _bytes.length) { 239 flushBuffer(); 240 } 241 } else { 242 write(c); 243 } 244 } 245 } 246 247 255 public void write(String str, int off, int len) throws IOException { 256 final int off_plus_len = off + len; 257 for (int i = off; i < off_plus_len;) { 258 char c = str.charAt(i++); 259 if (c < 0x80) { 260 _bytes[_index] = (byte) c; 261 if (++_index >= _bytes.length) { 262 flushBuffer(); 263 } 264 } else { 265 write(c); 266 } 267 } 268 } 269 270 276 public void write(CharSequence csq) throws IOException { 277 final int length = csq.length(); 278 for (int i = 0; i < length;) { 279 char c = csq.charAt(i++); 280 if (c < 0x80) { 281 _bytes[_index] = (byte) c; 282 if (++_index >= _bytes.length) { 283 flushBuffer(); 284 } 285 } else { 286 write(c); 287 } 288 } 289 } 290 291 300 public void flush() throws IOException { 301 flushBuffer(); 302 _outputStream.flush(); 303 } 304 305 310 public void close() throws IOException { 311 if (_outputStream != null) { 312 flushBuffer(); 313 _outputStream.close(); 314 reset(); 315 } 316 } 317 318 323 private void flushBuffer() throws IOException { 324 if (_outputStream == null) 325 throw new IOException("Stream closed"); 326 _outputStream.write(_bytes, 0, _index); 327 _index = 0; 328 } 329 330 public void reset() { 332 _highSurrogate = 0; 333 _index = 0; 334 _outputStream = null; 335 } 336 337 } | Popular Tags |