--- nono/lib/memorystream.h 2026/04/29 17:04:34 1.1.1.2 +++ nono/lib/memorystream.h 2026/04/29 17:05:22 1.1.1.6 @@ -4,70 +4,149 @@ // Licensed under nono-license.txt // +// +// メモリストリーム +// + #pragma once #include "header.h" // ホストのメモリ領域に対するストリームクラスみたいなもの。 -// データの受け渡しはホストエンディアンで、 -// アクセスはビッグエンディアンになる。 -class MemoryStreamBE +class MemoryStream { - protected: - union union_ptr { - uint8 *b; - uint16 *w; - uint32 *l; - }; - public: - // コンストラクタ - MemoryStreamBE() { + MemoryStream(void *start_) { + Init(start_); } - MemoryStreamBE(void *p) { - SetPtr(p); + + // 開始ポインタを設定する + // 現在のポインタ位置は開始ポインタ位置になる + void Init(void *start_) { + start = (uint8 *)start_; + ptr = start; + } + + // 開始ポインタを取得する + void *GetStartPtr() const + { + return (void *)start; } - // デストラクタ不要 - // ポインタを設定する - void SetPtr(void *p) { - ptr.b = (uint8 *)p; + // バイトオフセットを設定する + void SetOffset(uint32 ofs) + { + ptr = start + ofs; } - // ポインタを取得する - void *GetPtr() const { - return (void *)ptr.b; + // 現在のバイトオフセットを取得する + uint32 GetOffset() const + { + return (uint32)(ptr - start); } // 1バイト読み込んでポインタを進める uint32 Read8() { - uint32 data = *ptr.b++; + uint32 data = *ptr++; return data; } + + // 1バイト書き込んでポインタを進める + void Write8(uint32 data) { + *ptr++ = data; + } + + // 文字列を書き込んでポインタを進める。 + // 書き込む文字列も終端の '\0' まで書く。 + void WriteString(const char *p) { + while (*p) { + Write8(*p++); + } + Write8('\0'); + } + + protected: + uint8 *ptr {}; + uint8 *start {}; +}; + +// データの受け渡しはホストエンディアンで、 +// アクセスはビッグエンディアンになる。境界への整列は不要。 +class MemoryStreamBE : public MemoryStream +{ + using inherited = MemoryStream; + public: + MemoryStreamBE(void *start_) + : inherited(start_) + { + } + // BE で2バイト読み込んでポインタを進める uint32 Read16() { - uint32 data = *ptr.w++; - return be16toh(data); + uint32 data; + data = Read8() << 8; + data |= Read8(); + return data; } // BE で4バイト読み込んでポインタを進める uint32 Read32() { - uint32 data = *ptr.l++; - return be32toh(data); + uint32 data; + data = Read16() << 16; + data |= Read16(); + return data; } - // 1バイト書き込んでポインタを進める - void Write8(uint32 data) { - *ptr.b++ = data; - } // BE で2バイト書き込んでポインタを進める void Write16(uint32 data) { - *ptr.w++ = htobe16(data); + Write8(data >> 8); + Write8(data & 0xff); } // BE で4バイト書き込んでポインタを進める void Write32(uint32 data) { - *ptr.l++ = htobe32(data); + Write16(data >> 16); + Write16(data & 0xffff); + } +}; + +// データの受け渡しはホストエンディアンで、 +// アクセスはリトルエンディアンになる。境界への整列は不要。 +class MemoryStreamLE : public MemoryStream +{ + using inherited = MemoryStream; + public: + MemoryStreamLE(void *start_) + : inherited(start_) + { } - private: - union_ptr ptr {}; + // LE で2バイト読み込んでポインタを進める + uint32 Read16() { + uint32 data; + data = Read8(); + data |= Read8() << 8; + return data; + } + // LE で4バイト読み込んでポインタを進める + uint32 Read32() { + uint32 data; + data = Read16(); + data |= Read16() << 16; + return data; + } + + // LE で2バイト書き込んでポインタを進める。 + void Write16(uint32 data) { + Write8(data & 0xff); + Write8(data >> 8); + } + // LE で4バイト書き込んでポインタを進める。 + void Write32(uint32 data) { + Write16(data & 0xffff); + Write16(data >> 16); + } + // LE で8バイト書き込んでポインタを進める。 + void Write64(uint64 data) { + Write32((uint32)data); + Write32(data >> 32); + } };