1 9 package javolution.xml; 10 11 import j2me.lang.IllegalStateException; 12 import j2me.io.CharConversionException; 13 import javolution.lang.Reusable; 14 15 import java.io.IOException; 16 import java.io.InputStream; 17 import java.io.Reader; 18 19 30 public class XmlInputStream extends InputStream implements Reusable { 31 32 35 private final ObjectReader _objectReader = new ObjectReader(); 36 37 40 private final XmlReader _xmlReader = new XmlReader(); 41 42 45 public XmlInputStream() { 46 } 47 48 56 public XmlInputStream setInputStream(InputStream in) { 57 if (_xmlReader._inputStream != null) 58 throw new IllegalStateException("Stream not closed or reset"); 59 _xmlReader._inputStream = in; 60 return this; 61 } 62 63 69 public Object readObject() throws IOException { 70 try { 71 return _objectReader.read(_xmlReader); 72 } finally { 73 _xmlReader.resume(); 74 } 75 } 76 77 82 public void close() throws IOException { 83 if (_xmlReader._inputStream != null) { 84 _xmlReader._inputStream.close(); 85 reset(); 86 } 87 } 88 89 95 public int read() throws IOException { 96 if (_xmlReader._start < _xmlReader._end) { 97 return _xmlReader._bytes[_xmlReader._start++]; 98 } else { return _xmlReader.fillBuffer() ? 100 _xmlReader._bytes[_xmlReader._start++] : -1; 101 } 102 } 103 104 115 public int read(byte b[], int off, int len) throws IOException { 116 int rem = _xmlReader._end - _xmlReader._start; 117 if (rem == 0) { return _xmlReader._inputStream.read(b, off, len); 119 } 120 int count = (len < rem) ? len : rem; 122 System.arraycopy(_xmlReader._bytes, _xmlReader._start, b, off, count); 123 _xmlReader._start += count; 124 return count; 125 } 126 127 public void reset() { 129 _objectReader.reset(); 130 _xmlReader.reset(); 131 } 132 133 139 private static final class XmlReader extends Reader implements Reusable { 140 private InputStream _inputStream; 141 private int _code; 142 private int _moreBytes; 143 private int _start; 144 private int _end; 145 private final byte[] _bytes = new byte[2048]; 146 private boolean _isHalted; 147 148 149 153 public void resume() { 154 _isHalted = false; 155 } 156 157 164 public boolean fillBuffer() throws IOException { 165 if (_inputStream == null) throw new IOException("Stream closed"); 166 _start = 0; 167 _end = _inputStream.read(_bytes, 0, _bytes.length); 168 return _end > 0; 169 } 170 171 public int read(char[] cbuf, int off, int len) throws IOException { 173 if (_isHalted) { 174 return -1; 175 } else if (_start >= _end) { 176 if (!fillBuffer()) { 177 return - 1; 178 } 179 } 180 final int off_plus_len = off + len; 181 for (int i = off; i < off_plus_len;) { 182 byte b = _bytes[_start]; 184 if ((b >= 0) && (++_start < _end)) { 185 cbuf[i++] = (char) b; } else if (b < 0) { 187 if (b == XmlOutputStream.END_XML) { 188 ++_start; 189 _isHalted = true; 190 return i - off; 191 } else if (i < off_plus_len - 1) { int code = read2(); 193 if (code < 0x10000) { 194 cbuf[i++] = (char) code; 195 } else if (code <= 0x10ffff) { cbuf[i++] = (char) (((code - 0x10000) >> 10) + 0xd800); 197 cbuf[i++] = (char) (((code - 0x10000) & 0x3ff) + 0xdc00); 198 } else { 199 throw new CharConversionException( 200 "Cannot convert U+" 201 + Integer.toHexString(code) 202 + " to char (code greater than U+10FFFF)"); 203 } 204 if (_start < _end) { 205 continue; 206 } 207 } 208 return i - off; 209 } else { cbuf[i++] = (char) b; 211 return i - off; 212 } 213 } 214 return len; 215 } 216 217 public void close() throws IOException { 219 } 222 223 private int read2() throws IOException { 225 if (_start < _end) { 226 byte b = _bytes[_start++]; 227 228 if ((b >= 0) && (_moreBytes == 0)) { 230 return b; 232 } else if (((b & 0xc0) == 0x80) && (_moreBytes != 0)) { 233 _code = (_code << 6) | (b & 0x3f); if (--_moreBytes == 0) { 236 return _code; 237 } else { 238 return read2(); 239 } 240 } else if (((b & 0xe0) == 0xc0) && (_moreBytes == 0)) { 241 _code = b & 0x1f; 243 _moreBytes = 1; 244 return read2(); 245 } else if (((b & 0xf0) == 0xe0) && (_moreBytes == 0)) { 246 _code = b & 0x0f; 248 _moreBytes = 2; 249 return read2(); 250 } else if (((b & 0xf8) == 0xf0) && (_moreBytes == 0)) { 251 _code = b & 0x07; 253 _moreBytes = 3; 254 return read2(); 255 } else { 256 throw new CharConversionException("Invalid UTF-8 Encoding"); 257 } 258 } else { if (fillBuffer()) { 260 return read2(); } else { if (_moreBytes == 0) { 263 return -1; 264 } else { throw new CharConversionException( 266 "Unexpected end of stream"); 267 } 268 } 269 } 270 } 271 272 public void reset() { 274 _code = 0; 275 _end = 0; 276 _inputStream = null; 277 _moreBytes = 0; 278 _start = 0; 279 } 280 } 281 } | Popular Tags |