001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.encoding;
031:
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.io.Reader;
035:
036: /**
037: * A reader that uses a PDF style encoding to map byte code to unicode.
038: */
039: public class MappedReader extends Reader {
040: /** the encoding we use to decode/encode the byte stream */
041: private Encoding encoding;
042:
043: /** the stream we read from */
044: private InputStream inStream;
045:
046: /**
047: * Create a MappedReader
048: *
049: * @param is
050: * The underlying byte stream.
051: * @param encoding
052: * The encoding to use.
053: */
054: public MappedReader(InputStream is, Encoding encoding) {
055: super (is);
056: setInStream(is);
057: setEncoding(encoding);
058: }
059:
060: /**
061: * The encoding used by this reader.
062: *
063: * @return The encoding used by this reader.
064: */
065: public Encoding getEncoding() {
066: return encoding;
067: }
068:
069: /**
070: * @see java.io.Reader#close()
071: */
072: public void close() throws IOException {
073: synchronized (lock) {
074: if (inStream == null) {
075: return;
076: }
077: inStream.close();
078: inStream = null;
079: }
080: }
081:
082: /**
083: * Read characters into a portion of an array. This method will block until
084: * some input is available, an I/O error occurs, or the end of the stream is
085: * reached.
086: *
087: * @param cbuf
088: * Destination buffer
089: * @param off
090: * Offset at which to start storing characters
091: * @param len
092: * Maximum number of characters to read
093: *
094: * @return The number of characters read, or -1 if the end of the stream has
095: * been reached
096: *
097: * @exception IOException
098: * If an I/O error occurs
099: * @throws IndexOutOfBoundsException
100: */
101: public int read(char[] cbuf, int off, int len) throws IOException {
102: synchronized (lock) {
103: ensureOpen();
104: if ((off < 0) || (off > cbuf.length) || (len < 0)
105: || ((off + len) > cbuf.length) || ((off + len) < 0)) {
106: throw new IndexOutOfBoundsException();
107: } else if (len == 0) {
108: return 0;
109: }
110:
111: int b = 0;
112: for (int i = off; (b > -1) && (i < (off + len)); i++) {
113: b = getInStream().read();
114: if (b == -1) {
115: if (i == off) {
116: return -1;
117: }
118: return i - off;
119: }
120: cbuf[i] = (char) getEncoding().getUnicode(b);
121: }
122: return len;
123: }
124: }
125:
126: protected void setInStream(java.io.InputStream newInStream) {
127: inStream = newInStream;
128: }
129:
130: protected java.io.InputStream getInStream() {
131: return inStream;
132: }
133:
134: /**
135: * Check to make sure that the stream has not been closed
136: *
137: * @throws IOException
138: * if the inStream is null.
139: */
140: protected void ensureOpen() throws IOException {
141: if (inStream == null) {
142: throw new IOException("Stream closed");
143: }
144: }
145:
146: /**
147: * Set the encoding to be used by this reader.
148: *
149: * @param encoding
150: * The new encoding to use.
151: */
152: private void setEncoding(Encoding encoding) {
153: this.encoding = encoding;
154: }
155: }
|