summaryrefslogtreecommitdiff
path: root/support/dktools/test-rld.c
blob: d818b3622ef2d2cb5147f60b88da038f1c428706 (plain)
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
113
114
115
116
117
118
119
120
121
122
123
124
/*
	WARNING: This file was generated by dkct.
	Changes you make here will be lost if dkct is run again!
	You should modify the original source and run dkct on it.
	Original source: test-rld.ctr
*/

/**	@file test-rld.c The test-rld module.
*/


#line 1 "test-rld.ctr"

#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;
}