KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > it > stefanochizzolini > clown > tokens > Reader


1 /*
2   Copyright © 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
3
4   Contributors:
5     * Stefano Chizzolini (original code developer, info@stefanochizzolini.it):
6       contributed code is Copyright © 2006 by Stefano Chizzolini.
7
8   This file should be part of the source code distribution of "PDF Clown library"
9   (the Program): see the accompanying README files for more info.
10
11   This Program is free software; you can redistribute it and/or modify it under
12   the terms of the GNU General Public License as published by the Free Software
13   Foundation; either version 2 of the License, or (at your option) any later version.
14
15   This Program is distributed in the hope that it will be useful, but WITHOUT ANY
16   WARRANTY, either expressed or implied; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
18
19   You should have received a copy of the GNU General Public License along with this
20   Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
21
22   Redistribution and use, with or without modification, are permitted provided that such
23   redistributions retain the above copyright notice, license and disclaimer, along with
24   this list of conditions.
25 */

26
27 package it.stefanochizzolini.clown.tokens;
28
29 import it.stefanochizzolini.clown.bytes.IInputStream;
30 import it.stefanochizzolini.clown.files.File;
31 import it.stefanochizzolini.clown.objects.PdfDictionary;
32 import it.stefanochizzolini.clown.objects.PdfInteger;
33 import it.stefanochizzolini.clown.objects.PdfName;
34 import java.io.EOFException JavaDoc;
35
36 /**
37   PDF file reader.
38 */

39 public class Reader
40 {
41   // <class>
42
// <dynamic>
43
// <fields>
44
private Parser parser;
45   // </fields>
46

47   // <constructors>
48
/**
49     <h3>Remarks</h3>
50     <p>For internal use only.</p>
51   */

52   public Reader(
53     IInputStream stream,
54     File file
55     )
56   {
57     this.parser = new Parser(stream,file);
58   }
59   // </constructors>
60

61   // <interface>
62
// <public>
63
public int hashCode(
64     )
65   {return parser.hashCode();}
66
67   public Parser getParser(
68     )
69   {return parser;}
70
71   public PdfDictionary readTrailer(
72     ) throws FileFormatException
73   {
74     // Get the offset of the last xref-table section!
75
long xrefOffset = parser.retrieveXRefOffset();
76     // Go to the start of the last xref-table section!
77
parser.seek(xrefOffset); parser.moveNext();
78     if(!((String JavaDoc)parser.getToken()).equals("xref"))
79       throw new FileFormatException("'xref' keyword not found.",parser.getPosition());
80
81     // Searching the start of the last trailer...
82
while(true)
83     {
84       parser.moveNext();
85       if(parser.getTokenType() == TokenTypeEnum.Keyword)
86         break;
87       parser.moveNext();
88       int count = (Integer JavaDoc)parser.getToken();
89       parser.skip(count * 20);
90     }
91     if(!((String JavaDoc)parser.getToken()).equals("trailer"))
92       throw new FileFormatException("'trailer' keyword not found.",parser.getPosition());
93
94     // Get the last trailer!
95
parser.moveNext();
96     return (PdfDictionary)parser.parsePdfObject();
97   }
98
99   /**
100     Retrieves the xref-table.
101     @return The xref-table entries array.
102   */

103   public XRefEntry[] readXRefTable(
104     PdfDictionary trailer
105     ) throws FileFormatException
106   {
107     // 1. XRef-table.
108
// Get the xref-table size!
109
PdfInteger xrefTableSize = (PdfInteger)trailer.get(PdfName.Size);
110     // Allocate the xref-table array!
111
XRefEntry[] xrefEntries = new XRefEntry[xrefTableSize.getValue()];
112
113     // 2. Last xref-table section.
114
// Move to the start of the last xref-table section!
115
parser.seek(parser.retrieveXRefOffset());
116     // Parse the last xref-table section!
117
readXRefSection(xrefEntries);
118
119     // 3. Previous xref-table sections.
120
while(true)
121     {
122       // 1. Previous xref-table section.
123
// Get the previous xref-table section offset!
124
PdfInteger prevXRefOffset = (PdfInteger)trailer.get(PdfName.Prev);
125       if(prevXRefOffset == null)
126         break;
127       // Move to the start of the previous xref-table section!
128
parser.seek(prevXRefOffset.getValue());
129       // Parse the previous xref-table section!
130
readXRefSection(xrefEntries);
131
132       // 2. Previous trailer.
133
// Skip 'trailer' keyword!
134
parser.moveNext();
135       // Get the previous trailer!
136
trailer = (PdfDictionary)parser.parsePdfObject();
137     }
138
139     return xrefEntries;
140   }
141
142   public String JavaDoc readVersion(
143     ) throws FileFormatException
144   {
145     return parser.retrieveVersion();
146   }
147   // </public>
148

149   // <protected>
150
protected void readXRefSection(
151     XRefEntry[] xrefEntries
152     ) throws FileFormatException
153   {
154     // Reach the start of the xref-table section!
155
parser.moveNext();
156     if(!((String JavaDoc)parser.getToken()).equals("xref"))
157       throw new FileFormatException("'xref' keyword not found.",parser.getPosition());
158
159     // Loop sequentially across the subsections inside the current xref-table section.
160
while(true)
161     {
162       /*
163         NOTE: Each iteration of this loop block represents the scanning
164         of one subsection.
165         We get its bounds (first and last object numbers within its range)
166         and then collect its entries.
167       */

168       // 1. First object number.
169
parser.moveNext();
170       // Have we reached the end of the xref-table section?
171
if((parser.getTokenType() == TokenTypeEnum.Keyword)
172           && ((String JavaDoc)parser.getToken()).equals("trailer"))
173         break;
174       // Is the current token type different from the expected one?
175
if(parser.getTokenType() != TokenTypeEnum.Integer)
176         throw new FileFormatException("Neither object number of the first object in this xref subsection nor end of xref section found.",parser.getPosition());
177       // Get the object number of the first object in this xref-table subsection!
178
int startObjectNumber = (Integer JavaDoc)parser.getToken();
179
180       // 2. Last object number.
181
parser.moveNext();
182       if(parser.getTokenType() != TokenTypeEnum.Integer)
183         throw new FileFormatException("Number of entries in this xref subsection not found.",parser.getPosition());
184       // Get the object number of the last object in this xref-table subsection!
185
int endObjectNumber = (Integer JavaDoc)parser.getToken() + startObjectNumber;
186
187       // 3. xref-table subsection entries.
188
for(
189         int index = startObjectNumber;
190         index < endObjectNumber;
191         index++
192         )
193       {
194         // Is the entry undefined?
195
if(xrefEntries[index] == null) // Undefined entry.
196
{
197           // 1. Get the indirect object offset!
198
parser.moveNext();
199           int offset = (Integer JavaDoc)parser.getToken();
200           // 2. Get the object generation number!
201
parser.moveNext();
202           int generation = (Integer JavaDoc)parser.getToken();
203           // 3. Get the usage tag!
204
parser.moveNext();
205           String JavaDoc usageToken = (String JavaDoc)parser.getToken();
206           XRefEntryUsageEnum usage;
207           if(usageToken.equals("n"))
208             usage = XRefEntryUsageEnum.InUse;
209           else if(usageToken.equals("f"))
210             usage = XRefEntryUsageEnum.Free;
211           else
212             throw new FileFormatException("Invalid xref entry.",parser.getPosition());
213
214           // 4. Entry initialization.
215
xrefEntries[index] = new XRefEntry(
216             index,
217             generation,
218             offset,
219             usage
220             );
221         }
222         else // Already-defined entry.
223
{
224           // Skip to the next entry!
225
parser.moveNext(3);
226         }
227       }
228     }
229   }
230   // </protected>
231
// </interface>
232
// </dynamic>
233
// </class>
234
}
Popular Tags