001: // Copyright (c) 2004, 2007 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.text;
005:
006: import java.io.*;
007: import gnu.mapping.WrappedException; /* #ifdef use:java.nio */
008: import java.nio.*;
009: import java.nio.charset.*;
010:
011: /* #endif */
012:
013: /** A LineBufferedReader that wraps an InputStream.
014: * Similar functionality as using an InputStreamReader, but provides hooks
015: * to read at the byte level before setting the charset.
016: * Optionally uses java.nio.charset directly, for extra flexibility
017: * and a possible (but slight and unverified) performance improvement.
018: */
019:
020: public class LineInputStreamReader extends LineBufferedReader {
021: InputStream istrm;
022: /* #ifdef use:java.nio */
023: byte[] barr = new byte[8192];
024: ByteBuffer bbuf;
025: char[] carr;
026: CharBuffer cbuf = null;
027:
028: Charset cset;
029: CharsetDecoder decoder;
030:
031: public void setCharset(Charset cset) {
032: this .cset = cset;
033: this .decoder = cset.newDecoder();
034: }
035:
036: /* #endif */
037:
038: public void setCharset(String name) {
039: /* #ifdef use:java.nio */
040: Charset cset = Charset.forName(name);
041: if (this .cset == null)
042: setCharset(cset);
043: else if (!cset.equals(this .cset))
044: throw new RuntimeException("encoding " + name
045: + " does not match previous " + this .cset);
046: /* #else */
047: // if (this.in != null)
048: // return; // Should also check for a mismatch
049: // try
050: // {
051: // this.in = new InputStreamReader(istrm, name);
052: // }
053: // catch (java.io.UnsupportedEncodingException ex)
054: // {
055: // throw new WrappedException(ex);
056: // }
057: /* #endif */
058: }
059:
060: public LineInputStreamReader(InputStream in) {
061: super ((Reader) null);
062: /* #ifdef use:java.nio */
063: bbuf = ByteBuffer.wrap(barr);
064: bbuf.position(barr.length);
065: this .istrm = in;
066: /* #else */
067: // this.istrm = new BufferedInputStream(in);
068: /* #endif */
069: }
070:
071: public void close() throws IOException {
072: if (in != null)
073: in.close();
074: istrm.close();
075: }
076:
077: /* #ifdef use:java.nio */
078: private int fillBytes() throws java.io.IOException {
079: int n = istrm.read(barr, 0, barr.length);
080: bbuf.position(0);
081: bbuf.limit(n < 0 ? 0 : n);
082: return n;
083: }
084:
085: /* #endif */
086:
087: public void markStart() throws java.io.IOException {
088: /* #ifndef use:java.nio */
089: // istrm.mark(200);
090: /* #endif */
091: }
092:
093: public void resetStart(int pos) throws java.io.IOException {
094: /* #ifdef use:java.nio */
095: bbuf.position(pos);
096: /* #else */
097: // istrm.reset();
098: // while (--pos >= 0)
099: // istrm.read();
100: /* #endif */
101: }
102:
103: public int getByte() throws java.io.IOException {
104: /* #ifdef use:java.nio */
105: if (!bbuf.hasRemaining()) {
106: int n = fillBytes();
107: if (n <= 0)
108: return -1;
109: }
110: return bbuf.get() & 0xFF;
111: /* #else */
112: // return istrm.read();
113: /* #endif */
114: }
115:
116: public int fill(int len) throws java.io.IOException {
117: /* #ifdef use:java.nio */
118: if (cset == null)
119: setCharset("UTF-8");
120: if (buffer != carr) {
121: cbuf = CharBuffer.wrap(buffer);
122: carr = buffer;
123: }
124: cbuf.limit(pos + len);
125: cbuf.position(pos);
126: boolean eof = false;
127: if (!bbuf.hasRemaining()) {
128: int n = fillBytes();
129: if (n < 0) {
130: eof = true;
131: }
132: }
133: CoderResult cres = decoder.decode(bbuf, cbuf, eof);
134: int count = cbuf.position() - pos;
135: return count == 0 && eof ? -1 : count;
136: /* #else */
137: // if (in == null)
138: // setCharset("UTF-8");
139: // return super.fill(len);
140: /* #endif */
141: }
142:
143: /* #ifdef use:java.nio */
144: public boolean ready() throws java.io.IOException {
145: return pos < limit || bbuf.hasRemaining()
146: || istrm.available() > 0;
147: }
148: /* #endif */
149: }
|