1
//========================================================================
5
// Copyright 1996-2002 Glyph & Cog, LLC
7
//========================================================================
11
#ifdef USE_GCC_PRAGMAS
12
#pragma implementation
26
Parser::Parser(XRef *xrefA, Lexer *lexerA) {
41
Object *Parser::getObj(Object *obj,
42
Guchar *fileKey, int keyLength,
43
int objNum, int objGen) {
45
Object *Parser::getObj(Object *obj) {
58
// refill buffer after inline image data
68
if (buf1.isCmd("[")) {
71
while (!buf1.isCmd("]") && !buf1.isEOF())
73
obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
75
obj->arrayAdd(getObj(&obj2));
78
error(getPos(), "End of file inside array");
81
// dictionary or stream
82
} else if (buf1.isCmd("<<")) {
85
while (!buf1.isCmd(">>") && !buf1.isEOF()) {
87
error(getPos(), "Dictionary key must be a name object");
90
key = copyString(buf1.getName());
92
if (buf1.isEOF() || buf1.isError()) {
97
obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
99
obj->dictAdd(key, getObj(&obj2));
104
error(getPos(), "End of file inside dictionary");
105
if (buf2.isCmd("stream")) {
106
if ((str = makeStream(obj))) {
107
obj->initStream(str);
108
#ifndef NO_DECRYPTION
110
str->getBaseStream()->doDecryption(fileKey, keyLength,
122
// indirect reference or integer
123
} else if (buf1.isInt()) {
126
if (buf1.isInt() && buf2.isCmd("R")) {
127
obj->initRef(num, buf1.getInt());
134
#ifndef NO_DECRYPTION
136
} else if (buf1.isString() && fileKey) {
138
s = obj->getString();
139
decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
140
for (i = 0, p = obj->getString()->getCString();
143
*p = decrypt->decryptByte(*p);
158
Stream *Parser::makeStream(Object *dict) {
161
Guint pos, endPos, length;
163
// get stream start position
164
lexer->skipToNextLine();
165
pos = lexer->getPos();
168
dict->dictLookup("Length", &obj);
170
length = (Guint)obj.getInt();
173
error(getPos(), "Bad 'Length' attribute in stream");
178
// check for length in damaged file
179
if (xref->getStreamEnd(pos, &endPos)) {
180
length = endPos - pos;
184
str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
188
str = str->addFilters(dict);
190
// skip over stream data
191
lexer->setPos(pos + length);
193
// refill token buffers and check for 'endstream'
194
shift(); // kill '>>'
195
shift(); // kill 'stream'
196
if (buf1.isCmd("endstream"))
199
error(getPos(), "Missing 'endstream'");
204
void Parser::shift() {
209
// in a damaged content stream, if 'ID' shows up in the middle
210
// of a dictionary, we need to reset
213
} else if (buf2.isCmd("ID")) {
214
lexer->skipChar(); // skip char after 'ID' command
219
if (inlineImg > 0) // don't buffer inline image data
222
lexer->getObj(&buf2);