#include #include "c_Float.h" c_err_t c_BinaryInStream_Init(c_BinaryInStream_t* self, c_InStream_t* underlying_io_port) { if (!self || !underlying_io_port) return C_ERR_PARAM; self->base_io = underlying_io_port; self->buffer = 0; self->n = 0; return C_SUCCESS; } c_err_t c_BinaryInStream_ReadBits(c_BinaryInStream_t* self, int bit_count, uint32_t* out_value) { if (!self || !self->base_io || !out_value || bit_count < 1 || bit_count > 32) return C_ERR_PARAM; uint32_t result = 0; for (int i = 0; i < bit_count; ++i) { if (self->n == 0) { unsigned char next_byte = 0; c_size_t read_bytes = 0; c_err_t err = c_InStream_Read(self->base_io, &next_byte, 1, &read_bytes); if (err != C_SUCCESS && err != C_ERR_OUTOFBOUND) return err; if (read_bytes == 0) return C_ERR_OUTOFBOUND; self->buffer = next_byte; self->n = 8; } int bit = (self->buffer >> (self->n - 1)) & 1; self->n--; result = (result << 1) | bit; } *out_value = result; return C_SUCCESS; } c_err_t c_BinaryInStream_ReadBit(c_BinaryInStream_t* self, int* out_bit) { if (!out_bit) return C_ERR_PARAM; uint32_t val = 0; c_err_t err = c_BinaryInStream_ReadBits(self, 1, &val); if (err == C_SUCCESS) *out_bit = (int)val; return err; } c_err_t c_BinaryInStream_ReadByte(c_BinaryInStream_t* self, int* out_byte) { if (!out_byte) return C_ERR_PARAM; uint32_t val = 0; c_err_t err = c_BinaryInStream_ReadBits(self, 8, &val); if (err == C_SUCCESS) *out_byte = (int)val; return err; } c_err_t c_BinaryInStream_ReadChar(c_BinaryInStream_t* self, char* out_char) { if (!out_char) return C_ERR_PARAM; uint32_t val = 0; c_err_t err = c_BinaryInStream_ReadBits(self, 8, &val); if (err == C_SUCCESS) *out_char = (char)val; return err; } c_err_t c_BinaryInStream_ReadUInt16(c_BinaryInStream_t* self, uint16_t* out_x) { if (!out_x) return C_ERR_PARAM; uint32_t val = 0; c_err_t err = c_BinaryInStream_ReadBits(self, 16, &val); if (err == C_SUCCESS) *out_x = (uint16_t)val; return err; } c_err_t c_BinaryInStream_ReadUInt32(c_BinaryInStream_t* self, uint32_t* out_x) { return c_BinaryInStream_ReadBits(self, 32, out_x); } c_err_t c_BinaryInStream_ReadUInt64(c_BinaryInStream_t* self, uint64_t* out_x) { if (!out_x) return C_ERR_PARAM; uint32_t high = 0, low = 0; c_err_t err = c_BinaryInStream_ReadBits(self, 32, &high); if (err != C_SUCCESS) return err; err = c_BinaryInStream_ReadBits(self, 32, &low); if (err != C_SUCCESS) return err; *out_x = ((uint64_t)high << 32) | low; return C_SUCCESS; } c_err_t c_BinaryInStream_ReadFloat(c_BinaryInStream_t* self, float* out_x) { if (!out_x) return C_ERR_PARAM; uint32_t bits = 0; c_err_t err = c_BinaryInStream_ReadBits(self, 32, &bits); if (err == C_SUCCESS) *out_x = c_Float_FromBits(bits); return err; } c_err_t c_BinaryInStream_ReadDouble(c_BinaryInStream_t* self, double* out_x) { if (!out_x) return C_ERR_PARAM; uint64_t bits = 0; c_err_t err = c_BinaryInStream_ReadUInt64(self, &bits); if (err == C_SUCCESS) *out_x = c_Double_FromBits(bits); return err; } c_err_t c_BinaryInStream_ReadString(c_BinaryInStream_t* self, char* out_buffer, c_size_t buffer_cap) { if (!self || !out_buffer || buffer_cap == 0) return C_ERR_PARAM; c_size_t idx = 0; while (idx < buffer_cap - 1) { char ch = 0; c_err_t err = c_BinaryInStream_ReadChar(self, &ch); if (err != C_SUCCESS) { out_buffer[idx] = '\0'; return err; } out_buffer[idx++] = ch; if (ch == '\0') return C_SUCCESS; /* Completed extraction sequence safely */ } out_buffer[idx] = '\0'; /* Force sentinel safety ceiling string termination */ return C_ERR_OUTOFBOUND; }