KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > pdf > RandomAccessFileOrArray


1 /*
2  * $Id: RandomAccessFileOrArray.java 2809 2007-05-30 13:57:03Z psoares33 $
3  * $Name$
4  *
5  * Copyright 2001, 2002 Paulo Soares
6  *
7  * The contents of this file are subject to the Mozilla Public License Version 1.1
8  * (the "License"); you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the License.
14  *
15  * The Original Code is 'iText, a free JAVA-PDF library'.
16  *
17  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
19  * All Rights Reserved.
20  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
22  *
23  * Contributor(s): all the names of the contributors are added in the source code
24  * where applicable.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
28  * provisions of LGPL are applicable instead of those above. If you wish to
29  * allow use of your version of this file only under the terms of the LGPL
30  * License and not to allow others to use your version of this file under
31  * the MPL, indicate your decision by deleting the provisions above and
32  * replace them with the notice and other provisions required by the LGPL.
33  * If you do not delete the provisions above, a recipient may use your version
34  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Library General Public License as published by the Free Software Foundation;
39  * either version 2 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
44  * details.
45  *
46  * If you didn't download this code from the following link, you should check if
47  * you aren't using an obsolete version:
48  * http://www.lowagie.com/iText/
49  */

50
51 package com.lowagie.text.pdf;
52
53 import com.lowagie.text.Document;
54 import java.io.ByteArrayOutputStream JavaDoc;
55 import java.io.DataInput JavaDoc;
56 import java.io.DataInputStream JavaDoc;
57 import java.io.EOFException JavaDoc;
58 import java.io.File JavaDoc;
59 import java.io.FileInputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.InputStream JavaDoc;
62 import java.io.RandomAccessFile JavaDoc;
63 import java.net.URL JavaDoc;
64 /** An implementation of a RandomAccessFile for input only
65  * that accepts a file or a byte array as data source.
66  *
67  * @author Paulo Soares (psoares@consiste.pt)
68  */

69 public class RandomAccessFileOrArray implements DataInput JavaDoc {
70     
71     MappedRandomAccessFile rf;
72     RandomAccessFile JavaDoc trf;
73     boolean plainRandomAccess;
74     String JavaDoc filename;
75     byte arrayIn[];
76     int arrayInPtr;
77     byte back;
78     boolean isBack = false;
79     
80     /** Holds value of property startOffset. */
81     private int startOffset = 0;
82
83     public RandomAccessFileOrArray(String JavaDoc filename) throws IOException JavaDoc {
84         this(filename, false, Document.plainRandomAccess);
85     }
86     
87     public RandomAccessFileOrArray(String JavaDoc filename, boolean forceRead, boolean plainRandomAccess) throws IOException JavaDoc {
88         this.plainRandomAccess = plainRandomAccess;
89         File JavaDoc file = new File JavaDoc(filename);
90         if (!file.canRead()) {
91             if (filename.startsWith("file:/") || filename.startsWith("http://") || filename.startsWith("https://") || filename.startsWith("jar:")) {
92                 InputStream JavaDoc is = new URL JavaDoc(filename).openStream();
93                 try {
94                     this.arrayIn = InputStreamToArray(is);
95                     return;
96                 }
97                 finally {
98                     try {is.close();}catch(IOException JavaDoc ioe){}
99                 }
100             }
101             else {
102                 InputStream JavaDoc is = BaseFont.getResourceStream(filename);
103                 if (is == null)
104                     throw new IOException JavaDoc(filename + " not found as file or resource.");
105                 try {
106                     this.arrayIn = InputStreamToArray(is);
107                     return;
108                 }
109                 finally {
110                     try {is.close();}catch(IOException JavaDoc ioe){}
111                 }
112             }
113         }
114         else if (forceRead) {
115             InputStream JavaDoc s = null;
116             try {
117                 s = new FileInputStream JavaDoc(file);
118                 this.arrayIn = InputStreamToArray(s);
119             }
120             finally {
121                 try {if (s != null) {s.close();}}catch(Exception JavaDoc e){}
122             }
123             return;
124         }
125         this.filename = filename;
126         if (plainRandomAccess)
127             trf = new RandomAccessFile JavaDoc(filename, "r");
128         else
129             rf = new MappedRandomAccessFile(filename, "r");
130     }
131
132     public RandomAccessFileOrArray(URL JavaDoc url) throws IOException JavaDoc {
133         InputStream JavaDoc is = url.openStream();
134         try {
135             this.arrayIn = InputStreamToArray(is);
136         }
137         finally {
138             try {is.close();}catch(IOException JavaDoc ioe){}
139         }
140     }
141
142     public RandomAccessFileOrArray(InputStream JavaDoc is) throws IOException JavaDoc {
143         this.arrayIn = InputStreamToArray(is);
144     }
145     
146     public static byte[] InputStreamToArray(InputStream JavaDoc is) throws IOException JavaDoc {
147         byte b[] = new byte[8192];
148         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
149         while (true) {
150             int read = is.read(b);
151             if (read < 1)
152                 break;
153             out.write(b, 0, read);
154         }
155         return out.toByteArray();
156     }
157
158     public RandomAccessFileOrArray(byte arrayIn[]) {
159         this.arrayIn = arrayIn;
160     }
161     
162     public RandomAccessFileOrArray(RandomAccessFileOrArray file) {
163         filename = file.filename;
164         arrayIn = file.arrayIn;
165         startOffset = file.startOffset;
166         plainRandomAccess = file.plainRandomAccess;
167     }
168     
169     public void pushBack(byte b) {
170         back = b;
171         isBack = true;
172     }
173     
174     public int read() throws IOException JavaDoc {
175         if(isBack) {
176             isBack = false;
177             return back & 0xff;
178         }
179         if (arrayIn == null)
180             return plainRandomAccess ? trf.read() : rf.read();
181         else {
182             if (arrayInPtr >= arrayIn.length)
183                 return -1;
184             return arrayIn[arrayInPtr++] & 0xff;
185         }
186     }
187     
188     public int read(byte[] b, int off, int len) throws IOException JavaDoc {
189         if (len == 0)
190             return 0;
191         int n = 0;
192         if (isBack) {
193             isBack = false;
194             if (len == 1) {
195                 b[off] = back;
196                 return 1;
197             }
198             else {
199                 n = 1;
200                 b[off++] = back;
201                 --len;
202             }
203         }
204         if (arrayIn == null) {
205             return (plainRandomAccess ? trf.read(b, off, len) : rf.read(b, off, len)) + n;
206         }
207         else {
208             if (arrayInPtr >= arrayIn.length)
209                 return -1;
210             if (arrayInPtr + len > arrayIn.length)
211                 len = arrayIn.length - arrayInPtr;
212             System.arraycopy(arrayIn, arrayInPtr, b, off, len);
213             arrayInPtr += len;
214             return len + n;
215         }
216     }
217     
218     public int read(byte b[]) throws IOException JavaDoc {
219         return read(b, 0, b.length);
220     }
221     
222     public void readFully(byte b[]) throws IOException JavaDoc {
223         readFully(b, 0, b.length);
224     }
225     
226     public void readFully(byte b[], int off, int len) throws IOException JavaDoc {
227         int n = 0;
228         do {
229             int count = read(b, off + n, len - n);
230             if (count < 0)
231                 throw new EOFException JavaDoc();
232             n += count;
233         } while (n < len);
234     }
235     
236     public long skip(long n) throws IOException JavaDoc {
237         return skipBytes((int)n);
238     }
239     
240     public int skipBytes(int n) throws IOException JavaDoc {
241         if (n <= 0) {
242             return 0;
243         }
244         int adj = 0;
245         if (isBack) {
246             isBack = false;
247             if (n == 1) {
248                 return 1;
249             }
250             else {
251                 --n;
252                 adj = 1;
253             }
254         }
255         int pos;
256         int len;
257         int newpos;
258         
259         pos = getFilePointer();
260         len = length();
261         newpos = pos + n;
262         if (newpos > len) {
263             newpos = len;
264         }
265         seek(newpos);
266         
267         /* return the actual number of bytes skipped */
268         return newpos - pos + adj;
269     }
270     
271     public void reOpen() throws IOException JavaDoc {
272         if (filename != null && rf == null && trf == null) {
273             if (plainRandomAccess)
274                 trf = new RandomAccessFile JavaDoc(filename, "r");
275             else
276                 rf = new MappedRandomAccessFile(filename, "r");
277         }
278         seek(0);
279     }
280     
281     protected void insureOpen() throws IOException JavaDoc {
282         if (filename != null && rf == null && trf == null) {
283             reOpen();
284         }
285     }
286     
287     public boolean isOpen() {
288         return (filename == null || rf != null || trf != null);
289     }
290     
291     public void close() throws IOException JavaDoc {
292         isBack = false;
293         if (rf != null) {
294             rf.close();
295             rf = null;
296         }
297         else if (trf != null) {
298             trf.close();
299             trf = null;
300         }
301     }
302     
303     public int length() throws IOException JavaDoc {
304         if (arrayIn == null) {
305             insureOpen();
306             return (int)(plainRandomAccess ? trf.length() : rf.length()) - startOffset;
307         }
308         else
309             return arrayIn.length - startOffset;
310     }
311     
312     public void seek(int pos) throws IOException JavaDoc {
313         pos += startOffset;
314         isBack = false;
315         if (arrayIn == null) {
316             insureOpen();
317             if (plainRandomAccess)
318                 trf.seek(pos);
319             else
320                 rf.seek(pos);
321         }
322         else
323             arrayInPtr = pos;
324     }
325     
326     public void seek(long pos) throws IOException JavaDoc {
327         seek((int)pos);
328     }
329     
330     public int getFilePointer() throws IOException JavaDoc {
331         insureOpen();
332         int n = isBack ? 1 : 0;
333         if (arrayIn == null) {
334             return (int)(plainRandomAccess ? trf.getFilePointer() : rf.getFilePointer()) - n - startOffset;
335         }
336         else
337             return arrayInPtr - n - startOffset;
338     }
339     
340     public boolean readBoolean() throws IOException JavaDoc {
341         int ch = this.read();
342         if (ch < 0)
343             throw new EOFException JavaDoc();
344         return (ch != 0);
345     }
346     
347     public byte readByte() throws IOException JavaDoc {
348         int ch = this.read();
349         if (ch < 0)
350             throw new EOFException JavaDoc();
351         return (byte)(ch);
352     }
353     
354     public int readUnsignedByte() throws IOException JavaDoc {
355         int ch = this.read();
356         if (ch < 0)
357             throw new EOFException JavaDoc();
358         return ch;
359     }
360     
361     public short readShort() throws IOException JavaDoc {
362         int ch1 = this.read();
363         int ch2 = this.read();
364         if ((ch1 | ch2) < 0)
365             throw new EOFException JavaDoc();
366         return (short)((ch1 << 8) + ch2);
367     }
368     
369     /**
370      * Reads a signed 16-bit number from this stream in little-endian order.
371      * The method reads two
372      * bytes from this stream, starting at the current stream pointer.
373      * If the two bytes read, in order, are
374      * <code>b1</code> and <code>b2</code>, where each of the two values is
375      * between <code>0</code> and <code>255</code>, inclusive, then the
376      * result is equal to:
377      * <blockquote><pre>
378      * (short)((b2 &lt;&lt; 8) | b1)
379      * </pre></blockquote>
380      * <p>
381      * This method blocks until the two bytes are read, the end of the
382      * stream is detected, or an exception is thrown.
383      *
384      * @return the next two bytes of this stream, interpreted as a signed
385      * 16-bit number.
386      * @exception EOFException if this stream reaches the end before reading
387      * two bytes.
388      * @exception IOException if an I/O error occurs.
389      */

390     public final short readShortLE() throws IOException JavaDoc {
391         int ch1 = this.read();
392         int ch2 = this.read();
393         if ((ch1 | ch2) < 0)
394             throw new EOFException JavaDoc();
395         return (short)((ch2 << 8) + (ch1 << 0));
396     }
397     
398     public int readUnsignedShort() throws IOException JavaDoc {
399         int ch1 = this.read();
400         int ch2 = this.read();
401         if ((ch1 | ch2) < 0)
402             throw new EOFException JavaDoc();
403         return (ch1 << 8) + ch2;
404     }
405     
406     /**
407      * Reads an unsigned 16-bit number from this stream in little-endian order.
408      * This method reads
409      * two bytes from the stream, starting at the current stream pointer.
410      * If the bytes read, in order, are
411      * <code>b1</code> and <code>b2</code>, where
412      * <code>0&nbsp;&lt;=&nbsp;b1, b2&nbsp;&lt;=&nbsp;255</code>,
413      * then the result is equal to:
414      * <blockquote><pre>
415      * (b2 &lt;&lt; 8) | b1
416      * </pre></blockquote>
417      * <p>
418      * This method blocks until the two bytes are read, the end of the
419      * stream is detected, or an exception is thrown.
420      *
421      * @return the next two bytes of this stream, interpreted as an
422      * unsigned 16-bit integer.
423      * @exception EOFException if this stream reaches the end before reading
424      * two bytes.
425      * @exception IOException if an I/O error occurs.
426      */

427     public final int readUnsignedShortLE() throws IOException JavaDoc {
428         int ch1 = this.read();
429         int ch2 = this.read();
430         if ((ch1 | ch2) < 0)
431             throw new EOFException JavaDoc();
432         return (ch2 << 8) + (ch1 << 0);
433     }
434     
435     public char readChar() throws IOException JavaDoc {
436         int ch1 = this.read();
437         int ch2 = this.read();
438         if ((ch1 | ch2) < 0)
439             throw new EOFException JavaDoc();
440         return (char)((ch1 << 8) + ch2);
441     }
442     
443     /**
444      * Reads a Unicode character from this stream in little-endian order.
445      * This method reads two
446      * bytes from the stream, starting at the current stream pointer.
447      * If the bytes read, in order, are
448      * <code>b1</code> and <code>b2</code>, where
449      * <code>0&nbsp;&lt;=&nbsp;b1,&nbsp;b2&nbsp;&lt;=&nbsp;255</code>,
450      * then the result is equal to:
451      * <blockquote><pre>
452      * (char)((b2 &lt;&lt; 8) | b1)
453      * </pre></blockquote>
454      * <p>
455      * This method blocks until the two bytes are read, the end of the
456      * stream is detected, or an exception is thrown.
457      *
458      * @return the next two bytes of this stream as a Unicode character.
459      * @exception EOFException if this stream reaches the end before reading
460      * two bytes.
461      * @exception IOException if an I/O error occurs.
462      */

463     public final char readCharLE() throws IOException JavaDoc {
464         int ch1 = this.read();
465         int ch2 = this.read();
466         if ((ch1 | ch2) < 0)
467             throw new EOFException JavaDoc();
468         return (char)((ch2 << 8) + (ch1 << 0));
469     }
470     
471     public int readInt() throws IOException JavaDoc {
472         int ch1 = this.read();
473         int ch2 = this.read();
474         int ch3 = this.read();
475         int ch4 = this.read();
476         if ((ch1 | ch2 | ch3 | ch4) < 0)
477             throw new EOFException JavaDoc();
478         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
479     }
480     
481     /**
482      * Reads a signed 32-bit integer from this stream in little-endian order.
483      * This method reads 4
484      * bytes from the stream, starting at the current stream pointer.
485      * If the bytes read, in order, are <code>b1</code>,
486      * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
487      * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
488      * then the result is equal to:
489      * <blockquote><pre>
490      * (b4 &lt;&lt; 24) | (b3 &lt;&lt; 16) + (b2 &lt;&lt; 8) + b1
491      * </pre></blockquote>
492      * <p>
493      * This method blocks until the four bytes are read, the end of the
494      * stream is detected, or an exception is thrown.
495      *
496      * @return the next four bytes of this stream, interpreted as an
497      * <code>int</code>.
498      * @exception EOFException if this stream reaches the end before reading
499      * four bytes.
500      * @exception IOException if an I/O error occurs.
501      */

502     public final int readIntLE() throws IOException JavaDoc {
503         int ch1 = this.read();
504         int ch2 = this.read();
505         int ch3 = this.read();
506         int ch4 = this.read();
507         if ((ch1 | ch2 | ch3 | ch4) < 0)
508             throw new EOFException JavaDoc();
509         return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
510     }
511     
512     /**
513      * Reads an unsigned 32-bit integer from this stream. This method reads 4
514      * bytes from the stream, starting at the current stream pointer.
515      * If the bytes read, in order, are <code>b1</code>,
516      * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
517      * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
518      * then the result is equal to:
519      * <blockquote><pre>
520      * (b1 &lt;&lt; 24) | (b2 &lt;&lt; 16) + (b3 &lt;&lt; 8) + b4
521      * </pre></blockquote>
522      * <p>
523      * This method blocks until the four bytes are read, the end of the
524      * stream is detected, or an exception is thrown.
525      *
526      * @return the next four bytes of this stream, interpreted as a
527      * <code>long</code>.
528      * @exception EOFException if this stream reaches the end before reading
529      * four bytes.
530      * @exception IOException if an I/O error occurs.
531      */

532     public final long readUnsignedInt() throws IOException JavaDoc {
533         long ch1 = this.read();
534         long ch2 = this.read();
535         long ch3 = this.read();
536         long ch4 = this.read();
537         if ((ch1 | ch2 | ch3 | ch4) < 0)
538             throw new EOFException JavaDoc();
539         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
540     }
541     
542     public final long readUnsignedIntLE() throws IOException JavaDoc {
543         long ch1 = this.read();
544         long ch2 = this.read();
545         long ch3 = this.read();
546         long ch4 = this.read();
547         if ((ch1 | ch2 | ch3 | ch4) < 0)
548             throw new EOFException JavaDoc();
549         return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
550     }
551     
552     public long readLong() throws IOException JavaDoc {
553         return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
554     }
555     
556     public final long readLongLE() throws IOException JavaDoc {
557         int i1 = readIntLE();
558         int i2 = readIntLE();
559         return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL);
560     }
561     
562     public float readFloat() throws IOException JavaDoc {
563         return Float.intBitsToFloat(readInt());
564     }
565     
566     public final float readFloatLE() throws IOException JavaDoc {
567         return Float.intBitsToFloat(readIntLE());
568     }
569     
570     public double readDouble() throws IOException JavaDoc {
571         return Double.longBitsToDouble(readLong());
572     }
573     
574     public final double readDoubleLE() throws IOException JavaDoc {
575         return Double.longBitsToDouble(readLongLE());
576     }
577     
578     public String JavaDoc readLine() throws IOException JavaDoc {
579         StringBuffer JavaDoc input = new StringBuffer JavaDoc();
580         int c = -1;
581         boolean eol = false;
582         
583         while (!eol) {
584             switch (c = read()) {
585                 case -1:
586                 case '\n':
587                     eol = true;
588                     break;
589                 case '\r':
590                     eol = true;
591                     int cur = getFilePointer();
592                     if ((read()) != '\n') {
593                         seek(cur);
594                     }
595                     break;
596                 default:
597                     input.append((char)c);
598                     break;
599             }
600         }
601         
602         if ((c == -1) && (input.length() == 0)) {
603             return null;
604         }
605         return input.toString();
606     }
607     
608     public String JavaDoc readUTF() throws IOException JavaDoc {
609         return DataInputStream.readUTF(this);
610     }
611     
612     /** Getter for property startOffset.
613      * @return Value of property startOffset.
614      *
615      */

616     public int getStartOffset() {
617         return this.startOffset;
618     }
619     
620     /** Setter for property startOffset.
621      * @param startOffset New value of property startOffset.
622      *
623      */

624     public void setStartOffset(int startOffset) {
625         this.startOffset = startOffset;
626     }
627     
628 }
629
Popular Tags