Diffstat (limited to 'noncore/apps/opie-reader/Aportis.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/Aportis.cpp | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/Aportis.cpp b/noncore/apps/opie-reader/Aportis.cpp new file mode 100644 index 0000000..595b385 --- a/dev/null +++ b/noncore/apps/opie-reader/Aportis.cpp | |||
@@ -0,0 +1,291 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | #include "Aportis.h" | ||
4 | |||
5 | Aportis::Aportis() { /*printf("constructing:%x\n",fin);*/ } | ||
6 | |||
7 | CList<Bkmk>* Aportis::getbkmklist() | ||
8 | { | ||
9 | if (bCompressed != 4) return NULL; | ||
10 | CList<Bkmk>* t = new CList<Bkmk>; | ||
11 | size_t cur = ftell(fin); | ||
12 | for (int i = 0; i < nRecs2; i++) | ||
13 | { | ||
14 | DWORD dwPos; | ||
15 | fseek(fin, 0x56 + 8*i, SEEK_SET); | ||
16 | fread(&dwPos, 4, 1, fin); | ||
17 | dwPos = SwapLong(dwPos); | ||
18 | fseek(fin,dwPos,SEEK_SET); | ||
19 | unsigned char ch; | ||
20 | fread(&ch,1,1,fin); | ||
21 | if (ch != 241) | ||
22 | { | ||
23 | char name[17]; | ||
24 | name[16] = '\0'; | ||
25 | fseek(fin,dwPos,SEEK_SET); | ||
26 | fread(name,1,16,fin); | ||
27 | unsigned long lcn; | ||
28 | fread(&lcn,sizeof(lcn),1,fin); | ||
29 | lcn = SwapLong(lcn); | ||
30 | #ifdef _UNICODE | ||
31 | tchar tname[17]; | ||
32 | memset(tname, 0, sizeof(tname)); | ||
33 | for (int i = 0; name[i] != 0; i++) | ||
34 | { | ||
35 | tname[i] = name[i]; | ||
36 | } | ||
37 | t->push_back(Bkmk(tname,lcn)); | ||
38 | #else | ||
39 | t->push_back(Bkmk(name,lcn)); | ||
40 | #endif | ||
41 | } | ||
42 | } | ||
43 | fseek(fin, cur, SEEK_SET); | ||
44 | return t; | ||
45 | } | ||
46 | |||
47 | int Aportis::openfile(const char *src) | ||
48 | { | ||
49 | |||
50 | // printf("In openfile\n"); | ||
51 | int ret = 0; | ||
52 | |||
53 | if (!Cpdb::openfile(src)) return -1; | ||
54 | |||
55 | if (head.creator != 0x64414552 // 'dAER' | ||
56 | || head.type != 0x74584554) // 'tXET') | ||
57 | { | ||
58 | return -2; | ||
59 | } | ||
60 | |||
61 | gotorecordnumber(0); | ||
62 | tDocRecord0 hdr0; | ||
63 | fread(&hdr0, sizeof(hdr0), 1, fin); | ||
64 | bCompressed = SwapWord(hdr0.wVersion); | ||
65 | if (bCompressed!=1 && bCompressed!=2 && bCompressed != 4) { | ||
66 | ret = bCompressed; | ||
67 | bCompressed = 2; | ||
68 | } | ||
69 | |||
70 | fseek(fin,0,SEEK_END); | ||
71 | dwLen = ftell(fin); | ||
72 | nRecs2 = nRecs = SwapWord(head.recordList.numRecords) - 1; | ||
73 | |||
74 | switch (bCompressed) | ||
75 | { | ||
76 | case 4: | ||
77 | { | ||
78 | dwTLen = 0; | ||
79 | int i; | ||
80 | for (i = 0; i < nRecs; i++) | ||
81 | { | ||
82 | unsigned int bs = GetBS(i); | ||
83 | if (bs == 0) break; | ||
84 | else dwTLen += bs; | ||
85 | } | ||
86 | nRecs = i; | ||
87 | BlockSize = 0; | ||
88 | } | ||
89 | break; | ||
90 | case 1: | ||
91 | case 2: | ||
92 | default: | ||
93 | dwTLen = SwapLong(hdr0.dwStoryLen); | ||
94 | BlockSize = SwapWord(hdr0.wRecSize); | ||
95 | if (BlockSize == 0) | ||
96 | { | ||
97 | BlockSize = 4096; | ||
98 | printf("WARNING: Blocksize not set in source file\n"); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | |||
103 | // this is the main record buffer | ||
104 | // it knows how to stretch to accomodate the decompress | ||
105 | currentrec = 0; | ||
106 | cbptr = 0; | ||
107 | outptr = 0; | ||
108 | refreshbuffer(); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | int Aportis::getch() | ||
113 | { | ||
114 | if (bCompressed == 1) | ||
115 | { | ||
116 | if ((dwRecLen == 0) && !refreshbuffer()) return EOF; | ||
117 | else | ||
118 | { | ||
119 | int c = getc(fin); | ||
120 | dwRecLen--; | ||
121 | currentpos++; | ||
122 | return c; | ||
123 | } | ||
124 | } | ||
125 | if (outptr != cbptr) | ||
126 | { | ||
127 | currentpos++; | ||
128 | return (circbuf[outptr = (outptr + 1) % 2048]); | ||
129 | } | ||
130 | if ((dwRecLen == 0) && !refreshbuffer()) return EOF; | ||
131 | currentpos++; | ||
132 | unsigned int c; | ||
133 | |||
134 | // take a char from the input buffer | ||
135 | c = getc(fin); | ||
136 | dwRecLen--; | ||
137 | // separate the char into zones: 0, 1...8, 9...0x7F, 0x80...0xBF, 0xC0...0xFF | ||
138 | |||
139 | // codes 1...8 mean copy that many chars; for accented chars & binary | ||
140 | if (c == 0) | ||
141 | { | ||
142 | circbuf[outptr = cbptr = (cbptr+1)%2048] = c; | ||
143 | return c; | ||
144 | } | ||
145 | else if (c >= 0x09 && c <= 0x7F) | ||
146 | { | ||
147 | circbuf[outptr = cbptr = (cbptr+1)%2048] = c; | ||
148 | return c; | ||
149 | } | ||
150 | else if (c >= 0x01 && c <= 0x08) | ||
151 | { | ||
152 | dwRecLen -= c; | ||
153 | while(c--) | ||
154 | { | ||
155 | circbuf[cbptr = (cbptr+1)%2048] = getc(fin); | ||
156 | } | ||
157 | return circbuf[outptr = (outptr+1)%2048]; | ||
158 | } | ||
159 | else if (c >= 0x80 && c <= 0xBF) | ||
160 | { | ||
161 | int m,n; | ||
162 | c <<= 8; | ||
163 | c += getc(fin); | ||
164 | dwRecLen--; | ||
165 | m = (c & 0x3FFF) >> COUNT_BITS; | ||
166 | n = c & ((1<<COUNT_BITS) - 1); | ||
167 | n += 3; | ||
168 | while (n--) | ||
169 | { | ||
170 | cbptr = (cbptr+1)%2048; | ||
171 | circbuf[cbptr] = circbuf[(cbptr+2048-m)%2048]; | ||
172 | } | ||
173 | return circbuf[outptr = (outptr+1)%2048]; | ||
174 | } | ||
175 | else if (c >= 0xC0 && c <= 0xFF) | ||
176 | { | ||
177 | circbuf[cbptr = (cbptr+1)%2048] = ' '; | ||
178 | circbuf[cbptr = (cbptr+1)%2048] = c^0x80; | ||
179 | return circbuf[outptr = (outptr+1)%2048]; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | unsigned int Aportis::GetBS(unsigned int bn) | ||
184 | { | ||
185 | DWORD dwPos; | ||
186 | WORD fs; | ||
187 | |||
188 | fseek(fin, 0x56 + 8*bn, SEEK_SET); | ||
189 | fread(&dwPos, 4, 1, fin); | ||
190 | dwPos = SwapLong(dwPos); | ||
191 | fseek(fin,dwPos,SEEK_SET); | ||
192 | |||
193 | // gotorecordnumber(bn+1); | ||
194 | unsigned char ch; | ||
195 | fread(&ch,1,1,fin); | ||
196 | if (ch == 241) | ||
197 | { | ||
198 | fread(&fs,sizeof(fs),1,fin); | ||
199 | fs = SwapWord(fs); | ||
200 | } | ||
201 | else | ||
202 | fs = 0; | ||
203 | return fs; | ||
204 | } | ||
205 | |||
206 | unsigned int Aportis::locate() | ||
207 | { | ||
208 | if (bCompressed == 4) | ||
209 | { | ||
210 | size_t cur = ftell(fin); | ||
211 | unsigned int clen = 0; | ||
212 | for (unsigned int i = 0; i < currentrec-1; i++) | ||
213 | { | ||
214 | unsigned int bs = GetBS(i); | ||
215 | if (bs == 0) break; | ||
216 | clen += bs; | ||
217 | } | ||
218 | fseek(fin,cur,SEEK_SET); | ||
219 | return clen+currentpos; | ||
220 | } | ||
221 | else | ||
222 | return (currentrec-1)*BlockSize+currentpos; | ||
223 | } | ||
224 | |||
225 | void Aportis::locate(unsigned int n) | ||
226 | { | ||
227 | unsigned int offset; | ||
228 | // currentrec = (n >> OFFBITS); | ||
229 | switch (bCompressed) | ||
230 | { | ||
231 | case 4: | ||
232 | { | ||
233 | DWORD clen = 0; | ||
234 | offset = n; | ||
235 | unsigned int i; | ||
236 | for (i = 0; i < nRecs; i++) | ||
237 | { | ||
238 | unsigned int bs = GetBS(i); | ||
239 | if (bs == 0) break; | ||
240 | clen += bs; | ||
241 | if (clen > n) break; | ||
242 | offset = n - clen; | ||
243 | } | ||
244 | currentrec = i; | ||
245 | } | ||
246 | break; | ||
247 | case 1: | ||
248 | case 2: | ||
249 | default: | ||
250 | currentrec = n / BlockSize; | ||
251 | offset = n % BlockSize; | ||
252 | } | ||
253 | |||
254 | outptr = cbptr; | ||
255 | refreshbuffer(); | ||
256 | while (currentpos < offset && getch() != EOF); | ||
257 | } | ||
258 | |||
259 | bool Aportis::refreshbuffer() | ||
260 | { | ||
261 | if (currentrec < nRecs) | ||
262 | { | ||
263 | dwRecLen = recordlength(currentrec+1); | ||
264 | gotorecordnumber(currentrec+1); | ||
265 | if (bCompressed == 4) | ||
266 | { | ||
267 | unsigned char t[3]; | ||
268 | fread(t,1,3,fin); | ||
269 | if (t[0] != 241) | ||
270 | { | ||
271 | printf("You shouldn't be here!\n"); | ||
272 | return false; | ||
273 | } | ||
274 | dwRecLen -= 3; | ||
275 | } | ||
276 | /* | ||
277 | int n = fread(t.buf, 1, dwRecLen, fin); | ||
278 | t.len = n; | ||
279 | // if(bCompressed) | ||
280 | t.Decompress(); | ||
281 | |||
282 | t.buf[t.Len()] = '\0'; | ||
283 | */ | ||
284 | currentpos = 0; | ||
285 | currentrec++; | ||
286 | return true; | ||
287 | } | ||
288 | else { | ||
289 | return false; | ||
290 | } | ||
291 | } | ||