1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include <stdio.h>
#include "dk4rld.h"
#include "dk4edstm.h"
/*
Example file for run-length decoding.
The program reads data from standard input, applies
run-length decoding and writes result data to standard
output.
For better understanding we only do minimal diagnostics
here (set exit status code).
In real world programs one would issue more diagnostics
on problems.
*/
int main(int argc, char *argv[])
{
dk4_rl_dec_t dec; /* Decoder */
const unsigned char *ucptr; /* Address of output buffer */
size_t sz; /* Number of output characters */
size_t i; /* Current output char index */
#if DK4_ON_WINDOWS
int oldimode; /* Old file mode for stdin */
int oldomode; /* Old file mode for stdout */
#endif
int ic; /* Current input char from stdin */
int stopped = 0; /* Flag: EOD found */
int exval = 0; /* Exit status code */
/* On Windows we must set stdin and stdout to binary mode explicitly.
*/
#if DK4_ON_WINDOWS
oldimode = _setmode(_fileno(stdin), _O_BINARY);
oldomode = _setmode(_fileno(stdout), _O_BINARY);
#endif
/* Initialize decoder
*/
dk4rld_init(&dec, NULL);
/* Process standard input.
*/
while (EOF != (ic = fgetc(stdin))) {
if (1 == stopped) {
stopped = 2;
/* Error: Addtional bytes after EOD marker */
}
switch (dk4rld_add(&dec, (unsigned char)ic, NULL)) {
case DK4_EDSTM_FINISHED : {
ucptr = NULL; sz = 0;
if (0 != dk4rld_output(&ucptr, &sz, &dec, NULL)) {
if ((NULL != ucptr) && (0 < sz)) {
for (i = 0; i < sz; i++) {
if (EOF == fputc((int)(ucptr[i]), stdout)) {
exval = 1;
/* Error: Failed to write to standard output */
}
}
}
}
} break;
case DK4_EDSTM_STOP : {
if (0 == stopped) { stopped = 1; }
} break;
case DK4_EDSTM_ERROR : {
exval = 1;
/* Error: Not properly run-length encoded data */
} break;
}
}
/* If successful so far, process final data from decoder
and check for syntax error.
*/
if (0 == exval) {
switch (dk4rld_finish(&dec, NULL)) {
case DK4_EDSTM_FINISHED : {
ucptr = NULL; sz = 0;
if (0 != dk4rld_output(&ucptr, &sz, &dec, NULL)) {
if ((NULL != ucptr) && (0 < sz)) {
for (i = 0; i < sz; i++) {
if (EOF == fputc((int)(ucptr[i]), stdout)) {
exval = 1;
/* Error: Failed to write to standard output */
}
}
}
}
} break;
case DK4_EDSTM_ERROR : {
exval = 1;
/* Error: Not properly run-length encoded data */
} break;
}
}
/* Restore previous file mode for stdin and stdout on Windows.
*/
#if DK4_ON_WINDOWS
fflush(stdout);
_setmode(_fileno(stdout), oldomode);
_setmode(_fileno(stdin), oldimode);
#endif
/* Exit, indicate success or error.
*/
exit(exval); return exval;
}
|