00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifdef __GNUC__
00010 #pragma implementation
00011 #endif
00012
00013 #include <aconf.h>
00014 #include <stddef.h>
00015 #include "Object.h"
00016 #include "Array.h"
00017 #include "Dict.h"
00018 #include "Parser.h"
00019 #include "XRef.h"
00020 #include "Error.h"
00021 #ifndef NO_DECRYPTION
00022 #include "Decrypt.h"
00023 #endif
00024
00025 Parser::Parser(XRef *xrefA, Lexer *lexerA) {
00026 xref = xrefA;
00027 lexer = lexerA;
00028 inlineImg = 0;
00029 lexer->getObj(&buf1);
00030 lexer->getObj(&buf2);
00031 }
00032
00033 Parser::~Parser() {
00034 buf1.free();
00035 buf2.free();
00036 delete lexer;
00037 }
00038
00039 #ifndef NO_DECRYPTION
00040 Object *Parser::getObj(Object *obj,
00041 Guchar *fileKey, int keyLength,
00042 int objNum, int objGen) {
00043 #else
00044 Object *Parser::getObj(Object *obj) {
00045 #endif
00046 char *key;
00047 Stream *str;
00048 Object obj2;
00049 int num;
00050 #ifndef NO_DECRYPTION
00051 Decrypt *decrypt;
00052 GString *s;
00053 char *p;
00054 int i;
00055 #endif
00056
00057
00058 if (inlineImg == 2) {
00059 buf1.free();
00060 buf2.free();
00061 lexer->getObj(&buf1);
00062 lexer->getObj(&buf2);
00063 inlineImg = 0;
00064 }
00065
00066
00067 if (buf1.isCmd("[")) {
00068 shift();
00069 obj->initArray(xref);
00070 while (!buf1.isCmd("]") && !buf1.isEOF())
00071 #ifndef NO_DECRYPTION
00072 obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
00073 #else
00074 obj->arrayAdd(getObj(&obj2));
00075 #endif
00076 if (buf1.isEOF())
00077 error(getPos(), "End of file inside array");
00078 shift();
00079
00080
00081 } else if (buf1.isCmd("<<")) {
00082 shift();
00083 obj->initDict(xref);
00084 while (!buf1.isCmd(">>") && !buf1.isEOF()) {
00085 if (!buf1.isName()) {
00086 error(getPos(), "Dictionary key must be a name object");
00087 shift();
00088 } else {
00089 key = copyString(buf1.getName());
00090 shift();
00091 if (buf1.isEOF() || buf1.isError())
00092 break;
00093 #ifndef NO_DECRYPTION
00094 obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
00095 #else
00096 obj->dictAdd(key, getObj(&obj2));
00097 #endif
00098 }
00099 }
00100 if (buf1.isEOF())
00101 error(getPos(), "End of file inside dictionary");
00102 if (buf2.isCmd("stream")) {
00103 if ((str = makeStream(obj))) {
00104 obj->initStream(str);
00105 #ifndef NO_DECRYPTION
00106 if (fileKey) {
00107 str->getBaseStream()->doDecryption(fileKey, keyLength,
00108 objNum, objGen);
00109 }
00110 #endif
00111 } else {
00112 obj->free();
00113 obj->initError();
00114 }
00115 } else {
00116 shift();
00117 }
00118
00119
00120 } else if (buf1.isInt()) {
00121 num = buf1.getInt();
00122 shift();
00123 if (buf1.isInt() && buf2.isCmd("R")) {
00124 obj->initRef(num, buf1.getInt());
00125 shift();
00126 shift();
00127 } else {
00128 obj->initInt(num);
00129 }
00130
00131 #ifndef NO_DECRYPTION
00132
00133 } else if (buf1.isString() && fileKey) {
00134 buf1.copy(obj);
00135 s = obj->getString();
00136 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
00137 for (i = 0, p = obj->getString()->getCString();
00138 i < s->getLength();
00139 ++i, ++p) {
00140 *p = decrypt->decryptByte(*p);
00141 }
00142 delete decrypt;
00143 shift();
00144 #endif
00145
00146
00147 } else {
00148 buf1.copy(obj);
00149 shift();
00150 }
00151
00152 return obj;
00153 }
00154
00155 Stream *Parser::makeStream(Object *dict) {
00156 Object obj;
00157 Stream *str;
00158 Guint pos, endPos, length;
00159
00160
00161 lexer->skipToNextLine();
00162 pos = lexer->getPos();
00163
00164
00165 dict->dictLookup("Length", &obj);
00166 if (obj.isInt()) {
00167 length = (Guint)obj.getInt();
00168 obj.free();
00169 } else {
00170 error(getPos(), "Bad 'Length' attribute in stream");
00171 obj.free();
00172 return NULL;
00173 }
00174
00175
00176 if (xref->getStreamEnd(pos, &endPos)) {
00177 length = endPos - pos;
00178 }
00179
00180
00181 str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
00182 length, dict);
00183
00184
00185 str = str->addFilters(dict);
00186
00187
00188 lexer->setPos(pos + length);
00189
00190
00191 shift();
00192 shift();
00193 if (buf1.isCmd("endstream"))
00194 shift();
00195 else
00196 error(getPos(), "Missing 'endstream'");
00197
00198 return str;
00199 }
00200
00201 void Parser::shift() {
00202 if (inlineImg > 0) {
00203 ++inlineImg;
00204 } else if (buf2.isCmd("ID")) {
00205 lexer->skipChar();
00206 inlineImg = 1;
00207 }
00208 buf1.free();
00209 buf1 = buf2;
00210 if (inlineImg > 0)
00211 buf2.initNull();
00212 else
00213 lexer->getObj(&buf2);
00214 }