%% options copyright owner = Dirk Krause copyright year = 2016-xxxx license = bsd %% header /** @file dk4strmu.h Unserialize data from stream. */ #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 DK4STRM_H_INCLUDED #include #endif #ifdef __cplusplus extern "C" { #endif /** Retrieve 32 bit unsigned value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
if the end of data stream was reached before reading 4 bytes, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_u32(uint32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve 32 bit signed value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
if the end of data stream was reached before reading 4 bytes, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_i32(int32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve 16 bit unsigned value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
if the end of data stream was reached before reading 2 bytes, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_u16(uint16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve 16 bit signed value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
if the end of data stream was reached before reading 2 bytes, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_i16(int16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve 8 bit unsigned value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
if the end of data stream was reached before reading 1 byte, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_u8(uint8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve 8 bit signed value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
if the end of data stream was reached before reading 1 byte, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_i8(int8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve string from stream. The variable strptr points to should be initialized to NULL. On success (string found) this variable is set to dynamically allocated memory. Use dk4mem_release() or dk4mem_free() to release that memory after use. The function sets the destination pointer variable to NULL and reports success if a leading string length 0 was found. @param strptr Address of pointer variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if strptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
on unexpected end of data stream or when missing the finalizing 0x00 byte on end of string, - DK4_E_NOT_FOUND
if EOF was reached, - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available. - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_string(char **strptr, dk4_stream_t *strm, dk4_er_t *erp); /** Retrieve double value from stream. @param ptr Address of result variable. @param strm Data stream to read from. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if ptr is NULL or strm is NULL or not opened for reading, - DK4_E_SYNTAX
on - unexpected end of data stream - or when missing the finalizing 0x00 byte on end of string - or when the string is too long - or when the string does not contain a double number, - DK4_E_NOT_FOUND
if not further data was found (EOF reached), - DK4_E_READ_FAILED
if a read attempt failed for other reasons. */ int dk4stream_unser_double(double *ptr, dk4_stream_t *strm, dk4_er_t *erp); #ifdef __cplusplus } #endif %% module #include "dk4conf.h" #include "dk4strmu.h" #include "dk4mai8dbl.h" #include "dk4mem.h" int dk4stream_unser_u32(uint32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp) { unsigned char buf[8]; size_t sz = 4; unsigned long res = 0UL; int back = 0; if ((NULL != ptr) && (NULL != strm)) { if (0 < dk4stream_read(buf, &sz, strm, erp)) { if (4 == sz) { res = ( ( (unsigned long)(buf[0])) & 0x000000FFUL ) | ( (((unsigned long)(buf[1])) << 8) & 0x0000FF00UL ) | ( (((unsigned long)(buf[2])) << 16) & 0x00FF0000UL ) | ( (((unsigned long)(buf[3])) << 24) & 0xFF000000UL ); *ptr = (uint32_t)res; back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { /* ERROR: Read failed, already reported */ } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4stream_unser_i32(int32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp) { uint32_t res = 0UL; int back = 0; if (NULL != ptr) { back = dk4stream_unser_u32(&res, strm, erp); if (0 < back) { *ptr = (int32_t)res; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4stream_unser_u16(uint16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp) { unsigned char buf[8]; size_t sz = 2; unsigned res = 0U; int back = 0; if ((NULL != ptr) && (NULL != strm)) { if (0 < dk4stream_read(buf, &sz, strm, erp)) { if (2 == sz) { res = ( ( (unsigned)(buf[0])) & 0x00FFU ) | ( (((unsigned)(buf[1])) << 8) & 0xFF00U ); *ptr = (uint16_t)res; back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { /* ERROR: Read failed, already reported */ } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4stream_unser_i16(int16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp) { uint16_t res = 0UL; int back = 0; if (NULL != ptr) { back = dk4stream_unser_u16(&res, strm, erp); if (0 < back) { *ptr = (int16_t)res; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4stream_unser_u8(uint8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp) { unsigned char buf[8]; size_t sz = 1; int back = 0; if ((NULL != ptr) && (NULL != strm)) { if (0 < dk4stream_read(buf, &sz, strm, erp)) { if (1 == sz) { *ptr = (uint8_t)(buf[0]); back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { /* ERROR: Read failed, already reported */ } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4stream_unser_i8(int8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp) { uint8_t res = 0UL; int back = 0; if (NULL != ptr) { back = dk4stream_unser_u8(&res, strm, erp); if (0 < back) { *ptr = (int8_t)res; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4stream_unser_string(char **strptr, dk4_stream_t *strm, dk4_er_t *erp) { char *np = NULL; size_t sz = 0; int back = 0; int res = 0; uint16_t sl = 0; if ((NULL != strptr) && (NULL != strm)) { res = dk4stream_unser_u16(&sl, strm, erp); if (0 < res) { if (0U < sl) { np = dk4mem_new(char, (size_t)sl, erp); if (NULL != np) { sz = (size_t)sl; back = dk4stream_read(np, &sz, strm, erp); if (0 < back) { back = 0; if (sz == (size_t)sl) { if ('\0' == np[sz - 1]) { back = 1; } else { /* ERROR: Missing delimiter */ dk4error_set_simple_error_code( erp, DK4_E_SYNTAX ); dk4mem_free(np); np = NULL; } } else { /* ERROR: Wrong number of bytes */ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); dk4mem_free(np); np = NULL; } } else { /* ERROR: Read attempt failed */ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); dk4mem_free(np); np = NULL; } } else { /* ERROR: Memory, already reported */ } } else { /* ERROR: Length is zero */ back = 1; #if 0 dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); #endif } } else { /* ERROR: Failed to read string length, already reported */ } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } if (NULL != strptr) { *strptr = np; } return back; } int dk4stream_unser_double(double *ptr, dk4_stream_t *strm, dk4_er_t *erp) { char buf[16*sizeof(double)]; const char *ep = NULL; double d = 0.0; size_t szb = sizeof(buf); size_t sz = 0; int back = 0; uint16_t sl = 0; if ((NULL != ptr) && (NULL != strm)) { if (0 < dk4stream_unser_u16(&sl, strm, erp)) { if (0U == sl) { /* Easy variant for 0.0 */ *ptr = 0.0; back = 1; } else { if (szb >= (size_t)sl) { sz = (size_t)sl; if (0 < dk4stream_read(buf, &sz, strm, erp)) { if (sz == (size_t)sl) { if ('\0' == buf[sz - 1]) { back = dk4ma_input_c8_double( &d, buf, &ep, 0, erp ); if (0 < back) { *ptr = d; } else { /* ERROR: Conversion failed, reported */ } } else { /* ERROR: Not 0x00-terminated */ dk4error_set_simple_error_code( erp, DK4_E_SYNTAX ); } } else { /* ERROR: Too few bytes */ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { /* ERROR: Failed to read */ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { /* ERROR: String too long */ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } } else { /* ERROR: Failed to read length, already reported */ } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } /* vim: set ai sw=4 ts=4 : */