1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
10 #pragma implementation
24 Parser::Parser(Lexer *lexer1) {
38 Object *Parser::getObj(Object *obj,
39 Guchar *fileKey, int objNum, int objGen) {
41 Object *Parser::getObj(Object *obj) {
54 // refill buffer after inline image data
64 if (buf1.isCmd("[")) {
67 while (!buf1.isCmd("]") && !buf1.isEOF())
69 obj->arrayAdd(getObj(&obj2, fileKey, objNum, objGen));
71 obj->arrayAdd(getObj(&obj2));
74 error(getPos(), "End of file inside array");
77 // dictionary or stream
78 } else if (buf1.isCmd("<<")) {
81 while (!buf1.isCmd(">>") && !buf1.isEOF()) {
83 error(getPos(), "Dictionary key must be a name object");
86 key = copyString(buf1.getName());
88 if (buf1.isEOF() || buf1.isError())
91 obj->dictAdd(key, getObj(&obj2, fileKey, objNum, objGen));
93 obj->dictAdd(key, getObj(&obj2));
98 error(getPos(), "End of file inside dictionary");
99 if (buf2.isCmd("stream")) {
100 if ((str = makeStream(obj))) {
101 obj->initStream(str);
102 #ifndef NO_DECRYPTION
104 str->getBaseStream()->doDecryption(fileKey, objNum, objGen);
115 // indirect reference or integer
116 } else if (buf1.isInt()) {
119 if (buf1.isInt() && buf2.isCmd("R")) {
120 obj->initRef(num, buf1.getInt());
127 #ifndef NO_DECRYPTION
129 } else if (buf1.isString() && fileKey) {
131 s = obj->getString();
132 decrypt = new Decrypt(fileKey, objNum, objGen);
133 for (i = 0, p = obj->getString()->getCString();
136 *p = decrypt->decryptByte(*p);
151 Stream *Parser::makeStream(Object *dict) {
154 int pos, endPos, length;
156 // get stream start position
157 lexer->skipToNextLine();
158 pos = lexer->getPos();
161 dict->dictLookup("Length", &obj);
163 length = obj.getInt();
166 error(getPos(), "Bad 'Length' attribute in stream");
171 // check for length in damaged file
172 if ((endPos = xref->getStreamEnd(pos)) >= 0) {
173 length = endPos - pos;
177 str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict);
180 str = str->addFilters(dict);
182 // skip over stream data
183 lexer->setPos(pos + length);
185 // refill token buffers and check for 'endstream'
186 shift(); // kill '>>'
187 shift(); // kill 'stream'
188 if (buf1.isCmd("endstream"))
191 error(getPos(), "Missing 'endstream'");
196 void Parser::shift() {
199 } else if (buf2.isCmd("ID")) {
200 lexer->skipChar(); // skip char after 'ID' command
205 if (inlineImg > 0) // don't buffer inline image data
208 lexer->getObj(&buf2);