1 //========================================================================
5 // Copyright 1996-2002 Glyph & Cog, LLC
7 //========================================================================
10 #pragma implementation
25 Parser::Parser(XRef *xrefA, Lexer *lexerA) {
40 Object *Parser::getObj(Object *obj,
41 Guchar *fileKey, int keyLength,
42 int objNum, int objGen) {
44 Object *Parser::getObj(Object *obj) {
57 // refill buffer after inline image data
67 if (buf1.isCmd("[")) {
70 while (!buf1.isCmd("]") && !buf1.isEOF())
72 obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
74 obj->arrayAdd(getObj(&obj2));
77 error(getPos(), "End of file inside array");
80 // dictionary or stream
81 } else if (buf1.isCmd("<<")) {
84 while (!buf1.isCmd(">>") && !buf1.isEOF()) {
86 error(getPos(), "Dictionary key must be a name object");
89 key = copyString(buf1.getName());
91 if (buf1.isEOF() || buf1.isError())
94 obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
96 obj->dictAdd(key, getObj(&obj2));
101 error(getPos(), "End of file inside dictionary");
102 if (buf2.isCmd("stream")) {
103 if ((str = makeStream(obj))) {
104 obj->initStream(str);
105 #ifndef NO_DECRYPTION
107 str->getBaseStream()->doDecryption(fileKey, keyLength,
119 // indirect reference or integer
120 } else if (buf1.isInt()) {
123 if (buf1.isInt() && buf2.isCmd("R")) {
124 obj->initRef(num, buf1.getInt());
131 #ifndef NO_DECRYPTION
133 } else if (buf1.isString() && fileKey) {
135 s = obj->getString();
136 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
137 for (i = 0, p = obj->getString()->getCString();
140 *p = decrypt->decryptByte(*p);
155 Stream *Parser::makeStream(Object *dict) {
158 Guint pos, endPos, length;
160 // get stream start position
161 lexer->skipToNextLine();
162 pos = lexer->getPos();
165 dict->dictLookup("Length", &obj);
167 length = (Guint)obj.getInt();
170 error(getPos(), "Bad 'Length' attribute in stream");
175 // check for length in damaged file
176 if (xref->getStreamEnd(pos, &endPos)) {
177 length = endPos - pos;
181 str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
185 str = str->addFilters(dict);
187 // skip over stream data
188 lexer->setPos(pos + length);
190 // refill token buffers and check for 'endstream'
191 shift(); // kill '>>'
192 shift(); // kill 'stream'
193 if (buf1.isCmd("endstream"))
196 error(getPos(), "Missing 'endstream'");
201 void Parser::shift() {
204 } else if (buf2.isCmd("ID")) {
205 lexer->skipChar(); // skip char after 'ID' command
210 if (inlineImg > 0) // don't buffer inline image data
213 lexer->getObj(&buf2);