Diffstat (limited to 'noncore/apps/opie-reader/iSilo.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/iSilo.cpp | 638 |
1 files changed, 638 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/iSilo.cpp b/noncore/apps/opie-reader/iSilo.cpp new file mode 100644 index 0000000..5f14b96 --- a/dev/null +++ b/noncore/apps/opie-reader/iSilo.cpp | |||
@@ -0,0 +1,638 @@ | |||
1 | #include "iSilo.h" | ||
2 | #ifdef _WINDOWS | ||
3 | #include <winsock.h> | ||
4 | #endif | ||
5 | u_int8_t *rodata = (u_int8_t *) | ||
6 | "\x10\x11\x12\x00\x08\x07\x09\x06\x0a\x05\x0b\x04\x0c\x03\x0d\x02\x0e\x01\x0f"; | ||
7 | |||
8 | u_int16_t *rsize_min = (u_int16_t *) | ||
9 | "\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0d" | ||
10 | "\x00\x0f\x00\x11\x00\x13\x00\x17\x00\x1b\x00\x1f\x00\x23\x00\x2b\x00\x33\x00" | ||
11 | "\x3b\x00\x43\x00\x53\x00\x63\x00\x73\x00\x83\x00\xa3\x00\xc3\x00\xe3\x00\x02" | ||
12 | "\x01"; | ||
13 | |||
14 | u_int8_t *rsize_delta = (u_int8_t *) | ||
15 | "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x03" | ||
16 | "\x03\x04\x04\x04\x04\x05\x05\x05\x05\x00"; | ||
17 | |||
18 | u_int16_t *rpos_min = (u_int16_t *) | ||
19 | "\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x07\x00\x09\x00\x0d\x00\x11\x00\x19" | ||
20 | "\x00\x21\x00\x31\x00\x41\x00\x61\x00\x81\x00\xc1\x00\x01\x01\x81\x01\x01\x02" | ||
21 | "\x01\x03\x01\x04\x01\x06\x01\x08\x01\x0c\x01\x10\x01\x18\x01\x20\x01\x30\x01" | ||
22 | "\x40\x01\x60"; | ||
23 | |||
24 | u_int8_t *rpos_delta = (u_int8_t *) | ||
25 | "\x00\x00\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07" | ||
26 | "\x08\x08\x09\x09\x0a\x0a\x0b\x0b\x0c\x0c\x0d\x0d"; | ||
27 | |||
28 | void iSilo::init_tables(void) | ||
29 | { | ||
30 | int i; | ||
31 | u_int16_t j; | ||
32 | return; | ||
33 | for (i = 0; i < 3; i++) | ||
34 | rodata[i] = 0x10 + i; | ||
35 | rodata[3] = 0; | ||
36 | for (i = 4; i < 19; i = i + 2) | ||
37 | rodata[i] = 8 + (i-4)/2; | ||
38 | for (i = 5; i < 19; i = i + 2) | ||
39 | rodata[i] = 7 - (i-5)/2; | ||
40 | |||
41 | memset(rsize_delta, 0, 29); | ||
42 | for (i = 4; i < 29; i++) { | ||
43 | rsize_delta[i] = (i - 4) >> 2; | ||
44 | } | ||
45 | memset(rpos_delta, 0, 30); | ||
46 | for (i = 2; i < 30; i++) { | ||
47 | rpos_delta[i] = (i - 2) >> 1; | ||
48 | } | ||
49 | j = 3; | ||
50 | for (i = 0; i < 29; i++) { | ||
51 | rsize_min[i] = j; | ||
52 | j += 1 << rsize_delta[i]; | ||
53 | } | ||
54 | j = 1; | ||
55 | for (i = 0; i < 30; i++) { | ||
56 | rpos_min[i] = j; | ||
57 | j += 1 << rpos_delta[i]; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* read num bits from the file descriptor */ | ||
62 | |||
63 | int iSilo::code2tree(struct s_huffman *h) { | ||
64 | struct s_tree *t, *tmp; | ||
65 | u_int32_t i; | ||
66 | int j, b; | ||
67 | |||
68 | t = new s_tree(); | ||
69 | h->tree = t; | ||
70 | if (t == NULL) return -1; | ||
71 | memset(t, 0, sizeof(struct s_tree)); | ||
72 | t->value = (u_int32_t)-1; | ||
73 | for (i = 0; i < h->num; i++) { | ||
74 | tmp = t; | ||
75 | for (j = 0; j < h->size[i]; j++) { | ||
76 | b = (h->code[i] >> j) & 1; | ||
77 | if (tmp->branch[b] == NULL) { | ||
78 | tmp->branch[b] =new s_tree(); | ||
79 | if (tmp->branch[b] == NULL) return(-1); | ||
80 | memset(tmp->branch[b], 0, sizeof(struct s_tree)); | ||
81 | tmp->value = (u_int32_t)-1; | ||
82 | } | ||
83 | tmp = tmp->branch[b]; | ||
84 | } | ||
85 | if (h->size[i] > 0) tmp->value = i; | ||
86 | } | ||
87 | return (0); | ||
88 | } | ||
89 | |||
90 | u_int32_t iSilo::swap_bits(u_int32_t n, int num) { | ||
91 | n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); | ||
92 | n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); | ||
93 | n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); | ||
94 | n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); | ||
95 | n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); | ||
96 | n >>= (32 - num); | ||
97 | return(n); | ||
98 | } | ||
99 | |||
100 | |||
101 | u_int32_t *iSilo::huffman_get(struct s_huffman *h) | ||
102 | { | ||
103 | int b; | ||
104 | struct s_tree *t = h->tree; | ||
105 | |||
106 | while (t->value == -1) { | ||
107 | b = get_bits(1); | ||
108 | if (t->branch[b] == NULL) { | ||
109 | return(NULL); | ||
110 | } | ||
111 | t = t->branch[b]; | ||
112 | } | ||
113 | return (&t->value); | ||
114 | } | ||
115 | |||
116 | int iSilo::size2code(struct s_huffman *h) { | ||
117 | u_int8_t i, sk, max = 0; | ||
118 | u_int16_t sc, c; | ||
119 | u_int32_t j, k, l; | ||
120 | int skip; | ||
121 | |||
122 | for (l = 0; l < h->num; l++) { | ||
123 | if (h->size[l] > max) max = h->size[l]; | ||
124 | } | ||
125 | |||
126 | for (i = 1; i <= max; i++) { | ||
127 | sc = 0; | ||
128 | c = 0; | ||
129 | for (j = 0; j < h->num; j++) { | ||
130 | if (h->size[j] == i) { | ||
131 | do { | ||
132 | skip = 0; | ||
133 | for (k = 0; k < h->num; k++) { | ||
134 | sk = h->size[k]; | ||
135 | |||
136 | if ((sk < i) && (sk != 0) && !((h->code[k] ^ c) & ((1 << sk)-1))) { | ||
137 | if ((c + 1) == (1 << i)) { | ||
138 | return -1; | ||
139 | } | ||
140 | sc += 1 << (i-sk); | ||
141 | c = swap_bits(sc, i); | ||
142 | skip = 1; | ||
143 | break; | ||
144 | } | ||
145 | } | ||
146 | } while (skip); | ||
147 | h->code[j] = c; | ||
148 | sc++; | ||
149 | c = swap_bits(sc, i); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | return(0); | ||
154 | } | ||
155 | |||
156 | |||
157 | struct s_huffman *iSilo::huffman_create(u_int32_t num) { | ||
158 | struct s_huffman *h; | ||
159 | h = new s_huffman(); | ||
160 | h->tree = new s_tree(); | ||
161 | memset(h->tree, 0, sizeof(struct s_tree)); | ||
162 | h->tree->value = (u_int32_t)-1; | ||
163 | h->num = num; | ||
164 | h->code = new u_int16_t[num]; | ||
165 | h->size = new u_int8_t[num]; | ||
166 | memset(h->size, 0, num); | ||
167 | memset(h->code, 0, num*2); | ||
168 | return (h); | ||
169 | } | ||
170 | |||
171 | void iSilo::kill_tree(struct s_tree *tree) { | ||
172 | if (tree == NULL) { | ||
173 | return; | ||
174 | } | ||
175 | kill_tree(tree->branch[0]); | ||
176 | kill_tree(tree->branch[1]); | ||
177 | delete tree; | ||
178 | } | ||
179 | |||
180 | void iSilo::kill_huffman(struct s_huffman *h) { | ||
181 | if (h == NULL) { | ||
182 | return; | ||
183 | } | ||
184 | kill_tree(h->tree); | ||
185 | delete h->code; | ||
186 | delete h->size; | ||
187 | delete h; | ||
188 | } | ||
189 | |||
190 | int iSilo::read_size(struct s_huffman *prev, struct s_huffman *h) { | ||
191 | u_int32_t *j; | ||
192 | u_int32_t i, n; | ||
193 | int s_ok = 0, ls = 0; | ||
194 | |||
195 | for (i = 0;i < h->num;) { | ||
196 | j = huffman_get(prev); | ||
197 | if (j == NULL) | ||
198 | return(-1); | ||
199 | switch(*j) { | ||
200 | case HM_MEDIUM: | ||
201 | n = get_swapped(3) + 3; /* n bytes of 0 */ | ||
202 | memset(h->size + i, 0, n); | ||
203 | i += n; | ||
204 | break; | ||
205 | case HM_LONG: | ||
206 | n = get_swapped(7) + 11; /* n bytes of 0 */ | ||
207 | memset(h->size + i, 0, n); | ||
208 | i += n; | ||
209 | break; | ||
210 | case HM_SHORT: | ||
211 | if (!s_ok) { | ||
212 | return(-1); | ||
213 | } | ||
214 | n = get_swapped(2) + 3; /* n+1 bytes of ls */ | ||
215 | memset(h->size + i, ls, n); | ||
216 | i += n; | ||
217 | break; | ||
218 | default: | ||
219 | h->size[i] = *j; | ||
220 | ls = *j; | ||
221 | i++; | ||
222 | break; | ||
223 | } | ||
224 | if ((*j == HM_LONG) || (*j == HM_MEDIUM)) { | ||
225 | s_ok = 0; | ||
226 | } else { | ||
227 | s_ok = 1; | ||
228 | } | ||
229 | } | ||
230 | return(0); | ||
231 | } | ||
232 | |||
233 | void iSilo::mymemcpy(u_int8_t *dst, u_int8_t *src, u_int32_t num) { | ||
234 | u_int32_t i; | ||
235 | for (i = 0; i < num; i++) { | ||
236 | dst[i] = src[i]; | ||
237 | } | ||
238 | } | ||
239 | /* return size or -1 for error */ | ||
240 | |||
241 | int iSilo::read_tree(struct s_huffman *prev, struct s_huffman *curr) { | ||
242 | if (read_size(prev, curr) == -1) | ||
243 | return(-1); | ||
244 | if (size2code(curr) == -1) | ||
245 | return(-1); | ||
246 | if (code2tree(curr) == -1) | ||
247 | return(-1); | ||
248 | return(0); | ||
249 | } | ||
250 | bool iSilo::reset_trees() | ||
251 | { | ||
252 | get_bits(0); /* flush buffer */ | ||
253 | /* This is a Table record so we reload the tables */ | ||
254 | kill_huffman(lz); | ||
255 | kill_huffman(text); | ||
256 | kill_huffman(master); | ||
257 | |||
258 | master = huffman_create(19); | ||
259 | text = huffman_create(get_swapped(5) + 257); | ||
260 | lz = huffman_create(get_swapped(5) + 1); | ||
261 | int rdmax = get_swapped(4) + 4; | ||
262 | |||
263 | for (int i = 0; i < rdmax; i++) | ||
264 | { | ||
265 | master->size[rodata[i]] = get_swapped(3); | ||
266 | } | ||
267 | |||
268 | if (size2code(master) == -1) { | ||
269 | qDebug("size2code(master) error: size-table is incompatible"); | ||
270 | return false; | ||
271 | } | ||
272 | |||
273 | code2tree(master); | ||
274 | |||
275 | if (read_tree(master, text) == -1) { | ||
276 | qDebug("read_tree() failed (format incorrect?)"); | ||
277 | return false; | ||
278 | } | ||
279 | |||
280 | if (read_tree(master, lz) == -1) { | ||
281 | qDebug("read_tree() failed (format incorrect?)"); | ||
282 | return false;; | ||
283 | } | ||
284 | return true; | ||
285 | } | ||
286 | u_int32_t iSilo::get_bits(int num) { | ||
287 | int i, r; | ||
288 | u_int32_t result = 0; | ||
289 | |||
290 | if (num == 0) { | ||
291 | pos = 0; | ||
292 | return(0); | ||
293 | } | ||
294 | |||
295 | for (i = 0; i < num; i++) { | ||
296 | if (pos == 0) { | ||
297 | r = fread(buf, sizeof(u_int32_t), 256, fin); | ||
298 | if (r <= 0) { | ||
299 | qDebug("ERROR: Unexpected end of file"); | ||
300 | exit(-1); /* FIXME */ | ||
301 | } | ||
302 | pos = 32*256; | ||
303 | } | ||
304 | |||
305 | pos--; | ||
306 | result <<= 1; | ||
307 | result |= (ntohl(buf[255 - (pos/32)]) >> (31-(pos % 32))) & 1; | ||
308 | } | ||
309 | return(result); | ||
310 | } | ||
311 | u_int32_t iSilo::get_swapped(int num) { | ||
312 | return(swap_bits(get_bits(num),num)); | ||
313 | } | ||
314 | int iSilo::read_text() { | ||
315 | u_int32_t *j; | ||
316 | u_int32_t k, l, bp, idx; | ||
317 | for (bp = 0; bp < buffer_size;) { | ||
318 | j = huffman_get(text); | ||
319 | if (j == NULL) | ||
320 | return(-1); | ||
321 | if (*j == 256) { | ||
322 | break; | ||
323 | } | ||
324 | if (*j >= 257) { | ||
325 | idx = *j - 257; | ||
326 | k = rsize_min[idx]; | ||
327 | if (rsize_delta[idx] != 0) { | ||
328 | k += get_swapped(rsize_delta[idx]); | ||
329 | } | ||
330 | j = huffman_get(lz); | ||
331 | if (j == NULL) | ||
332 | return(-1); | ||
333 | l = rpos_min[*j]; | ||
334 | if (rpos_delta[*j] != 0) { | ||
335 | l += get_swapped(rpos_delta[*j]); | ||
336 | } | ||
337 | if (k <= l) { | ||
338 | memcpy(buffer + bp, buffer + bp - l, k); | ||
339 | } else { | ||
340 | mymemcpy(buffer + bp, buffer + bp - l, k); | ||
341 | } | ||
342 | bp += k; | ||
343 | } else { | ||
344 | buffer[bp] = *j; | ||
345 | bp++; | ||
346 | } | ||
347 | } | ||
348 | return(bp); | ||
349 | } | ||
350 | u_int32_t iSilo::getreccode() | ||
351 | { | ||
352 | u_int32_t offset, rec_code; | ||
353 | gotorecordnumber(cur_rec); | ||
354 | if (fread(&rec_code, sizeof(rec_code), 1, fin) != 1) | ||
355 | { | ||
356 | qDebug("short read"); | ||
357 | return 0xff; | ||
358 | } | ||
359 | return rec_code; | ||
360 | } | ||
361 | bool iSilo::process_record() | ||
362 | { | ||
363 | u_int32_t rec_code = getreccode(); | ||
364 | if (((rec_code & 0xFF) == 0) && (cur_rec != 0)) | ||
365 | { | ||
366 | return false; | ||
367 | } | ||
368 | else | ||
369 | { | ||
370 | /* process text */ | ||
371 | if ((cur_rec % 9) == 1) | ||
372 | { | ||
373 | bsize = 0; | ||
374 | if (!reset_trees()) return false; | ||
375 | cur_rec++; | ||
376 | rec_code = getreccode(); | ||
377 | if (((rec_code & 0xFF) == 0) && (cur_rec != 0)) | ||
378 | { | ||
379 | return false; | ||
380 | } | ||
381 | } | ||
382 | if (cur_rec != 0) | ||
383 | { | ||
384 | /* This is a Data record so we decode text using the table */ | ||
385 | get_bits(0); | ||
386 | bsize = read_text(); | ||
387 | } /* end of text processing */ | ||
388 | } | ||
389 | return true; | ||
390 | } | ||
391 | iSilo::~iSilo() | ||
392 | { | ||
393 | kill_huffman(master); | ||
394 | kill_huffman(lz); | ||
395 | kill_huffman(text); | ||
396 | if (attr != NULL) | ||
397 | { | ||
398 | delete [] attr; | ||
399 | attr = NULL; | ||
400 | } | ||
401 | } | ||
402 | int iSilo::getch() | ||
403 | { | ||
404 | if (filepos >= textsize) | ||
405 | { | ||
406 | // qDebug("File end at record %u", cur_rec); | ||
407 | return EOF; | ||
408 | } | ||
409 | if (current_pos >= bsize) | ||
410 | { | ||
411 | cur_rec++; | ||
412 | if (!process_record()) return EOF; | ||
413 | current_pos = 0; | ||
414 | } | ||
415 | filepos++; | ||
416 | while (attr != NULL && filepos > attr[current_attr].offset) | ||
417 | { | ||
418 | mystyle.unset(); | ||
419 | u_int16_t a = attr[current_attr].value; | ||
420 | // qDebug("Handling attr:%x at pos:%u", a, filepos); | ||
421 | if ((a & 0x1) != 0) | ||
422 | { | ||
423 | mystyle.setBold(); | ||
424 | } | ||
425 | if ((a & 0xe) != 0) | ||
426 | { | ||
427 | qDebug("Unknown attribute:%x (%x)", a & 0xe, a); | ||
428 | } | ||
429 | if ((a & 0x10) != 0) | ||
430 | { | ||
431 | mystyle.setCentreJustify(); | ||
432 | } | ||
433 | else if ((a & 0x20) != 0) | ||
434 | { | ||
435 | mystyle.setRightJustify(); | ||
436 | } | ||
437 | else | ||
438 | { | ||
439 | mystyle.setLeftJustify(); | ||
440 | } | ||
441 | if ((a & 0x40) != 0) | ||
442 | { | ||
443 | qDebug("Unknown attribute:%x (%x)", a & 0x40, a); | ||
444 | } | ||
445 | if ((a & 0x80) != 0) | ||
446 | { | ||
447 | mystyle.setLeftMargin(10); | ||
448 | mystyle.setRightMargin(10); | ||
449 | } | ||
450 | switch (a & 0xf00) | ||
451 | { | ||
452 | case 0x300: | ||
453 | mystyle.setFontSize(0); | ||
454 | break; | ||
455 | case 0xd00: | ||
456 | mystyle.setFontSize(1); | ||
457 | break; | ||
458 | case 0xe00: | ||
459 | mystyle.setFontSize(2); | ||
460 | break; | ||
461 | case 0xf00: | ||
462 | mystyle.setFontSize(3); | ||
463 | break; | ||
464 | default: | ||
465 | mystyle.setFontSize(0); | ||
466 | qDebug("Not sure of font size:%x (%x)", a & 0xf00, a); | ||
467 | break; | ||
468 | } | ||
469 | if ((a & 0x1000) != 0) | ||
470 | { | ||
471 | mystyle.setMono(); | ||
472 | } | ||
473 | if ((a & 0x2000) != 0) | ||
474 | { | ||
475 | mystyle.setItalic(); | ||
476 | } | ||
477 | if ((a & 0x4000) != 0) | ||
478 | { | ||
479 | qDebug("Unknown attribute:%x (%x)", a & 0x4000, a); | ||
480 | } | ||
481 | if ((a & 0x8000) != 0) | ||
482 | { | ||
483 | mystyle.setUnderline(); | ||
484 | } | ||
485 | current_attr++; | ||
486 | if (current_attr >= attr_num) | ||
487 | { | ||
488 | attr_rec++; | ||
489 | read_attr(); | ||
490 | } | ||
491 | } | ||
492 | return buffer[current_pos++]; | ||
493 | } | ||
494 | |||
495 | void iSilo::getch(tchar& ch, CStyle& sty, unsigned long& pos) | ||
496 | { | ||
497 | pos = filepos; | ||
498 | ch = getch(); | ||
499 | sty = mystyle; | ||
500 | } | ||
501 | |||
502 | int iSilo::OpenFile(const char* src) | ||
503 | { | ||
504 | struct stat _stat; | ||
505 | stat(src,&_stat); | ||
506 | filesize = _stat.st_size; | ||
507 | pos = 0; | ||
508 | cur_rec = 0; | ||
509 | buffer_size = 4096; | ||
510 | current_pos = 0; | ||
511 | bsize = 0; | ||
512 | filepos = 0; | ||
513 | |||
514 | if (!Cpdb::openpdbfile(src)) | ||
515 | { | ||
516 | return -1; | ||
517 | } | ||
518 | if (head.creator != 0x6F476F54 // 'ToGo' | ||
519 | || head.type != 0x6F476F54) // 'ToGo') | ||
520 | { | ||
521 | return -1; | ||
522 | } | ||
523 | qDebug("There is %u records in this PDB file", ntohs(head.recordList.numRecords)); | ||
524 | init_tables(); | ||
525 | gotorecordnumber(0); | ||
526 | fread(buffer,1,12,fin); | ||
527 | fread(&textsize, sizeof(textsize), 1, fin); | ||
528 | textsize = ntohl(textsize); | ||
529 | fread(buffer,1,4,fin); | ||
530 | fread(&attr_start,sizeof(attr_start),1,fin); | ||
531 | attr_start = ntohs(attr_start); | ||
532 | fread(buffer,1,2,fin); | ||
533 | fread(&attr_end,sizeof(attr_end),1,fin); | ||
534 | attr_end = ntohs(attr_end); | ||
535 | attr_rec = attr_start; | ||
536 | attr = NULL; | ||
537 | pos_hi = 0xffff; | ||
538 | last_pos = 0xffff; | ||
539 | last_value = 0xffff; | ||
540 | read_attr(); | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | void iSilo::read_attr() | ||
545 | { | ||
546 | // qDebug("read_attr:<%u, %u, %u>", attr_rec, attr_start, attr_end); | ||
547 | current_attr = 0; | ||
548 | if (attr != NULL) | ||
549 | { | ||
550 | delete [] attr; | ||
551 | attr = NULL; | ||
552 | } | ||
553 | if (attr_rec >= attr_start && attr_rec < attr_end) | ||
554 | { | ||
555 | gotorecordnumber(attr_rec); | ||
556 | fread(buffer, 1, 4, fin); | ||
557 | fread(&attr_num, sizeof(attr_num), 1, fin); | ||
558 | attr_num = ntohs(attr_num)+1; | ||
559 | attr = new s_attrib[attr_num]; | ||
560 | for (int j = 0; j < attr_num; j++) | ||
561 | { | ||
562 | fread(&attr[j].offset, 2, 1, fin); | ||
563 | attr[j].offset = htons(attr[j].offset); | ||
564 | } | ||
565 | #ifdef _WINDOWS | ||
566 | for (j = 0; j < attr_num; j++) | ||
567 | #else | ||
568 | for (int j = 0; j < attr_num; j++) | ||
569 | #endif | ||
570 | { | ||
571 | fread(&attr[j].value, 2, 1, fin); | ||
572 | if (attr[j].offset < last_pos) | ||
573 | { | ||
574 | pos_hi++; | ||
575 | } | ||
576 | |||
577 | if ((attr[j].offset == last_pos) && (attr[j].value == last_value)) | ||
578 | { | ||
579 | pos_hi++; | ||
580 | } | ||
581 | |||
582 | last_pos = attr[j].offset; | ||
583 | attr[j].offset |= ((u_int32_t)pos_hi) << 16; | ||
584 | last_value = attr[j].value; | ||
585 | } | ||
586 | current_attr = 0; | ||
587 | // last_value = attr[attr_num-1].value; | ||
588 | // qDebug("Next attr:%u (%u)", attr[current_attr].offset, filepos); | ||
589 | // qDebug("Next attr:%x (%x)", attr[current_attr].offset, filepos); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | void iSilo::locate(unsigned int n) | ||
594 | { | ||
595 | // qDebug("Locating %u", n); | ||
596 | if (n >= textsize) n = 0; | ||
597 | pos = 0; | ||
598 | buffer_size = 4096; | ||
599 | current_pos = 0; | ||
600 | bsize = 0; | ||
601 | /* Brute force | ||
602 | cur_rec = 0; | ||
603 | filepos = 0; | ||
604 | */ // Fast | ||
605 | filepos = n - n % (8*buffer_size); | ||
606 | cur_rec = 9*(n/(8*buffer_size)); | ||
607 | // End of fast | ||
608 | pos_hi = 0xffff; | ||
609 | last_pos = 0xffff; | ||
610 | last_value = 0xffff; | ||
611 | attr_rec = attr_start; | ||
612 | read_attr(); | ||
613 | // While loop added for fast locate | ||
614 | while (attr != NULL && attr[attr_num-1].offset < filepos) | ||
615 | { | ||
616 | attr_rec++; | ||
617 | read_attr(); | ||
618 | } | ||
619 | |||
620 | while (filepos < n) | ||
621 | { | ||
622 | getch(); | ||
623 | } | ||
624 | } | ||
625 | /* | ||
626 | if (!process_record()) return EOF; | ||
627 | current_pos = 0; | ||
628 | */ | ||
629 | |||
630 | QString iSilo::about() | ||
631 | { | ||
632 | return QString("iSilo codec (c) Tim Wentford, based on code supplied by an anonymous donor"); | ||
633 | } | ||
634 | |||
635 | extern "C" | ||
636 | { | ||
637 | CExpander* newcodec() { return new iSilo; } | ||
638 | } | ||