summaryrefslogtreecommitdiff
path: root/support/dktools/dk4strm.h
blob: aa02a5ef2811125b94884b0d20cc6fda82e5d9ed (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/*
	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: dk4strm.ctr
*/

/*
Copyright (C) 2015-2017, Dirk Krause

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above opyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used
  to endorse or promote products derived from this software without specific
  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef DK4STRM_H_INCLUDED
/** Avoid multiple inclusions. */
#define DK4STRM_H_INCLUDED 1


#line 10 "dk4strm.ctr"

/**	@file
	Generic dk4_stream_t interface for
	input and output operations.

	CRT on Windows: Optional.
*/

#ifndef DK4CONF_H_INCLUDED
#include "dk4conf.h"
#endif

#ifndef DK4TYPES_H_INCLUDED
#include "dk4types.h"
#endif

#ifndef DK4ERROR_H_INCLUDED
#include "dk4error.h"
#endif

#ifndef STDLIB_H_INCLUDED
#include <stdlib.h>
#define	STDLIB_H_INCLUDED 1
#endif

/**	API for stream function.
*/
typedef struct {
  void		*d;		/**< In: Low level data. */
  char		*b;		/**< In: Buffer for data to write or read. */
  size_t	 sz_in;		/**< In: Number of bytes to write or read. */
  size_t	 sz_out;	/**< Out: Number of bytes written or read. */
  int		 cmd;		/**< In: Command to execute. */
  int		 res;		/**< Out: Low level operation result. */
} dk4_stream_api_t;

/**	Function to execute one low level command.
*/
typedef void dk4_stream_api_fct_t(dk4_stream_api_t *);

/**	Generic I/O stream.
*/
typedef struct {
  void			*d;	/**< Low level data object. */
  dk4_stream_api_fct_t	*fct;	/**< Function for low level operations. */
  char			*bi;	/**< Buffer for input. */
  char			*bo;	/**< Buffer for output. */
  dk4_um_t		 bwr;	/**< Number of bytes written. */
  size_t		 szbi;	/**< Input buffer size. */
  size_t		 szbo;	/**< Output buffer size. */
  size_t		 usbi;	/**< Bytes used in input buffer. */
  size_t		 usbo;	/**< Bytes used in output buffer. */
  size_t		 rebi;	/**< Read bytes from input buffer. */
  int			 fl;	/**< Flags for allowed operations. */
  int			 feoi;	/**< Flag: Found end of input. */
  int			 bwo;	/**< Flag: Numeric overflow in bwr. */
  int			 oenc;	/**< Output encoding for 32 bit characters. */
  int			 zreof;	/**< Flag: Zero bytes read indicates EOF. */
} dk4_stream_t;

#ifdef __cplusplus
extern "C" {
#endif

/**	Open new stream, allocate memory.
	@param	obj	Low level object.
	@param	fct	Low level function.
	@param	fl	Read/write flags: DK4_STREAM_READ, DK4_STREAM_WRITE
			or (DK4_STREAM_READ | DK4_STREAM_WRITE).
	@param	ibs	Input buffer size (0 for default).
	@param	obs	Output buffer size (0 for default).
	@param	erp	Error report, may be NULL.
	@return	Pointer to new stream on success, NULL on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if obj or fct is NULL or fl is invalid,
	- DK4_E_MATH_OVERFLOW<br>
	  if ibs or obs is too large,
	- DK4_E_MEMORY_ALLOCATION_FAILED<br>
	  if allocation of input or output buffer failed.
*/
dk4_stream_t *
dk4stream_open(
  void			*obj,
  dk4_stream_api_fct_t	*fct,
  int			 fl,
  size_t		 ibs,
  size_t		 obs,
  dk4_er_t		*erp
);

/**	Close data stream, release memory.
	@param	strm	Stream to close.
	@param	erp	Error report, may be NULL.
	@return	1 on success, 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL,
	- DK4_E_WRITE_FAILED<br>
	  if writing one ore multiple bytes to the stream failed,
	- DK4_E_FLUSH_FAILED<br>
	  if flushing data downwards failed,
	- DK4_E_CLOSE_FAILED<br>
	  if closing downward data failed.
*/
int
dk4stream_close(dk4_stream_t *strm, dk4_er_t *erp);

/**	Write one byte to output stream.
	@param	strm	Output stream.
	@param	c	Byte to write.
	@param	erp	Error report, may be NULL.
	@return	1 on success, 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for writing,
	- DK4_E_WRITE_FAILED<br>
	  if writing one ore multiple bytes to the stream failed,
	- DK4_E_FLUSH_FAILED<br>
	  if flusing data downwards failed.
*/
int
dk4stream_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp);

/**	Write a buffer to output stream.
	@param	strm	Output stream.
	@param	b	Buffer start address.
	@param	sz	Number of bytes to write.
	@param	erp	Error report, may be NULL.
	@return 1 on success (all bytes written), 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for writing,
	- DK4_E_WRITE_FAILED<br>
	  if writing one ore multiple bytes to the stream failed,
	- DK4_E_FLUSH_FAILED<br>
	  if flusing data downwards failed.
*/
int
dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp);


/**	Write a char string to the stream.
	@param	strm	Output stream.
	@param	str	String to write.
	@param	erp	Error report, may be NULL.
	@return 1 on success (all bytes written), 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for writing,
	- DK4_E_WRITE_FAILED<br>
	  if writing one ore multiple bytes to the stream failed,
	- DK4_E_FLUSH_FAILED<br>
	  if flusing data downwards failed.
*/
int
dk4stream_write_char_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp);

/**	Flush stream input and output data.
	@param	strm	Stream to flush.
	@param	flfl	Flush type: 0=just flush output buffer
	contents to low level object, 1=0+flush low level object,
	2=1+flush all low level objects recursively (for output filtering).
	@param	erp	Error report, may be NULL.
	@return	1 on success, 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL.
	- DK4_E_WRITE_FAILED<br>
	  if writing one ore multiple bytes to the stream failed
	- DK4_E_FLUSH_FAILED<br>
	  if flusing data downwards failed.
*/
int
dk4stream_flush(dk4_stream_t *strm, int flfl, dk4_er_t *erp);

/**	Flush stream output data.
	@param	strm	Stream to flush.
	@param	flfl	Flush type: 0=just flush output buffer
	contents to low level object, 1=0+flush low level object,
	2=1+flush all low level objects recursively (for output filtering).
	@param	erp	Error report, may be NULL.
	@return	1 on success, 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for writing,
	- DK4_E_WRITE_FAILED<br>
	  if writing one ore multiple bytes to the stream failed,
	- DK4_E_FLUSH_FAILED<br>
	  if flushing data downwards failed.
*/
int
dk4stream_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp);

/**	Flush stream input data (discard data in input buffer).
	@param	strm	Stream to flush.
	@param	erp	Error report, may be NULL.
	@return	1 on success, 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for writing.
*/
int
dk4stream_flush_read(dk4_stream_t *strm, dk4_er_t *erp);

/**	Read a single character.
	@param	dst	Pointer to variable for result.
	@param	strm	Stream to read from.
	@param	erp	Error report, may be NULL.
	@return	1 on success, 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for reading,
*/
int
dk4stream_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp);

/**	Read multiple bytes into buffer.
	@param	b	Pointer to buffer start address.
	@param	szptr	Pointer to size variable, in: available size,
			out: number of bytes read.
	@param	strm	Stream to read from.
	@param	erp	Error report, may be NULL.
	@return	1 on success (there were bytes read), 0 on error.
	
	Error codes:
	- DK4_E_INVALID_ARGUMENTS<br>
	  if strm is NULL or not opened for reading,
	- DK4_E_NOT_FOUND<br>
	  if end of input was detected in read attempt,
	- DK4_E_READ_FAILED<br>
	  if a read attempt failed for other reasons.
*/
int
dk4stream_read(void *b, size_t *szptr, dk4_stream_t *strm, dk4_er_t *erp);

/**	Get number of bytes written.
	@param	strm	Stream to get number of bytes for.
	@return	Number of bytes written to the stream (number of bytes
	received from the upside, not number of bytes written
	downwards).
*/
dk4_um_t
dk4stream_bytes_written(const dk4_stream_t *strm);

/**	Check for numeric overflow in number of bytes written.
	@param	strm	Stream to check.
	@return	1 if overflow occured, 0 if there was no overflow.
*/
int
dk4stream_overflow_bytes_written(const dk4_stream_t *strm);

/**	Check whether end of input was found during read attempt.
	@param	strm	Stream to check.
	@return	1 if EOF was detected, 0 otherwise.
*/
int
dk4stream_found_eof(const dk4_stream_t *strm);

#ifdef __cplusplus
}
#endif



/**	Flags whether read or write operations allowed.
*/
enum {
  DK4_STREAM_READ	= 1,	/**< Reading from stream allowed. */
  DK4_STREAM_WRITE	= 2	/**< Writing to stream allowed. */
};



/**	Low level commands to execute in the stream API function.
	The api.cmd is set to one of the values.
	Depending on api.cmd, other api attributes must be set
	on input or must be set as response by the low level function.
*/
enum {
				/**	Read data.
  					Input	api.d:	    Low level data.
					Input	api.b:	    Input data buffer.
					Input	api.sz_in:  Input data buffer
							    size.
					Output	api.res:    1=any bytes found,
							    0=no bytes found.
					Output	api.sz_out: Number of bytes
							    read into input
							    buffer.
				*/
  DK4_STREAM_API_READ = 1,

				/**	Write data.
					Input 	api.d:	    Low level data.
					Input 	api.b:	    Output data buffer.
					Input 	api.sz_in:  Output data buffer
							    size.
					Output	api.res:    1=all bytes
							    written,
							    0=not all bytes
							    written.
					Output	api.sz_out: Number of bytes
							    written.
				*/
  DK4_STREAM_API_WRITE ,

				/**	Flush data.
					Input	api.d:	 Low level data.
					Output	api.res: 1=no error reported,
							 0=error reported.
				*/
  DK4_STREAM_API_FLUSH ,

				/**	Check whether end of input is found.
  					Input	api.d:	 Low level data.
					Output	api.res	 1=end of input
							 reached,
							 0=not yet reached.
				*/
  DK4_STREAM_API_AT_END ,

				/**	Close low level data.
					Input	api.d:	 Low level data.
					Output	api.res: 1=no error reported,
							 0=error reported.
				*/
  DK4_STREAM_API_CLOSE ,

				/**	Check whether a read result of 0
					indicates EOF.
					Input	api.d:	Low level data.
					Output	api.res	1=reading zero bytes
							indicates EOF, 0=no.
				*/
  DK4_STREAM_API_ZERO_READ_IS_EOF
};


#endif