MetaTrader 5 / ライブラリ

CBitBuffer Class - Data Serialization in MQL5 - MetaTrader 5のためのライブラリ

147
(8)

CBitBufferクラス - MQL5におけるビットレベルのデータ・シリアライゼーション

CBitBufferクラスは、MQL5でビットレベルのデータ・シリアライゼーションを行うための堅牢な基盤を提供し、データの格納と取得をきめ細かく制御します。このクラスには、可変長整数(ZigZagエンコーディングによるVLQ)を含むさまざまなデータ型のサポートや、文字列および構造体のシリアライズが含まれており、スペースの最適化に優れています。このクラスはパフォーマンスを向上させるために内部バッファリングや指数関数的な配列の増加といった最適化を採用しており、包括的なエラー処理システムを提供している。特に、データ・サイズの最小化が重要なネットワーク通信やファイル・ストレージに有用である(例えば、目盛りデータの圧縮)。

主な特徴

  • ビット・レベル操作:ビット単位、または64ビットまでの指定ビット長でのデータの書き込みと読み出しが可能。
  • データ型のサポート:bool、char、uchar、short、ushort、int、uint、long、ulong、datetime、float、double、string、structのメソッドを含む。
  • 可変長整数 (VLQ): int、uint、long、ulongの値に対してVLQエンコーディングを実装しており、頻繁に使用される小さな整数値のスペースを大幅に節約することができます。
  • エラー処理:ENUM_BIT_BUFFER_ERROR列挙型とGetLastError()/GetLastErrorString()メソッドを提供し、堅牢なエラー管理を実現します。
  • バッファ管理:バッファのクリア、ファイナライズ、生のバッファ・コンテンツの設定、ファイルへの保存、ファイルからのロードを行う関数を提供します。
  • 内部バッファリング:内部64ビット・バッファ(m_writeBufferInternal, m_readBufferInternal)を使用し、メインのulong[]配列に書き込んだり、ulong[]配列から読み込んだりする前にビットを蓄積することで、ビットレベルの操作を最適化します。
//+------------------------------------------------------------------+ | CBitBufferクラス| //| ulong[]バッファに個々のビットまたはビット列を読み書きする。| //| 効率的なビット操作と読み書き混在操作をサポートする。 //+------------------------------------------------------------------+ class CBitBuffer   { public: // コアビット演算    bool              WriteBit(bool bit);                   // シングルビットを書き込む    bool              WriteBits(ulong value, int numberOfBits); // ulongからNビットを書き込む    bool              ReadBit();                            // 1ビットを読み取る    ulong             ReadBits(int numberOfBits);           // Nビットをulongとして読み込む    ulong             PeekBits(int numberOfBits);           // 位置を進めずにNビットを読み出す public: // ポジションとサイズの管理    bool              SetReadPosition(long bitPosition);    // 読み出し位置をビット単位で設定    long              GetReadPosition();    bool              ResetReadPosition();                  // 読み取り位置を0にリセット    bool              SkipBits(long bitsToSkip);            // 現在の読み取り位置からNビットをスキップする    long              GetTotalWrittenBits();                // 書き込まれたビットの合計    long              GetTotalBytesWritten();               // 書き込まれた合計バイト数    long              GetTotalBytesAllocated();             // 割り当てられた総バイト数    long              GetRemainingReadBits();               // 残りの読み取りビット public: // データ型固有の読み書き操作    bool              WriteBool(bool value);    bool              WriteChar(char value);    bool              WriteUChar(uchar value);    bool              WriteShort(short value);    bool              WriteUShort(ushort value);    bool              WriteInt(int value);    bool              WriteUInt(uint value);    bool              WriteLong(long value);    bool              WriteULong(ulong value);    bool              WriteDatetime(datetime value);    bool              WriteFloat(float value);              // 32ビット浮動小数点を書き込む    bool              WriteDouble(double value);            // 64ビットダブルを書き込む    bool              WriteString(string value);            // 文字列をプレフィックス付きで書き込む    template<typename T>    bool              WriteStruct(T &struct_object);        // 長さプレフィックス付き構造体を書き込む    bool              ReadBool();    char              ReadChar();    uchar             ReadUChar();    short             ReadShort();    ushort            ReadUShort();    int               ReadInt();    uint              ReadUInt();    long              ReadLong();    ulong             ReadULong();    datetime          ReadDatetime();    float             ReadFloat();                          // 32ビット浮動小数点を読み込む    double            ReadDouble();                         // 64ビットダブルを読み込む    string            ReadString();                         // 文字列をプレフィックス付きで読み込む    template<typename T>    T                 ReadStruct();                         // 構造体をプレフィックス付きで読み込む public: // 整数の可変長エンコーディング (VLQ)    bool              WriteVarInt(int value);               // ZigZag + VLQ を使用して符号付き int を書き込む。    bool              WriteVarUInt(uint value);             // VLQ を使用した符号なし int の書き込み    bool              WriteVarLong(long value);             // ZigZag + VLQを使用した符号付きロングの書き込み    bool              WriteVarULong(ulong value);           // VLQを使用した符号なしロングの書き込み    int               ReadVarInt();                         // ZigZag + VLQを使用した符号付きintの読み込み    uint              ReadVarUInt();                        // VLQを使用して符号なしintを読み込む    long              ReadVarLong();                        // ZigZag + VLQを使用した符号付きロングの読み込み    ulong             ReadVarULong();                       // VLQを使用して符号なしロングを読み込む public: // バッファ管理    void              Clear();                              // バッファの内容をクリアし、状態をリセットする    bool              GetFinalizedBuffer(ulong &destinationArray[]); // バッファの内容を配列にコピーする    bool              SetRawBuffer(const ulong &sourceBuffer[]);     // 配列からバッファの内容を設定する    bool              Save(string filename);                // バッファをファイルに保存    bool              Load(string filename);                // ファイルからバッファをロードする public: // エラー処理    ENUM_BIT_BUFFER_ERROR GetLastError();                   // 直近のエラーコードを返す    string            GetLastErrorString();                 // エラーの説明文字列を返す    void              ClearLastError() ;                    // 直近のエラーをクリアする    void              PrintHex();                           // メインバッファを16進数で表示(デバッグ用)   }; 


上記で提供されている完全なテスト例 " CBitBuffer_Test.mq5 " は、エラーを検出し、クラスの機能を検証するための最良の方法です。


更新

2025.07.21 - v.1.01 :

  • CBitBufferクラスは、読み取り操作が開始された後の不正な書き込みの試みを積極的に防止し、データの整合性の維持に役立ちます。
  • ユーザーが操作を混在させようとすると、特定のエラー(BIT_BUFFER_MIXED_OPERATION_ERROR)を受け取ります。

2025.07.22 - v.1.02 :

  • 部分的な フラッシュ/リフィルを正しく処理することで、読み取り/書き込み モードの切り替え時にデータの整合性を維持できるように、クラスの設計を変更 しました。
  • 変数(m_operationMode)とエラー・コード(BIT_BUFFER_MIXED_OPERATION_ERROR)を削除しました。
  • コードのコメントを整理し、意図をより明確にしました。
  • より多くのテストケースをカバーするために "CBitBuffer_Test.mq5 "のサンプルを更新。




MetaQuotes Ltdによって英語から翻訳されました。
元のコード: https://www.mql5.com/en/code/61728