From 6025b6016517c6d898d8957d1d7e03ba71431912 Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 1 Dec 2006 12:20:24 +0000 Subject: Initial import of release 2.2. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@4 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../java/org/pdfbox/io/ASCII85InputStream.java | 269 ++++++++++++++ .../java/org/pdfbox/io/ASCII85OutputStream.java | 304 ++++++++++++++++ .../pdfbox/io/ByteArrayPushBackInputStream.java | 404 +++++++++++++++++++++ .../org/pdfbox/io/FastByteArrayOutputStream.java | 62 ++++ src/main/java/org/pdfbox/io/NBitInputStream.java | 124 +++++++ src/main/java/org/pdfbox/io/NBitOutputStream.java | 116 ++++++ .../java/org/pdfbox/io/PushBackInputStream.java | 92 +++++ .../org/pdfbox/io/RandomAccessFileInputStream.java | 132 +++++++ .../pdfbox/io/RandomAccessFileOutputStream.java | 145 ++++++++ src/main/java/org/pdfbox/io/package.html | 9 + 10 files changed, 1657 insertions(+) create mode 100644 src/main/java/org/pdfbox/io/ASCII85InputStream.java create mode 100644 src/main/java/org/pdfbox/io/ASCII85OutputStream.java create mode 100644 src/main/java/org/pdfbox/io/ByteArrayPushBackInputStream.java create mode 100644 src/main/java/org/pdfbox/io/FastByteArrayOutputStream.java create mode 100644 src/main/java/org/pdfbox/io/NBitInputStream.java create mode 100644 src/main/java/org/pdfbox/io/NBitOutputStream.java create mode 100644 src/main/java/org/pdfbox/io/PushBackInputStream.java create mode 100644 src/main/java/org/pdfbox/io/RandomAccessFileInputStream.java create mode 100644 src/main/java/org/pdfbox/io/RandomAccessFileOutputStream.java create mode 100644 src/main/java/org/pdfbox/io/package.html (limited to 'src/main/java/org/pdfbox/io') diff --git a/src/main/java/org/pdfbox/io/ASCII85InputStream.java b/src/main/java/org/pdfbox/io/ASCII85InputStream.java new file mode 100644 index 0000000..863d64d --- /dev/null +++ b/src/main/java/org/pdfbox/io/ASCII85InputStream.java @@ -0,0 +1,269 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.FilterInputStream; +import java.io.InputStream; +import java.io.IOException; + +/** + * This class represents an ASCII85 stream. + * + * @author Ben Litchfield + * @version $Revision: 1.5 $ + */ +public class ASCII85InputStream extends FilterInputStream +{ + private int index; + private int n; + private boolean eof; + + private byte[] ascii; + private byte[] b; + + /** + * Constructor. + * + * @param is The input stream to actually read from. + */ + public ASCII85InputStream( InputStream is ) + { + super(is); + index = 0; + n = 0; + eof = false; + ascii = new byte[5]; + b = new byte[4]; + } + + /** + * This will read the next byte from the stream. + * + * @return The next byte read from the stream. + * + * @throws IOException If there is an error reading from the wrapped stream. + */ + public final int read() throws IOException + { + if( index >= n ) + { + if(eof) + { + return -1; + } + index = 0; + int k; + byte z; + do + { + int zz=(byte)in.read(); + if(zz==-1) + { + eof=true; + return -1; + } + z = (byte)zz; + } while( z=='\n' || z=='\r' || z==' '); + + if (z == '~' || z=='x') + { + eof=true; + ascii=b=null; + n = 0; + return -1; + } + else if (z == 'z') + { + b[0]=b[1]=b[2]=b[3]=0; + n = 4; + } + else + { + ascii[0]=z; // may be EOF here.... + for (k=1;k<5;++k) + { + do + { + int zz=(byte)in.read(); + if(zz==-1) + { + eof=true; + return -1; + } + z=(byte)zz; + } while ( z=='\n' || z=='\r' || z==' ' ); + ascii[k]=z; + if (z == '~' || z=='x') + { + break; + } + } + n = k - 1; + if ( n==0 ) + { + eof = true; + ascii = null; + b = null; + return -1; + } + if ( k < 5 ) + { + for (++k; k < 5; ++k ) + { + ascii[k] = 0x21; + } + eof=true; + } + // decode stream + long t=0; + for ( k=0; k<5; ++k) + { + z=(byte)(ascii[k] - 0x21); + if (z < 0 || z > 93) + { + n = 0; + eof = true; + ascii = null; + b = null; + throw new IOException("Invalid data in Ascii85 stream"); + } + t = (t * 85L) + z; + } + for ( k = 3; k>=0; --k) + { + b[k] = (byte)(t & 0xFFL); + t>>>=8; + } + } + } + return b[index++] & 0xFF; + } + + /** + * This will read a chunk of data. + * + * @param data The buffer to write data to. + * @param offset The offset into the data stream. + * @param len The number of byte to attempt to read. + * + * @return The number of bytes actually read. + * + * @throws IOException If there is an error reading data from the underlying stream. + */ + public final int read(byte[] data, int offset, int len) throws IOException + { + if(eof && index>=n) + { + return -1; + } + for(int i=0;i126 || term=='z') + { + throw new IllegalArgumentException("Terminator must be 118-126 excluding z"); + } + terminator=term; + } + + /** + * This will get the terminating character. + * + * @return The terminating character. + */ + public char getTerminator() + { + return terminator; + } + + /** + * This will set the line length that will be used. + * + * @param l The length of the line to use. + */ + public void setLineLength(int l) + { + if( lineBreak > l ) + { + lineBreak = l; + } + maxline=l; + } + + /** + * This will get the length of the line. + * + * @return The line length attribute. + */ + public int getLineLength() + { + return maxline; + } + + /** + * This will transform the next four ascii bytes. + */ + private final void transformASCII85() + { + long word; + word=( (((indata[0] << 8) | (indata[1] &0xFF)) << 16) | + ( (indata[2] & 0xFF) << 8) | (indata[3] & 0xFF) + ) & 0xFFFFFFFFL; + // System.out.println("word=0x"+Long.toString(word,16)+" "+word); + + if (word == 0 ) + { + outdata[0]=(byte)'z'; + outdata[1]=0; + return; + } + long x; + x=word/(85L*85L*85L*85L); + // System.out.println("x0="+x); + outdata[0]=(byte)(x+'!'); + word-=x*85L*85L*85L*85L; + + x=word/(85L*85L*85L); + // System.out.println("x1="+x); + outdata[1]=(byte)(x+'!'); + word-=x*85L*85L*85L; + + x=word/(85L*85L); + // System.out.println("x2="+x); + outdata[2]=(byte)(x+'!'); + word-=x*85L*85L; + + x=word/85L; + // System.out.println("x3="+x); + outdata[3]=(byte)(x+'!'); + + // word-=x*85L; + + // System.out.println("x4="+(word % 85L)); + outdata[4]=(byte)((word%85L)+'!'); + } + + /** + * This will write a single byte. + * + * @param b The byte to write. + * + * @throws IOException If there is an error writing to the stream. + */ + public final void write(int b) throws IOException + { + flushed=false; + indata[count++]=(byte)b; + if(count < 4 ) + { + return; + } + transformASCII85(); + for(int i=0;i<5;i++) + { + if(outdata[i]==0) + { + break; + } + out.write(outdata[i]); + if(--lineBreak==0) + { + out.write('\n'); + lineBreak=maxline; + } + } + count = 0; + } + + /** + * This will write a chunk of data to the stream. + * + * @param b The byte buffer to read from. + * @param off The offset into the buffer. + * @param sz The number of bytes to read from the buffer. + * + * @throws IOException If there is an error writing to the underlying stream. + */ + public final void write(byte[] b,int off, int sz) throws IOException + { + for(int i=0;i 0 ) + { + for( int i=count; i<4; i++ ) + { + indata[i]=0; + } + transformASCII85(); + if(outdata[0]=='z') + { + for(int i=0;i<5;i++) // expand 'z', + { + outdata[i]=(byte)'!'; + } + } + for(int i=0;i= datalen; + } + + /** + * Save the state of this stream. + * @param readlimit Has no effect. + * @see InputStream#mark(int) + */ + public void mark(int readlimit) + { + if (false) + { + ++readlimit; // avoid unused param warning + } + save = datapos; + } + + /** + * Check if mark is supported. + * @return Always true. + * @see InputStream#markSupported() + */ + public boolean markSupported() + { + return true; + } + + /** + * Restore the state of this stream to the last saveState call. + * @see InputStream#reset() + */ + public void reset() + { + datapos = save; + } + + /** Available bytes. + * @see InputStream#available() + * @return Available bytes. + */ + public int available() + { + int av = datalen - datapos; + return av > 0 ? av : 0; + } + + /** Totally available bytes in the underlying array. + * @return Available bytes. + */ + public int size() + { + return datalen; + } + + /** + * Pushes back a byte. + * After this method returns, the next byte to be read will have the value (byte)by. + * @param by the int value whose low-order byte is to be pushed back. + * @throws IOException - If there is not enough room in the buffer for the byte. + * @see java.io.PushbackInputStream#unread(int) + */ + public void unread(int by) throws IOException + { + if (datapos == 0) + { + throw new IOException("ByteArrayParserInputStream.unread(int): " + + "cannot unread 1 byte at buffer position " + datapos); + } + --datapos; + data[datapos] = (byte)by; + } + + /** + * Pushes back a portion of an array of bytes by copying it to the + * front of the pushback buffer. After this method returns, the next byte + * to be read will have the value b[off], the byte after that will have + * the value b[off+1], and so forth. + * @param buffer the byte array to push back. + * @param off the start offset of the data. + * @param len the number of bytes to push back. + * @throws IOException If there is not enough room in the pushback buffer + * for the specified number of bytes. + * @see java.io.PushbackInputStream#unread(byte[], int, int) + */ + public void unread(byte[] buffer, int off, int len) throws IOException + { + if (len <= 0 || off >= buffer.length) + { + return; + } + if (off < 0) + { + off = 0; + } + if (len > buffer.length) + { + len = buffer.length; + } + localUnread(buffer, off, len); + } + + /** + * Pushes back a portion of an array of bytes by copying it to the + * front of the pushback buffer. After this method returns, the next byte + * to be read will have the value buffer[0], the byte after that will have + * the value buffer[1], and so forth. + * @param buffer the byte array to push back. + * @throws IOException If there is not enough room in the pushback buffer + * for the specified number of bytes. + * @see java.io.PushbackInputStream#unread(byte[]) + */ + public void unread(byte[] buffer) throws IOException + { + localUnread(buffer, 0, buffer.length); + } + + /** + * Pushes back a portion of an array of bytes by copying it to the + * front of the pushback buffer. After this method returns, the next byte + * to be read will have the value buffer[off], the byte after that will have + * the value buffer[off+1], and so forth. + * Internal method that assumes off and len to be valid. + * @param buffer the byte array to push back. + * @param off the start offset of the data. + * @param len the number of bytes to push back. + * @throws IOException If there is not enough room in the pushback buffer + * for the specified number of bytes. + * @see java.io.PushbackInputStream#unread(byte[], int, int) + */ + private void localUnread(byte[] buffer, int off, int len) throws IOException + { + if (datapos < len) + { + throw new IOException("ByteArrayParserInputStream.unread(int): " + + "cannot unread " + len + + " bytes at buffer position " + datapos); + } + datapos -= len; + System.arraycopy(buffer, off, data, datapos, len); + } + + /** + * Read a byte. + * @see InputStream#read() + * @return Byte read or -1 if no more bytes are available. + */ + public int read() + { + try + { + // convert negative values to 128..255 + return (data[datapos++] + 0x100) & 0xff; + } + catch (ArrayIndexOutOfBoundsException ex) + { + // could check this before, but this is a rare case + // and this method is called sufficiently often to justify this + // optimization + datapos = datalen; + return -1; + } + } + + /** + * Read a number of bytes. + * @see InputStream#read(byte[]) + * @param buffer the buffer into which the data is read. + * @return the total number of bytes read into the buffer, or -1 if there + * is no more data because the end of the stream has been reached. + */ + public int read(byte[] buffer) + { + return localRead(buffer, 0, buffer.length); + } + + /** + * Read a number of bytes. + * @see InputStream#read(byte[], int, int) + * @param buffer the buffer into which the data is read. + * @param off the start offset in array buffer at which the data is written. + * @param len the maximum number of bytes to read. + * @return the total number of bytes read into the buffer, or -1 if there + * is no more data because the end of the stream has been reached. + */ + public int read(byte[] buffer, int off, int len) + { + if (len <= 0 || off >= buffer.length) + { + return 0; + } + if (off < 0) + { + off = 0; + } + if (len > buffer.length) + { + len = buffer.length; + } + return localRead(buffer, off, len); + } + + + /** + * Read a number of bytes. Internal method that assumes off and len to be + * valid. + * @see InputStream#read(byte[], int, int) + * @param buffer the buffer into which the data is read. + * @param off the start offset in array buffer at which the data is written. + * @param len the maximum number of bytes to read. + * @return the total number of bytes read into the buffer, or -1 if there + * is no more data because the end of the stream has been reached. + */ + public int localRead(byte[] buffer, int off, int len) + { + if (len == 0) + { + return 0; // must return 0 even if at end! + } + else if (datapos >= datalen) + { + return -1; + } + else + { + int newpos = datapos + len; + if (newpos > datalen) + { + newpos = datalen; + len = newpos - datapos; + } + System.arraycopy(data, datapos, buffer, off, len); + datapos = newpos; + return len; + } + } + + /** + * Skips over and discards n bytes of data from this input stream. + * The skip method may, for a variety of reasons, end up skipping over some + * smaller number of bytes, possibly 0. This may result from any of a number + * of conditions; reaching end of file before n bytes have been skipped is + * only one possibility. The actual number of bytes skipped is returned. + * If n is negative, no bytes are skipped. + * @param num the number of bytes to be skipped. + * @return the actual number of bytes skipped. + * @see InputStream#skip(long) + */ + public long skip(long num) + { + if (num <= 0) + { + return 0; + } + else + { + long newpos = datapos + num; + if (newpos >= datalen) + { + num = datalen - datapos; + datapos = datalen; + } + else + { + datapos = (int)newpos; + } + return num; + } + } + + /** Position the stream at a given index. Positioning the stream + * at position size() will cause the next call to read() to return -1. + * + * @param newpos Position in the underlying array. A negative value will be + * interpreted as 0, a value greater than size() as size(). + * @return old position. + */ + public int seek(int newpos) + { + if (newpos < 0) + { + newpos = 0; + } + else if (newpos > datalen) + { + newpos = datalen; + } + int oldpos = pos; + pos = newpos; + return oldpos; + } + +} diff --git a/src/main/java/org/pdfbox/io/FastByteArrayOutputStream.java b/src/main/java/org/pdfbox/io/FastByteArrayOutputStream.java new file mode 100644 index 0000000..1e5fdc6 --- /dev/null +++ b/src/main/java/org/pdfbox/io/FastByteArrayOutputStream.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.ByteArrayOutputStream; + +/** + * An byte array output stream that allows direct access to the byte array. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class FastByteArrayOutputStream extends ByteArrayOutputStream +{ + /** + * Constructor. + * + * @param size An initial size of the stream. + */ + public FastByteArrayOutputStream( int size ) + { + super( size ); + } + + /** + * This will get the underlying byte array. + * + * @return The underlying byte array at this moment in time. + */ + public byte[] getByteArray() + { + return buf; + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/io/NBitInputStream.java b/src/main/java/org/pdfbox/io/NBitInputStream.java new file mode 100644 index 0000000..d8254b2 --- /dev/null +++ b/src/main/java/org/pdfbox/io/NBitInputStream.java @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.InputStream; +import java.io.IOException; + +/** + * This is an n-bit input stream. This means that you can read chunks of data + * as any number of bits, not just 8 bits like the regular input stream. Just set the + * number of bits that you would like to read on each call. The default is 8. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class NBitInputStream +{ + private int bitsInChunk; + private InputStream in; + + private int currentByte; + private int bitsLeftInCurrentByte; + + /** + * Constructor. + * + * @param is The input stream to read from. + */ + public NBitInputStream( InputStream is ) + { + in = is; + bitsLeftInCurrentByte = 0; + bitsInChunk = 8; + } + + /** + * This will unread some data. + * + * @param data The data to put back into the stream. + */ + public void unread( long data ) + { + data <<= bitsLeftInCurrentByte; + currentByte |= data; + bitsLeftInCurrentByte += bitsInChunk; + } + + /** + * This will read the next n bits from the stream and return the unsigned + * value of those bits. + * + * @return The next n bits from the stream. + * + * @throws IOException If there is an error reading from the underlying stream. + */ + public long read() throws IOException + { + long retval = 0; + for( int i=0; i> (bitsLeftInCurrentByte-1))&0x1); + bitsLeftInCurrentByte--; + } + } + return retval; + } + + /** Getter for property bitsToRead. + * @return Value of property bitsToRead. + */ + public int getBitsInChunk() + { + return bitsInChunk; + } + + /** Setter for property bitsToRead. + * @param bitsInChunkValue New value of property bitsToRead. + */ + public void setBitsInChunk(int bitsInChunkValue) + { + bitsInChunk = bitsInChunkValue; + } + +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/io/NBitOutputStream.java b/src/main/java/org/pdfbox/io/NBitOutputStream.java new file mode 100644 index 0000000..f944b8a --- /dev/null +++ b/src/main/java/org/pdfbox/io/NBitOutputStream.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.OutputStream; +import java.io.IOException; + +/** + * This is an n-bit output stream. This means that you write data in n-bit chunks. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class NBitOutputStream +{ + private int bitsInChunk; + private OutputStream out; + + private int currentByte; + private int positionInCurrentByte; + + /** + * Constructor. + * + * @param os The output stream to write to. + */ + public NBitOutputStream( OutputStream os ) + { + out = os; + currentByte = 0; + positionInCurrentByte = 7; + } + + /** + * This will write the next n-bits to the stream. + * + * @param chunk The next chunk of data to write. + * + * @throws IOException If there is an error writing the chunk. + */ + public void write( long chunk ) throws IOException + { + long bitToWrite; + for( int i=(bitsInChunk-1); i>=0; i-- ) + { + bitToWrite = (chunk >> i) & 0x1; + bitToWrite <<= positionInCurrentByte; + currentByte |= bitToWrite; + positionInCurrentByte--; + if( positionInCurrentByte < 0 ) + { + out.write( currentByte ); + currentByte = 0; + positionInCurrentByte = 7; + } + } + } + + /** + * This will close the stream. + * + * @throws IOException if there is an error closing the stream. + */ + public void close() throws IOException + { + if( positionInCurrentByte < 7 ) + { + out.write( currentByte ); + } + } + + /** Getter for property bitsToRead. + * @return Value of property bitsToRead. + */ + public int getBitsInChunk() + { + return bitsInChunk; + } + + /** Setter for property bitsToRead. + * @param bitsInChunkValue New value of property bitsToRead. + */ + public void setBitsInChunk(int bitsInChunkValue) + { + bitsInChunk = bitsInChunkValue; + } + +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/io/PushBackInputStream.java b/src/main/java/org/pdfbox/io/PushBackInputStream.java new file mode 100644 index 0000000..d519900 --- /dev/null +++ b/src/main/java/org/pdfbox/io/PushBackInputStream.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.InputStream; +import java.io.IOException; + +/** + * A simple subclass that adds a few convience methods. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.4 $ + */ +public class PushBackInputStream extends java.io.PushbackInputStream +{ + + /** + * Constructor. + * + * @param input The input stream. + * @param size The size of the push back buffer. + * + * @throws IOException If there is an error with the stream. + */ + public PushBackInputStream( InputStream input, int size ) throws IOException + { + super( input, size ); + if( input == null ) + { + throw new IOException( "Error: input was null" ); + } + } + + /** + * This will peek at the next byte. + * + * @return The next byte on the stream, leaving it as available to read. + * + * @throws IOException If there is an error reading the next byte. + */ + public int peek() throws IOException + { + int result = read(); + if( result != -1 ) + { + unread( result ); + } + return result; + } + + /** + * A simple test to see if we are at the end of the stream. + * + * @return true if we are at the end of the stream. + * + * @throws IOException If there is an error reading the next byte. + */ + public boolean isEOF() throws IOException + { + int peek = peek(); + return peek == -1; + } + +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/io/RandomAccessFileInputStream.java b/src/main/java/org/pdfbox/io/RandomAccessFileInputStream.java new file mode 100644 index 0000000..6589bcb --- /dev/null +++ b/src/main/java/org/pdfbox/io/RandomAccessFileInputStream.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.InputStream; +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * This class allows a section of a RandomAccessFile to be accessed as an + * input stream. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class RandomAccessFileInputStream extends InputStream +{ + private RandomAccessFile file; + private long currentPosition; + private long endPosition; + + /** + * Constructor. + * + * @param raFile The file to read the data from. + * @param startPosition The position in the file that this stream starts. + * @param length The length of the input stream. + */ + public RandomAccessFileInputStream( RandomAccessFile raFile, long startPosition, long length ) + { + file = raFile; + currentPosition = startPosition; + endPosition = currentPosition+length; + } + /** + * @see InputStream#available() + */ + public int available() + { + return (int)(endPosition - currentPosition); + } + /** + * @see InputStream#close() + */ + public void close() + { + //do nothing because we want to leave the random access file open. + } + /** + * @see InputStream#read() + */ + public int read() throws IOException + { + synchronized(file) + { + int retval = -1; + if( currentPosition < endPosition ) + { + file.seek( currentPosition ); + currentPosition++; + retval = file.read(); + } + return retval; + } + } + /** + * @see InputStream#read( byte[], int, int ) + */ + public int read( byte[] b, int offset, int length ) throws IOException + { + //only allow a read of the amount available. + if( length > available() ) + { + length = available(); + } + int amountRead = -1; + //only read if there are bytes actually available, otherwise + //return -1 if the EOF has been reached. + if( available() > 0 ) + { + synchronized(file) + { + file.seek( currentPosition ); + amountRead = file.read( b, offset, length ); + } + } + //update the current cursor position. + if( amountRead > 0 ) + { + currentPosition += amountRead; + } + return amountRead; + } + + /** + * @see InputStream#skip( long ) + */ + public long skip( long amountToSkip ) + { + long amountSkipped = Math.min( amountToSkip, available() ); + currentPosition+= amountSkipped; + return amountSkipped; + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/io/RandomAccessFileOutputStream.java b/src/main/java/org/pdfbox/io/RandomAccessFileOutputStream.java new file mode 100644 index 0000000..b2e7511 --- /dev/null +++ b/src/main/java/org/pdfbox/io/RandomAccessFileOutputStream.java @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2003, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.io; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; + +import org.pdfbox.cos.COSBase; +import org.pdfbox.cos.COSObject; +import org.pdfbox.cos.COSNumber; + +/** + * This will write to a RandomAccessFile in the filesystem and keep track + * of the position it is writing to and the length of the stream. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.3 $ + */ +public class RandomAccessFileOutputStream extends OutputStream +{ + private RandomAccessFile file; + private long position; + private long lengthWritten = 0; + private COSBase expectedLength = null; + + /** + * Constructor to create an output stream that will write to the end of a + * random access file. + * + * @param raf The file to write to. + * + * @throws IOException If there is a problem accessing the raf. + */ + public RandomAccessFileOutputStream( RandomAccessFile raf ) throws IOException + { + file = raf; + //first get the position that we will be writing to + position = raf.length(); + } + + /** + * This will get the position in the RAF that the stream was written + * to. + * + * @return The position in the raf where the file can be obtained. + */ + public long getPosition() + { + return position; + } + + /** + * The number of bytes written to the stream. + * + * @return The number of bytes read to the stream. + */ + public long getLength() + { + long length = -1; + if( expectedLength instanceof COSNumber ) + { + length = ((COSNumber)expectedLength).intValue(); + } + else if( expectedLength instanceof COSObject && + ((COSObject)expectedLength).getObject() instanceof COSNumber ) + { + length = ((COSNumber)((COSObject)expectedLength).getObject()).intValue(); + } + if( length == -1 ) + { + length = lengthWritten; + } + return length; + } + + /** + * @see OutputStream#write( byte[], int, int ) + */ + public void write( byte[] b, int offset, int length ) throws IOException + { + file.seek( position+lengthWritten ); + lengthWritten += length; + file.write( b, offset, length ); + + } + /** + * @see OutputStream#write( int ) + */ + public void write( int b ) throws IOException + { + file.seek( position+lengthWritten ); + lengthWritten++; + file.write( b ); + } + + /** + * This will get the length that the PDF document specified this stream + * should be. This may not match the number of bytes read. + * + * @return The expected length. + */ + public COSBase getExpectedLength() + { + return expectedLength; + } + + /** + * This will set the expected length of this stream. + * + * @param value The expected value. + */ + public void setExpectedLength(COSBase value) + { + expectedLength = value; + } +} \ No newline at end of file diff --git a/src/main/java/org/pdfbox/io/package.html b/src/main/java/org/pdfbox/io/package.html new file mode 100644 index 0000000..12261f4 --- /dev/null +++ b/src/main/java/org/pdfbox/io/package.html @@ -0,0 +1,9 @@ + + + + + + +This package contains IO streams. + + -- cgit v1.2.3