libpromeki main
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
datastream.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <cstdint>
11#include <cstring>
13#include <promeki/core/string.h>
14#include <promeki/core/buffer.h>
17
19
74 public:
80
88
99 enum TypeId : uint8_t {
100 TypeInt8 = 0x01,
101 TypeUInt8 = 0x02,
102 TypeInt16 = 0x03,
103 TypeUInt16 = 0x04,
104 TypeInt32 = 0x05,
105 TypeUInt32 = 0x06,
106 TypeInt64 = 0x07,
107 TypeUInt64 = 0x08,
108 TypeFloat = 0x09,
109 TypeDouble = 0x0A,
110 TypeBool = 0x0B,
111 TypeString = 0x0C,
112 TypeBuffer = 0x0D,
113 TypeVariant = 0x0E
114 };
115
117 static constexpr uint16_t CurrentVersion = 1;
118
120 static constexpr uint8_t Magic[4] = { 0x50, 0x4D, 0x44, 0x53 };
121
132
144
156
158 ~DataStream() = default;
159
160 // ============================================================
161 // Byte order
162 // ============================================================
163
168 void setByteOrder(ByteOrder order) { _byteOrder = order; }
169
174 ByteOrder byteOrder() const { return _byteOrder; }
175
176 // ============================================================
177 // Version
178 // ============================================================
179
189 uint16_t version() const { return _version; }
190
191 // ============================================================
192 // Status and error handling
193 // ============================================================
194
199 Status status() const { return _status; }
200
204 void resetStatus() { _status = Ok; }
205
210 bool atEnd() const;
211
216 IODevice *device() const { return _device; }
217
218 // ============================================================
219 // Write operators
220 // ============================================================
221
250
251 // ============================================================
252 // Read operators
253 // ============================================================
254
283
284 // ============================================================
285 // Raw byte access
286 // ============================================================
287
294 ssize_t readRawData(void *buf, size_t len);
295
302 ssize_t writeRawData(const void *buf, size_t len);
303
310
311 private:
315 void writeHeader();
316
320 void readHeader();
321
326 void writeTag(TypeId id);
327
336 bool readTag(TypeId expected);
337
344 bool readBytes(void *buf, size_t len);
345
352 bool writeBytes(const void *buf, size_t len);
353
354 // Untagged value write helpers (used by Variant to avoid double-tagging)
355 void writeInt8(int8_t val);
356 void writeUInt8(uint8_t val);
357 void writeInt16(int16_t val);
358 void writeUInt16(uint16_t val);
359 void writeInt32(int32_t val);
360 void writeUInt32(uint32_t val);
361 void writeInt64(int64_t val);
362 void writeUInt64(uint64_t val);
363 void writeFloat(float val);
364 void writeDouble(double val);
365 void writeBool(bool val);
366 void writeStringData(const String &val);
367
368 // Untagged value read helpers
369 int8_t readInt8();
370 uint8_t readUInt8();
371 int16_t readInt16();
372 uint16_t readUInt16();
373 int32_t readInt32();
374 uint32_t readUInt32();
375 int64_t readInt64();
376 uint64_t readUInt64();
377 float readFloat();
378 double readDouble();
379 bool readBoolValue();
380 String readStringData();
381
387 template <typename T>
388 void swapIfNeeded(T &val) const {
389 if constexpr (sizeof(T) == 1) return;
390 if(_byteOrder == nativeByteOrder()) return;
391 uint8_t *p = reinterpret_cast<uint8_t *>(&val);
392 if constexpr (sizeof(T) == 2) {
393 std::swap(p[0], p[1]);
394 } else if constexpr (sizeof(T) == 4) {
395 std::swap(p[0], p[3]);
396 std::swap(p[1], p[2]);
397 } else if constexpr (sizeof(T) == 8) {
398 std::swap(p[0], p[7]);
399 std::swap(p[1], p[6]);
400 std::swap(p[2], p[5]);
401 std::swap(p[3], p[4]);
402 }
403 }
404
409 static ByteOrder nativeByteOrder() {
410 static const uint16_t val = 1;
411 return (*reinterpret_cast<const uint8_t *>(&val) == 1)
413 }
414
415 IODevice *_device = nullptr;
416 ByteOrder _byteOrder = BigEndian;
417 uint16_t _version = 0;
418 Status _status = Ok;
419};
420
Generic memory buffer descriptor with alignment and memory space support.
Definition buffer.h:85
Binary stream for structured, portable serialization.
Definition datastream.h:73
DataStream(IODevice *device)
Constructs a DataStream on an IODevice without writing or reading a header.
DataStream & operator>>(Variant &val)
Reads a Variant from type tag + value.
DataStream & operator<<(const Buffer &val)
Writes a Buffer as length-prefixed raw bytes.
DataStream & operator>>(double &val)
Reads a double (IEEE 754).
static DataStream createReader(IODevice *device)
Constructs a DataStream for reading from an IODevice.
DataStream & operator>>(int16_t &val)
Reads an int16_t.
bool atEnd() const
Returns true if the read/write position is at the end.
DataStream & operator>>(float &val)
Reads a float (IEEE 754).
static constexpr uint16_t CurrentVersion
Current wire format version.
Definition datastream.h:117
DataStream & operator>>(uint64_t &val)
Reads a uint64_t.
DataStream & operator<<(uint64_t val)
Writes a uint64_t.
DataStream & operator<<(float val)
Writes a float (IEEE 754).
static DataStream createWriter(IODevice *device)
Constructs a DataStream for writing on an IODevice.
DataStream & operator>>(Buffer &val)
Reads a Buffer from length-prefixed raw bytes.
static constexpr uint8_t Magic[4]
Magic bytes identifying a DataStream ("PMDS").
Definition datastream.h:120
DataStream & operator<<(uint16_t val)
Writes a uint16_t.
DataStream & operator>>(uint16_t &val)
Reads a uint16_t.
DataStream & operator<<(uint8_t val)
Writes a uint8_t.
ssize_t writeRawData(const void *buf, size_t len)
Writes raw bytes to the stream.
uint16_t version() const
Returns the wire format version read from the header.
Definition datastream.h:189
TypeId
Type identifiers written before each value.
Definition datastream.h:99
@ TypeInt8
int8_t
Definition datastream.h:100
@ TypeUInt32
uint32_t
Definition datastream.h:105
@ TypeString
Length-prefixed UTF-8 String.
Definition datastream.h:111
@ TypeInt64
int64_t
Definition datastream.h:106
@ TypeVariant
Type-tagged Variant.
Definition datastream.h:113
@ TypeBuffer
Length-prefixed raw bytes.
Definition datastream.h:112
@ TypeBool
bool (as uint8_t)
Definition datastream.h:110
@ TypeUInt8
uint8_t
Definition datastream.h:101
@ TypeDouble
double (IEEE 754)
Definition datastream.h:109
@ TypeInt32
int32_t
Definition datastream.h:104
@ TypeFloat
float (IEEE 754)
Definition datastream.h:108
@ TypeUInt64
uint64_t
Definition datastream.h:107
@ TypeUInt16
uint16_t
Definition datastream.h:103
@ TypeInt16
int16_t
Definition datastream.h:102
void setByteOrder(ByteOrder order)
Sets the byte order for multi-byte value serialization.
Definition datastream.h:168
DataStream & operator<<(bool val)
Writes a bool (as uint8_t: 0 or 1).
Status
Stream status codes.
Definition datastream.h:82
@ WriteFailed
A write operation failed.
Definition datastream.h:86
@ ReadCorruptData
Data format is invalid.
Definition datastream.h:85
@ Ok
No error.
Definition datastream.h:83
@ ReadPastEnd
Attempted to read beyond available data.
Definition datastream.h:84
ssize_t readRawData(void *buf, size_t len)
Reads raw bytes from the stream.
DataStream & operator<<(const Variant &val)
Writes a Variant as type tag + value.
DataStream & operator<<(int32_t val)
Writes an int32_t.
DataStream & operator<<(int8_t val)
Writes an int8_t.
ByteOrder
Byte order for multi-byte values.
Definition datastream.h:76
@ BigEndian
Network byte order (default).
Definition datastream.h:77
@ LittleEndian
Intel/ARM byte order.
Definition datastream.h:78
Status status() const
Returns the current stream status.
Definition datastream.h:199
DataStream & operator>>(bool &val)
Reads a bool.
DataStream & operator<<(double val)
Writes a double (IEEE 754).
void resetStatus()
Resets the stream status to Ok.
Definition datastream.h:204
DataStream & operator>>(int32_t &val)
Reads an int32_t.
DataStream & operator<<(uint32_t val)
Writes a uint32_t.
ByteOrder byteOrder() const
Returns the current byte order.
Definition datastream.h:174
DataStream & operator<<(const String &val)
Writes a String as length-prefixed UTF-8.
~DataStream()=default
Destructor.
DataStream & operator>>(int64_t &val)
Reads an int64_t.
DataStream & operator>>(uint32_t &val)
Reads a uint32_t.
DataStream & operator>>(int8_t &val)
Reads an int8_t.
DataStream & operator>>(uint8_t &val)
Reads a uint8_t.
ssize_t skipRawData(size_t len)
Skips over raw bytes in the stream without reading them.
DataStream & operator>>(String &val)
Reads a String from length-prefixed UTF-8.
DataStream & operator<<(int16_t val)
Writes an int16_t.
IODevice * device() const
Returns the underlying IODevice.
Definition datastream.h:216
DataStream & operator<<(int64_t val)
Writes an int64_t.
Abstract base class for all I/O devices.
Definition iodevice.h:29
Dynamic array container wrapping std::vector.
Definition list.h:40
Encoding-aware string class with copy-on-write semantics.
Definition string.h:35
#define PROMEKI_NAMESPACE_BEGIN
Starts a promeki namespace block.
Definition namespace.h:14
#define PROMEKI_NAMESPACE_END
Ends a promeki namespace block.
Definition namespace.h:19