author | sandman <sandman> | 2002-04-13 00:47:20 (UTC) |
---|---|---|
committer | sandman <sandman> | 2002-04-13 00:47:20 (UTC) |
commit | 98a1e3f36567639344f12932b629e526a8783aa8 (patch) (unidiff) | |
tree | 0433d296857faceeafc54f7deabddb621f45a933 /noncore/unsupported/qpdf/xpdf/Parser.cc | |
parent | 7e31b1fba119f69929d6744d7295555ff1727f4f (diff) | |
download | opie-98a1e3f36567639344f12932b629e526a8783aa8.zip opie-98a1e3f36567639344f12932b629e526a8783aa8.tar.gz opie-98a1e3f36567639344f12932b629e526a8783aa8.tar.bz2 |
CVS import of QPdf
Diffstat (limited to 'noncore/unsupported/qpdf/xpdf/Parser.cc') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/qpdf/xpdf/Parser.cc | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.cc b/noncore/unsupported/qpdf/xpdf/Parser.cc new file mode 100644 index 0000000..a98753d --- a/dev/null +++ b/noncore/unsupported/qpdf/xpdf/Parser.cc | |||
@@ -0,0 +1,213 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // Parser.cc | ||
4 | // | ||
5 | // Copyright 1996 Derek B. Noonburg | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #ifdef __GNUC__ | ||
10 | #pragma implementation | ||
11 | #endif | ||
12 | |||
13 | #include <aconf.h> | ||
14 | #include <stddef.h> | ||
15 | #include "Object.h" | ||
16 | #include "Array.h" | ||
17 | #include "Dict.h" | ||
18 | #include "Parser.h" | ||
19 | #include "XRef.h" | ||
20 | #include "Error.h" | ||
21 | #ifndef NO_DECRYPTION | ||
22 | #include "Decrypt.h" | ||
23 | #endif | ||
24 | |||
25 | Parser::Parser(XRef *xrefA, Lexer *lexerA) { | ||
26 | xref = xrefA; | ||
27 | lexer = lexerA; | ||
28 | inlineImg = 0; | ||
29 | lexer->getObj(&buf1); | ||
30 | lexer->getObj(&buf2); | ||
31 | } | ||
32 | |||
33 | Parser::~Parser() { | ||
34 | buf1.free(); | ||
35 | buf2.free(); | ||
36 | delete lexer; | ||
37 | } | ||
38 | |||
39 | #ifndef NO_DECRYPTION | ||
40 | Object *Parser::getObj(Object *obj, | ||
41 | Guchar *fileKey, int keyLength, | ||
42 | int objNum, int objGen) { | ||
43 | #else | ||
44 | Object *Parser::getObj(Object *obj) { | ||
45 | #endif | ||
46 | char *key; | ||
47 | Stream *str; | ||
48 | Object obj2; | ||
49 | int num; | ||
50 | #ifndef NO_DECRYPTION | ||
51 | Decrypt *decrypt; | ||
52 | GString *s; | ||
53 | char *p; | ||
54 | int i; | ||
55 | #endif | ||
56 | |||
57 | // refill buffer after inline image data | ||
58 | if (inlineImg == 2) { | ||
59 | buf1.free(); | ||
60 | buf2.free(); | ||
61 | lexer->getObj(&buf1); | ||
62 | lexer->getObj(&buf2); | ||
63 | inlineImg = 0; | ||
64 | } | ||
65 | |||
66 | // array | ||
67 | if (buf1.isCmd("[")) { | ||
68 | shift(); | ||
69 | obj->initArray(xref); | ||
70 | while (!buf1.isCmd("]") && !buf1.isEOF()) | ||
71 | #ifndef NO_DECRYPTION | ||
72 | obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen)); | ||
73 | #else | ||
74 | obj->arrayAdd(getObj(&obj2)); | ||
75 | #endif | ||
76 | if (buf1.isEOF()) | ||
77 | error(getPos(), "End of file inside array"); | ||
78 | shift(); | ||
79 | |||
80 | // dictionary or stream | ||
81 | } else if (buf1.isCmd("<<")) { | ||
82 | shift(); | ||
83 | obj->initDict(xref); | ||
84 | while (!buf1.isCmd(">>") && !buf1.isEOF()) { | ||
85 | if (!buf1.isName()) { | ||
86 | error(getPos(), "Dictionary key must be a name object"); | ||
87 | shift(); | ||
88 | } else { | ||
89 | key = copyString(buf1.getName()); | ||
90 | shift(); | ||
91 | if (buf1.isEOF() || buf1.isError()) | ||
92 | break; | ||
93 | #ifndef NO_DECRYPTION | ||
94 | obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen)); | ||
95 | #else | ||
96 | obj->dictAdd(key, getObj(&obj2)); | ||
97 | #endif | ||
98 | } | ||
99 | } | ||
100 | if (buf1.isEOF()) | ||
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 | ||
106 | if (fileKey) { | ||
107 | str->getBaseStream()->doDecryption(fileKey, keyLength, | ||
108 | objNum, objGen); | ||
109 | } | ||
110 | #endif | ||
111 | } else { | ||
112 | obj->free(); | ||
113 | obj->initError(); | ||
114 | } | ||
115 | } else { | ||
116 | shift(); | ||
117 | } | ||
118 | |||
119 | // indirect reference or integer | ||
120 | } else if (buf1.isInt()) { | ||
121 | num = buf1.getInt(); | ||
122 | shift(); | ||
123 | if (buf1.isInt() && buf2.isCmd("R")) { | ||
124 | obj->initRef(num, buf1.getInt()); | ||
125 | shift(); | ||
126 | shift(); | ||
127 | } else { | ||
128 | obj->initInt(num); | ||
129 | } | ||
130 | |||
131 | #ifndef NO_DECRYPTION | ||
132 | // string | ||
133 | } else if (buf1.isString() && fileKey) { | ||
134 | buf1.copy(obj); | ||
135 | s = obj->getString(); | ||
136 | decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); | ||
137 | for (i = 0, p = obj->getString()->getCString(); | ||
138 | i < s->getLength(); | ||
139 | ++i, ++p) { | ||
140 | *p = decrypt->decryptByte(*p); | ||
141 | } | ||
142 | delete decrypt; | ||
143 | shift(); | ||
144 | #endif | ||
145 | |||
146 | // simple object | ||
147 | } else { | ||
148 | buf1.copy(obj); | ||
149 | shift(); | ||
150 | } | ||
151 | |||
152 | return obj; | ||
153 | } | ||
154 | |||
155 | Stream *Parser::makeStream(Object *dict) { | ||
156 | Object obj; | ||
157 | Stream *str; | ||
158 | int pos, endPos, length; | ||
159 | |||
160 | // get stream start position | ||
161 | lexer->skipToNextLine(); | ||
162 | pos = lexer->getPos(); | ||
163 | |||
164 | // get length | ||
165 | dict->dictLookup("Length", &obj); | ||
166 | if (obj.isInt()) { | ||
167 | length = obj.getInt(); | ||
168 | obj.free(); | ||
169 | } else { | ||
170 | error(getPos(), "Bad 'Length' attribute in stream"); | ||
171 | obj.free(); | ||
172 | return NULL; | ||
173 | } | ||
174 | |||
175 | // check for length in damaged file | ||
176 | if ((endPos = xref->getStreamEnd(pos)) >= 0) { | ||
177 | length = endPos - pos; | ||
178 | } | ||
179 | |||
180 | // make base stream | ||
181 | str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict); | ||
182 | |||
183 | // get filters | ||
184 | str = str->addFilters(dict); | ||
185 | |||
186 | // skip over stream data | ||
187 | lexer->setPos(pos + length); | ||
188 | |||
189 | // refill token buffers and check for 'endstream' | ||
190 | shift(); // kill '>>' | ||
191 | shift(); // kill 'stream' | ||
192 | if (buf1.isCmd("endstream")) | ||
193 | shift(); | ||
194 | else | ||
195 | error(getPos(), "Missing 'endstream'"); | ||
196 | |||
197 | return str; | ||
198 | } | ||
199 | |||
200 | void Parser::shift() { | ||
201 | if (inlineImg > 0) { | ||
202 | ++inlineImg; | ||
203 | } else if (buf2.isCmd("ID")) { | ||
204 | lexer->skipChar(); // skip char after 'ID' command | ||
205 | inlineImg = 1; | ||
206 | } | ||
207 | buf1.free(); | ||
208 | buf1 = buf2; | ||
209 | if (inlineImg > 0) // don't buffer inline image data | ||
210 | buf2.initNull(); | ||
211 | else | ||
212 | lexer->getObj(&buf2); | ||
213 | } | ||