diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4strm.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk4strm.ctr')
-rw-r--r-- | support/dktools/dk4strm.ctr | 978 |
1 files changed, 978 insertions, 0 deletions
diff --git a/support/dktools/dk4strm.ctr b/support/dktools/dk4strm.ctr new file mode 100644 index 0000000000..f26d0f93cb --- /dev/null +++ b/support/dktools/dk4strm.ctr @@ -0,0 +1,978 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% header + +/** @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 +}; + +%% module + + + +#include "dk4strm.h" +#include "dk4mem.h" +#include "dk4enc.h" +#include "dk4numco.h" + + + +$!trace-include + + + + +static +void +dk4stream_api_init(dk4_stream_api_t *ptr) +{ + $? "+ dk4stream_api_init" + DK4_MEMRES(ptr, sizeof(dk4_stream_api_t)); + ptr->d = NULL; + ptr->b = NULL; + ptr->sz_in = 0; + ptr->sz_out = 0; + ptr->res = 0; + ptr->cmd = 0; + $? "- dk4stream_api_init" +} + + + +/** Release memory allocated by a stream. + @param strm Stream to release. +*/ +static +void +dk4stream_release_memory(dk4_stream_t *strm) +{ + $? "+ dk4stream_release_memory PTR=%d", TR_IPTR(strm) + if (NULL != strm) { + dk4mem_release(strm->bi); + dk4mem_release(strm->bo); + strm->d = NULL; + strm->fct = NULL; + strm->bwr = (dk4_um_t)0UL; + strm->szbi = 0; + strm->szbo = 0; + strm->usbi = 0; + strm->usbo = 0; + strm->rebi = 0; + strm->fl = 0; + strm->feoi = 0; + strm->bwo = 0; + dk4mem_free(strm); + } $? "- dk4stream_release_memory" +} + + + + +/** Flush write buffer. +*/ +static +int +dk4stream_i_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp) +{ + dk4_stream_api_t api; + int back = 1; + $? "+ dk4stream_i_flush_write" + /* Write buffer contents (if any) downwards. + */ + if (0 != strm->usbo) { $? ". bytes in output buffer" + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_WRITE; + api.d = strm->d; + api.b = strm->bo; + api.sz_in = strm->usbo; + (*(strm->fct))(&api); + if (0 == api.res) { + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } + /* Flush downwards. + */ + if (0 < flfl) { $? ". downward flush" + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_FLUSH; + api.d = strm->d; + (*(strm->fct))(&api); + if (0 == api.res) { + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_FLUSH_FAILED); + } + } + /* Indicate output buffer is empty. + */ + strm->usbo = 0; + $? "- dk4stream_i_flush_write %d", back + return back; +} + + + +/** Internal function to write one character after checking stream. + @param strm Stream to write to. + @param c Character to write. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. +*/ +static +int +dk4stream_i_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp) +{ + int back = 0; + $? "+ dk4stream_i_write_byte" + if (strm->usbo < strm->szbo) { + (strm->bo)[strm->usbo] = c; + strm->usbo += 1; + strm->bwr += (dk4_um_t)1UL; + if ((dk4_um_t)0UL == strm->bwr) { strm->bwo = 1; } + back = 1; + if (strm->usbo >= strm->szbo) { + back = dk4stream_i_flush_write(strm, 0, erp); + } + } $? "- dk4stream_i_write_byte %d", back + return back; +} + + + + +/** Internal function to 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. +*/ +static +int +dk4stream_i_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp) +{ + dk4_stream_api_t api; + int back = 0; + $? "+ dk4stream_i_c8_read_byte" + if ((0 == strm->feoi) && ((strm->usbi == 0) || (strm->rebi >= strm->usbi))) { + $? ". low level read required" + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_READ; + api.d = strm->d; + api.b = strm->bi; + api.sz_in = strm->szbi; + (*(strm->fct))(&api); + if (0 != api.res) { $? ". low level read succeeded" + strm->rebi = 0; + strm->usbi = api.sz_out; + if (api.sz_out < strm->szbi) { $? ". less bytes than buffer size" + if (0 == strm->zreof) { + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_AT_END; + api.d = strm->d; + (*(strm->fct))(&api); + if (0 != api.res) { $? ". EOF found" + strm->feoi = 1; + } + } + } + } else { $? ". low level read failed" + if (0 != strm->zreof) { + strm->feoi = 1; + } else { + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_AT_END; + api.d = strm->d; + (*(strm->fct))(&api); + if (0 != api.res) { $? ". end of input reached" + strm->feoi = 1; + } + } + } + } else { $? ". data in buffer available" + } + if ((0 < strm->usbi) && (strm->rebi < strm->usbi)) { + $? ". data in buffer available" + *dst = (strm->bi)[strm->rebi]; + strm->rebi += 1; + back = 1; + } else { $? ". no data in buffer" + } + $? "- dk4stream_i_c8_read_byte %d", back + return back; +} + + + + +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 +) +{ + dk4_stream_api_t api; + dk4_stream_t *back = NULL; + $? "+ dk4stream_open" + /* Check arguments + */ + if ((NULL == obj) || (NULL == fct)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + /* Check flag, at least read or write must be set + */ + if (0 == (fl & (DK4_STREAM_READ | DK4_STREAM_WRITE))) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + /* Allocate memory for stream itself + */ + back = dk4mem_new(dk4_stream_t,1,erp); + if (NULL == back) { + goto finished; + } + /* Initialize members + */ + back->d = obj; back->fct = fct; + back->bi = NULL; back->bo = NULL; + back->bwr = (dk4_um_t)0UL; + back->szbi = 0; back->szbo = 0; + back->usbi = 0; back->usbo = 0; back->rebi = 0; + back->fl = fl; back->feoi = 0; + back->bwo = 0; + back->oenc = DK4_FILE_ENCODING_ASCII; + back->zreof = 0; + /* Allocate input buffer or destroy object + */ + if (fl & DK4_STREAM_READ) { + back->szbi = ((0 < ibs) ? ibs : 4096); + back->bi = dk4mem_new(char,back->szbi,erp); + if (NULL == back->bi) { + dk4stream_release_memory(back); + back = NULL; + goto finished; + } + } + /* Allocate output buffer or destroy object + */ + if (fl & DK4_STREAM_WRITE) { + back->szbo = ((0 < obs) ? obs : 4096); + back->bo = dk4mem_new(char,back->szbo,erp); + if (NULL == back->bo) { + dk4stream_release_memory(back); + back = NULL; + goto finished; + } + } + /* Check whether reading zero bytes indicates end of input + */ + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_ZERO_READ_IS_EOF; + api.d = obj; + (*(back->fct))(&api); + if (0 != api.res) { back->zreof = 1; } +finished: + $? "- dk4stream_open PTR=%d", TR_IPTR(back) + return back; +} + + + +int +dk4stream_close(dk4_stream_t *strm, dk4_er_t *erp) +{ + dk4_stream_api_t api; + int back = 0; + $? "+ dk4stream_close" + /* Check argument. + */ + if (NULL == strm) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + + /* Success so far, unless there are errors in the next sections. + */ + back = 1; + + /* Write bytes in output buffer downwards. + */ + if ((strm->fl) & DK4_STREAM_WRITE) { + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_WRITE; + api.d = strm->d; + api.b = strm->bo; + api.sz_in = strm->usbo; + (*(strm->fct))(&api); + if (0 == api.res) { + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } + + /* Attempt to flush downwards. + */ + if ((strm->fl) & DK4_STREAM_WRITE) { + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_FLUSH; + api.d = strm->d; + (*(strm->fct))(&api); + if (0 == api.res) { + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_FLUSH_FAILED); + } + } + + /* Finalize downward data structures. + */ + dk4stream_api_init(&api); + api.cmd = DK4_STREAM_API_CLOSE; + api.d = strm->d; + (*(strm->fct))(&api); + if (0 == api.res) { + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_CLOSE_FAILED); + } + + /* Release memory. + */ + dk4stream_release_memory(strm); + +finished: + $? "- dk4stream_close %d", back + return back; +} + + + +int +dk4stream_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp) +{ + int back = 0; + $? "+ dk4stream_write_byte" + if (NULL != strm) { + if ((strm->fl) & DK4_STREAM_WRITE) { + back = dk4stream_i_write_byte(strm, c, erp); + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_write_byte %d", back + return back; +} + + + +#if NOT_OPTIMIZED + +int +dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp) +{ + char *cptr; /* Traverse buffer */ + int back = 0; + $? "+ dk4stream_write" + if ((NULL != strm) && (NULL != b) && (0 < sz)) { + if ((strm->fl) & DK4_STREAM_WRITE) { + back = 1; + cptr = (char *)b; + while(sz--) { + if (0 == dk4stream_i_write_byte(strm, *(cptr++), erp)) { + back = 0; + } + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_write %d", back + return back; +} + +#else + +int +dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp) +{ + char *cptr; /* Traverse buffer */ + size_t bc; + int back = 0; + int cc; + + $? "+ dk4stream_write %lu", (unsigned long)sz + if ((NULL != strm) && (NULL != b) && (0 < sz)) { + if ((strm->fl) & DK4_STREAM_WRITE) { + back = 1; + cptr = (char *)b; + do { + cc = 0; $? ". loop start" + if (0 < sz) { + if (strm->usbo < strm->szbo) { $? ". can copy" + /* Attempt to copy as many bytes as still free in output buffer */ + bc = strm->szbo - strm->usbo; $? ". bc = %lu", (unsigned long)bc + /* If not enough bytes available, correct number of bytes */ + if (bc > sz) { bc = sz; } $? ". bc = %lu", (unsigned long)bc + DK4_MEMCPY(&((strm->bo)[strm->usbo]), cptr, bc); + strm->usbo += bc; $? ". usbo = %lu", (unsigned long)(strm->usbo) + cptr = &(cptr[bc]); + sz -= bc; $? ". sz = %lu", (unsigned long)sz + if ((DK4_UM_MAX - (dk4_um_t)bc) < strm->bwr) { + strm->bwo = 1; $? "! numeric overflow" + back = 0; + } + strm->bwr += (dk4_um_t)bc; $? ". bwr = %lu", (unsigned long)(strm->bwr) + if (strm->usbo >= strm->szbo) { $? ". must flush" + if (0 == dk4stream_i_flush_write(strm, 0, erp)) { + back = 0; $? "! flush failed" + } + } + if (0 < sz) { cc = 1; } + } else { $? ". must flush first" + if (0 == dk4stream_i_flush_write(strm, 0, erp)) { + back = 0; $? "! flush failed" + } + } + } + } while(0 != cc); + } else { $? "! stream not writable" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { $? "! invalid args" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_write %d", back + return back; +} + +#endif + + + +int +dk4stream_write_char_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp) +{ + size_t sl; + int back = 0; + if ((NULL != strm) && (NULL != str)) { + sl = strlen(str); + back = dk4stream_write(strm, str, sl, erp); + } + else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4stream_flush_read(dk4_stream_t *strm, dk4_er_t *erp) +{ + int back = 0; + $? "+ dk4stream_flush_read" + if (NULL != strm) { + if ((strm->fl) & DK4_STREAM_READ) { + back = 1; + strm->usbi = 0; + strm->rebi = 0; + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_flush_read %d", back + return back; +} + + + +int +dk4stream_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp) +{ + int back = 0; + $? "+ dk4stream_flush_write" + if (NULL != strm) { + if ((strm->fl) & DK4_STREAM_WRITE) { + back = dk4stream_i_flush_write(strm, flfl, erp); + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_flush_write %d", back + return back; +} + + + +int +dk4stream_flush(dk4_stream_t *strm, int flfl, dk4_er_t *erp) +{ + int back = 0; + $? "+ dk4stream_flush" + if (NULL != strm) { + back = 1; + if ((strm->fl) & DK4_STREAM_WRITE) { + if (0 == dk4stream_flush_write(strm, flfl, erp)) { + back = 0; + } + } + if ((strm->fl) & DK4_STREAM_READ) { + if (0 == dk4stream_flush_read(strm, erp)) { + back = 0; + } + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_flush %d", back + return back; +} + + + +int +dk4stream_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp) +{ + int back = 0; + $? "+ dk4stream_c8_read_byte" + if ((NULL != dst) && (NULL != strm)) { $? ". pointers ok" + if ((strm->fl) & DK4_STREAM_READ) { $? ". read" + back = dk4stream_i_c8_read_byte(dst, strm, erp); + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_c8_read_byte %d", back + return back; +} + + + +int +dk4stream_read(void *b, size_t *szptr, dk4_stream_t *strm, dk4_er_t *erp) +{ + char *cptr; /* Traverse the buffer */ + size_t szin; /* Input: Available buffer size */ + size_t szout; /* Output: Used buffer size */ + int back = 0; /* Function result */ + int cc = 1; /* Flag: Can continue */ + $? "+ dk4stream_read" + if ((NULL != b) && (NULL != szptr) && (NULL != strm)) { + if (((strm->fl) & DK4_STREAM_READ) && (0 < *szptr)) { + szin = *szptr; szout = 0; + cptr = (char *)b; + do { + if (0 != dk4stream_i_c8_read_byte(cptr++, strm, erp)) { + szout++; + if (szout >= szin) { + cc = 0; + back = 1; + } + } else { + cc = 0; + if (0 < szout) { + back = 1; + } else { + if (0 != dk4stream_found_eof(strm)) { + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } else { + dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED); + } + } + } + } while (0 != cc); + *szptr = szout; + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4stream_read %d", back + return back; +} + + + +dk4_um_t +dk4stream_bytes_written(const dk4_stream_t *strm) +{ + dk4_um_t back = (dk4_um_t)0UL; + if (NULL != strm) { back = strm->bwr; } + return back; +} + + + +int +dk4stream_overflow_bytes_written(const dk4_stream_t *strm) +{ + int back = 0; + if (NULL != strm) { back = strm->bwo; } + return back; +} + + + +int +dk4stream_found_eof(const dk4_stream_t *strm) +{ + int back = 0; + if (NULL != strm) { + back = strm->feoi; + } + return back; +} + |