|
dvander@27
|
1 |
/* expand.c -- Byte Pair Encoding decompression */ |
|
dvander@27
|
2 |
/* Copyright 1996 Philip Gage */ |
|
dvander@27
|
3 |
|
|
dvander@27
|
4 |
/* Byte Pair Compression appeared in the September 1997 |
|
dvander@27
|
5 |
* issue of C/C++ Users Journal. The original source code |
|
dvander@27
|
6 |
* may still be found at the web site of the magazine |
|
dvander@27
|
7 |
* (www.cuj.com). |
|
dvander@27
|
8 |
* |
|
dvander@27
|
9 |
* The decompressor has been modified by me (Thiadmer |
|
dvander@27
|
10 |
* Riemersma) to accept a string as input, instead of a |
|
dvander@27
|
11 |
* complete file. |
|
dvander@27
|
12 |
*/ |
|
dvander@27
|
13 |
#include <assert.h> |
|
dvander@27
|
14 |
#include <stdio.h> |
|
dvander@27
|
15 |
#include "sc.h" |
|
dvander@27
|
16 |
|
|
dvander@27
|
17 |
#define STACKSIZE 16 |
|
dvander@27
|
18 |
|
|
dvander@27
|
19 |
SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]) |
|
dvander@27
|
20 |
{ |
|
dvander@27
|
21 |
unsigned char stack[STACKSIZE]; |
|
dvander@27
|
22 |
short c, top = 0; |
|
dvander@27
|
23 |
int len; |
|
dvander@27
|
24 |
|
|
dvander@27
|
25 |
assert(maxlen > 0); |
|
dvander@27
|
26 |
len = 1; /* already 1 byte for '\0' */ |
|
dvander@27
|
27 |
for (;;) { |
|
dvander@27
|
28 |
|
|
dvander@27
|
29 |
/* Pop byte from stack or read byte from the input string */ |
|
dvander@27
|
30 |
if (top) |
|
dvander@27
|
31 |
c = stack[--top]; |
|
dvander@27
|
32 |
else if ((c = *(unsigned char *)source++) == '\0') |
|
dvander@27
|
33 |
break; |
|
dvander@27
|
34 |
|
|
dvander@27
|
35 |
/* Push pair on stack or output byte to the output string */ |
|
dvander@27
|
36 |
if (c > 127) { |
|
dvander@27
|
37 |
assert(top+2 <= STACKSIZE); |
|
dvander@27
|
38 |
stack[top++] = pairtable[c-128][1]; |
|
dvander@27
|
39 |
stack[top++] = pairtable[c-128][0]; |
|
dvander@27
|
40 |
} |
|
dvander@27
|
41 |
else { |
|
dvander@27
|
42 |
len++; |
|
dvander@27
|
43 |
if (maxlen > 1) { /* reserve one byte for the '\0' */ |
|
dvander@27
|
44 |
*dest++ = (char)c; |
|
dvander@27
|
45 |
maxlen--; |
|
dvander@27
|
46 |
} |
|
dvander@27
|
47 |
} |
|
dvander@27
|
48 |
} |
|
dvander@27
|
49 |
*dest = '\0'; |
|
dvander@27
|
50 |
return len; /* return number of bytes decoded */ |
|
dvander@27
|
51 |
} |
|
dvander@27
|
52 |
|
|
dvander@27
|
53 |
#if 0 /*for testing*/ |
|
dvander@27
|
54 |
#include "sc5.scp" |
|
dvander@27
|
55 |
|
|
dvander@27
|
56 |
int main (int argc, char **argv) |
|
dvander@27
|
57 |
{ |
|
dvander@27
|
58 |
int i; |
|
dvander@27
|
59 |
char str[128]; |
|
dvander@27
|
60 |
|
|
dvander@27
|
61 |
for (i=0; i<58; i++) { |
|
dvander@27
|
62 |
strexpand(str, errmsg[i], sizeof str, SCPACK_TABLE); |
|
dvander@27
|
63 |
printf("%s", str); |
|
dvander@27
|
64 |
} /* for */ |
|
dvander@27
|
65 |
return 0; |
|
dvander@27
|
66 |
} |
|
dvander@27
|
67 |
#endif |
|
dvander@27
|
68 |
|