KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > etymon > pjx > PdfInputBuffer


1 /*
2   Copyright (C) Etymon Systems, Inc. <http://www.etymon.com/>
3 */

4
5 package com.etymon.pjx;
6
7 import java.io.*;
8 import java.nio.*;
9 import java.nio.channels.*;
10 import java.nio.charset.*;
11
12 /**
13    Provides low-level methods for reading portions of a PDF document.
14    {@link PdfReader PdfReader} accesses PDF documents through the
15    {@link PdfInput PdfInput} interface, which is implemented by this
16    class. The entire buffer is stored in memory (except in the case
17    of {@link #PdfInputBuffer(File, boolean) PdfInputBuffer(File,
18    true)}); having the buffer in memory generally improves processing
19    speed as compared to {@link PdfInputFile PdfInputFile}, but of
20    course it requires the memory to be available and therefore puts
21    greater stress on system resources. For large PDF documents, it is
22    normally better to use {@link PdfInputFile PdfInputFile}
23    instead. <p> This class is synchronized; however, note that since
24    it acts as a wrapper around a buffer (in the case of {@link
25    #PdfInputBuffer(ByteBuffer, String) PdfInputBuffer(ByteBuffer,
26    String)}), it is the calling method's responsibility to ensure that
27    the buffer is not modified externally to this class. In the case
28    of {@link #PdfInputBuffer(File) PdfInputBuffer(File)} or {@link
29    #PdfInputBuffer(File, boolean) PdfInputBuffer(File, false)}, the
30    constructor reads the entire file into a buffer and that buffer is
31    not externally accessible; so there is no such danger. However,
32    {@link #PdfInputBuffer(File, boolean) PdfInputBuffer(File, true)}
33    leaves the file open, and therefore the calling method must ensure
34    that the file is not modified externally to this class.
35    @author Nassib Nassar
36  */

37 public class PdfInputBuffer
38     implements PdfInput {
39
40     /**
41        The byte buffer containing the PDF raw data.
42     */

43     protected ByteBuffer _bbuf;
44     
45     /**
46        The char buffer associated with <code>_bbuf</code>.
47     */

48     protected CharBuffer _cbuf;
49     
50     /**
51        The file channel associated with the PDF document.
52     */

53     protected FileChannel _fileChannel;
54
55     /**
56        The file input stream associated with the PDF document.
57     */

58     protected FileInputStream _fileInputStream;
59
60     /**
61        The file name or assigned name of this buffer.
62      */

63     protected String JavaDoc _name;
64     
65     /**
66       Constructs a PDF input source based on a specified
67       <code>ByteBuffer</code>. The buffer is read starting at its
68       current position until no more bytes are remaining. It is
69       the calling method's responsibility to ensure that the
70       buffer is not modified externally to this class. A name can
71       optionally be assigned to this document for identification.
72       @param pdfBuffer the source buffer.
73       @param name the name to assign to the document (or
74       <code>null</code> if no name is to be assigned).
75       @throws IOException
76      */

77         public PdfInputBuffer(ByteBuffer pdfBuffer, String JavaDoc name) throws IOException {
78
79         _bbuf = pdfBuffer.slice();
80
81         _name = (name != null) ? name : new String JavaDoc();
82         
83         initBuffer();
84
85         }
86
87     /**
88       Constructs a PDF input source based on a specified file.
89       This is equivalent to {@link #PdfInputBuffer(File, boolean)
90       PdfInputBuffer(File, false)}; i.e. this constructor reads
91       the entire file into memory and closes the file, and the
92       file is not memory-mapped. The size of the file must not be
93       greater than 2<sup>31</sup>-1; use {@link PdfInputFile
94       PdfInputFile} for huge files.
95       @param pdfFile the source file.
96       @throws IOException
97      */

98     public PdfInputBuffer(File pdfFile) throws IOException {
99
100         initFile(pdfFile, false);
101
102     }
103
104     /**
105       Constructs a PDF input source based on a specified file,
106       with optional memory-mapping. If memory-mapping is
107       disabled, this constructor reads the entire file into memory
108       and closes the file; if it is enabled, the file is kept
109       open, and it is the calling method's responsibility to
110       ensure that the file is not modified externally to this
111       class. The memory-mapping feature may be useful for very
112       large files, but in such cases {@link PdfInputFile
113       PdfInputFile} makes more sense in order to minimize stress
114       on system resources; therefore using the memory-mapping
115       feature is not generally recommended. The size of the file
116       must not be greater than 2<sup>31</sup>-1; use {@link
117       PdfInputFile PdfInputFile} for huge files.
118       @param pdfFile the source file.
119       @param memoryMapped specifies whether the file is to be
120       memory-mapped. A value of <code>true</code> enables
121       memory-mapping.
122       @throws IOException
123      */

124     public PdfInputBuffer(File pdfFile, boolean memoryMapped) throws IOException {
125
126         initFile(pdfFile, memoryMapped);
127
128     }
129
130         /**
131            Closes the PDF document and releases any system resources
132            associated with it.
133            @throws IOException
134         */

135         public void close() throws IOException {
136         synchronized (this) {
137             if (_fileChannel != null) {
138                 _fileChannel.close();
139                 _fileChannel = null;
140             }
141             if (_fileInputStream != null) {
142                 _fileInputStream.close();
143                 _fileInputStream = null;
144             }
145         }
146         }
147
148     /**
149        Performs initialization common to multiple constructors of
150        this class. This method is only intended to be called from
151        the constructors.
152      */

153     protected void init() {
154
155         _bbuf.position(0);
156         try {
157             _cbuf = Charset.forName("ISO-8859-1").newDecoder().decode(_bbuf);
158             // Unicode is "UTF-16"
159
}
160         catch (CharacterCodingException e) {
161             e.printStackTrace();
162             Runtime.getRuntime().exit(-1);
163         }
164
165     }
166     
167     /**
168        Performs initialization common to multiple constructors of
169        this class. This method is only intended to be called from
170        the constructors.
171      */

172     protected void initBuffer() {
173
174         _fileInputStream = null;
175         _fileChannel = null;
176
177         init();
178         
179     }
180
181     /**
182        Performs initialization common to multiple constructors of
183        this class. This method is only intended to be called from
184        the constructors.
185      */

186     protected void initFile(File pdfFile, boolean memoryMapped) throws IOException {
187
188         _name = pdfFile.getPath();
189         
190         if (memoryMapped) {
191
192             _fileInputStream = new FileInputStream(pdfFile);
193             _fileChannel = _fileInputStream.getChannel();
194             long fileChannelSize = _fileChannel.size();
195             if (fileChannelSize > Integer.MAX_VALUE) {
196                 _fileChannel.close();
197                 _fileInputStream.close();
198                 throw new IllegalArgumentException JavaDoc(
199                     "Huge files not supported by this class; use PdfInputFile.");
200             }
201             _bbuf = _fileChannel.map(FileChannel.MapMode.READ_ONLY,
202                          0, (int)fileChannelSize);
203             init();
204             
205         } else {
206
207             FileInputStream fis = new FileInputStream(pdfFile);
208             FileChannel fc = fis.getChannel();
209             long fcSize = fc.size();
210             if (fcSize > Integer.MAX_VALUE) {
211                 fc.close();
212                 fis.close();
213                 throw new IllegalArgumentException JavaDoc(
214                     "Huge files not supported by this class; use PdfInputFile.");
215             }
216             _bbuf = ByteBuffer.allocateDirect((int)fcSize);
217             fc.read(_bbuf);
218             fc.close();
219             fis.close();
220             
221             initBuffer();
222             
223         }
224         
225     }
226     
227     public ByteBuffer readBytes(long start, long end) throws IOException {
228         synchronized (this) {
229
230             _bbuf.limit((int)end);
231             _bbuf.position((int)start);
232             return _bbuf.slice();
233             
234         }
235     }
236
237     public CharBuffer readChars(long start, long end) throws IOException {
238         synchronized (this) {
239
240             _cbuf.limit((int)end);
241             _cbuf.position((int)start);
242             return _cbuf.slice();
243             
244         }
245     }
246
247     public long getLength() {
248         synchronized (this) {
249         
250             return _bbuf.capacity();
251             
252         }
253     }
254
255     public String JavaDoc getName() {
256         synchronized (this) {
257         
258             return _name;
259             
260         }
261     }
262
263 }
264
Popular Tags