summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/Aportis.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/Aportis.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/Aportis.cpp291
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
5Aportis::Aportis() { /*printf("constructing:%x\n",fin);*/ }
6
7CList<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
47int 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
112int 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
183unsigned 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
206unsigned 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
225void 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
259bool 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}