return n_out;
}
-int varicode_decode(char ascii_out[], int varicode_in[], int max_out, int n_in) {
- int i, n_out, n_zeros, found, v_len;
- unsigned short byte1, byte2, packed;
+void varicode_decode_init(struct VARICODE_DEC *dec_states)
+{
+ dec_states->n_zeros = 0;
+ dec_states->v_len = 0;
+ dec_states->packed = 0;
+}
- n_out = 0;
+static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, int varicode_in)
+{
+ int found, i;
+ unsigned short byte1, byte2;
- //printf("max_out: %d n_in: %d\n", max_out, n_in);
- while(n_in && (n_out < max_out)) {
-
- n_zeros = 0;
- v_len = 0;
- packed = 0;
- while ((n_zeros < 2) && n_in && (v_len <= VARICODE_MAX_BITS)) {
- if (*varicode_in++) {
- packed |= (0x8000 >> v_len);
- n_zeros = 0;
- }
- else {
- n_zeros++;
- }
- n_in--;
- v_len++;
- }
-
- //printf("packed: 0x%x n_zeros: %d v_len: %d n_in: %d\n", packed, n_zeros, v_len, n_in);
-
- /* v_len might be > VARICODE_MAX_BITS is an error condition */
+ if (varicode_in) {
+ s->packed |= (0x8000 >> s->v_len);
+ s->n_zeros = 0;
+ }
+ else {
+ s->n_zeros++;
+ }
+ s->v_len++;
- if (v_len && (v_len <= VARICODE_MAX_BITS)) {
- byte1 = packed >> 8;
- byte2 = packed & 0xff;
+ found = 0;
+
+ /* end of character code */
+
+ if (s->n_zeros == 2) {
+ if (s->v_len) {
+ byte1 = s->packed >> 8;
+ byte2 = s->packed & 0xff;
+
+ /* run thru table but note with bit errors means we might
+ not actually find a match */
- found = 0;
for(i=0; i<128; i++) {
if ((byte1 == varicode_table[2*i]) && (byte2 == varicode_table[2*i+1])) {
found = 1;
- //printf("%c\n", (char)i);
- *ascii_out++ = i;
+ *single_ascii = i;
}
}
- if (found == 1)
- n_out++;
}
- //printf("n_out: %d n_in: %d\n", n_out, n_in);
+ varicode_decode_init(s);
+ }
+
+ /* code can run too long if we have a bit error */
+
+ if (s->v_len > VARICODE_MAX_BITS)
+ varicode_decode_init(s);
+
+ return found;
+}
+
+int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], int varicode_in[], int max_out, int n_in) {
+ int output, n_out;
+ char single_ascii;
+
+ n_out = 0;
+
+ printf("varicode_decode: n_in: %d\n", n_in);
+
+ while(n_in && (n_out < max_out)) {
+ output = decode_one_bit(dec_states, &single_ascii, *varicode_in);
+ varicode_in++;
+ n_in--;
+ if (output) {
+ *ascii_out++ = single_ascii;
+ n_out++;
+ }
}
return n_out;
}
+
#ifdef VARICODE_UNITTEST
int main(void) {
char *ascii_in;
int *varicode;
- int i, n_varicode_bits_out, n_ascii_chars_out;
+ int i, n_varicode_bits_out, n_ascii_chars_out, length, half;
char *ascii_out;
+ struct VARICODE_DEC dec_states;
- ascii_in = (char*)malloc(sizeof(varicode_table)/2);
- varicode = (int*)malloc(VARICODE_MAX_BITS*sizeof(int)*strlen(ascii_in));
- ascii_out = (char*)malloc(strlen(ascii_in)+1);
+ length = sizeof(varicode_table)/2;
+
+ ascii_in = (char*)malloc(length);
+ varicode = (int*)malloc(VARICODE_MAX_BITS*sizeof(int)*length);
+ ascii_out = (char*)malloc(length);
- for(i=0; i<sizeof(varicode_table)/2; i++)
+ for(i=0; i<length; i++)
ascii_in[i] = (char)i;
- n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*strlen(ascii_in), strlen(ascii_in));
- n_ascii_chars_out = varicode_decode(ascii_out, varicode, strlen(ascii_in), n_varicode_bits_out);
- assert(n_ascii_chars_out == strlen(ascii_in));
- ascii_out[n_ascii_chars_out] = 0;
+ n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*length, length);
+
+ printf("n_varicode_bits_out: %d\n", n_varicode_bits_out);
+
+ varicode_decode_init(&dec_states);
+ half = n_varicode_bits_out/2;
+ n_ascii_chars_out = varicode_decode(&dec_states, ascii_out, varicode, length, half);
+ printf("n_ascii_chars_out: %d\n", n_ascii_chars_out);
+
+ n_ascii_chars_out += varicode_decode(&dec_states, &ascii_out[n_ascii_chars_out],
+ &varicode[half], length-n_ascii_chars_out, n_varicode_bits_out - half);
+ printf("n_ascii_chars_out: %d\n", n_ascii_chars_out);
+
+ assert(n_ascii_chars_out == length);
//for(i=0; i<n_varicode_bits_out; i++) {
// printf("%d \n", varicode[i]);
//}
//printf("ascii_out: %s\n", ascii_out);
- if (strcmp(ascii_in, ascii_out) == 0)
+ if (memcmp(ascii_in, ascii_out, length) == 0)
printf("Pass\n");
else
printf("Fail\n");
free(ascii_in);
free(ascii_out);
free(varicode);
+
return 0;
}
#endif