2026-09-03 18:43:26 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| Bytes.mqh |
|
| | | //| Copyright 2026, Niquel Mendoza |
|
| | | //| https://www.mql5.com |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2026, Niquel Mendoza"
|
| | | #property link "https://www.mql5.com"
|
| | | #property strict
|
| | |
|
| | | #ifndef MQLARTICLES_UTILS_BITS_BITFASTBUFFER_MQH
|
| | | #define MQLARTICLES_UTILS_BITS_BITFASTBUFFER_MQH
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | #include "Def.mqh"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | struct CBitBuffer
|
| | | {
|
| | | public:
|
| | | ulong m_bits[]; // bits como ulong
|
| | | int m_r; // reserva de m_bits
|
| | | int m_s; // bloques ya completos
|
| | | int m_w; // bit de escritura
|
| | |
|
| | |
|
| | | //--- inicializacion basica
|
2026-09-03 19:55:19 -05:00 | | | CBitBuffer();
|
2026-09-03 20:16:56 -05:00 | | | CBitBuffer(int reserve);
|
2026-09-03 19:55:19 -05:00 | | |
|
| | | //--- From
|
| | | void RobarDe(CBitBuffer& bit);
|
| | | void FromBytesLE(const uchar& buf[]);
|
| | | void FromBytesBE(const uchar& buf[]);
|
| | |
|
| | | //--- To
|
| | | int ToBytes(uchar &buf[], int w = 0);
|
| | |
|
| | | //--- Clear
|
| | | void Clear();
|
2026-09-03 18:43:26 -05:00 | | |
|
| | | //--- Write
|
2026-09-03 19:55:19 -05:00 | | | void WriteStringWPadd(const string& str);
|
2026-09-03 18:43:26 -05:00 | | | void WriteBool(bool v);
|
| | | template <typename TInteger>
|
| | | void WriteInteger(const TInteger v);
|
| | | template <typename TInteger>
|
| | | void WriteIntegerArray(const TInteger& v[]);
|
2026-09-03 19:55:19 -05:00 | | | void WriteDouble(const double v);
|
| | | void WriteFloat(const float v);
|
2026-09-03 21:50:10 -05:00 | | |
|
| | | //---
|
| | | __forceinline void SyncArrayRSize() { m_r = ArraySize(m_bits); }
|
2026-09-03 18:43:26 -05:00 | | | };
|
| | |
|
2026-09-03 19:55:19 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CBitBuffer::CBitBuffer(void)
|
| | | : m_s(0), m_w(0), m_r(2)
|
| | | {
|
| | | ArrayResize(m_bits, m_r, m_r);
|
| | | m_bits[0] = 0ULL;
|
| | | }
|
| | |
|
2026-09-03 20:16:56 -05:00 | | |
|
| | | //+------------------------------------------------------------------+
|
| | | CBitBuffer::CBitBuffer(int reserve)
|
| | | : m_s(0), m_w(0), m_r(reserve)
|
| | | {
|
| | | ArrayResize(m_bits, m_r, m_r);
|
| | | m_bits[0] = 0ULL;
|
| | | }
|
| | |
|
2026-09-03 19:55:19 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::FromBytesLE(const uchar &buf[])
|
| | | {
|
| | | //---
|
| | | const int k = ArraySize(buf);
|
| | | if(k < 1)
|
| | | return;
|
| | | //---
|
| | | if(k > m_r)
|
| | | {
|
| | | m_r = k;
|
| | | ArrayResize(m_bits, m_r, m_r);
|
| | | }
|
| | |
|
| | | //---
|
| | | CNumberUtils::ULL_LoadFromBytesLE(k, m_bits, m_s, buf, m_w);
|
| | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::FromBytesBE(const uchar &buf[])
|
| | | {
|
| | | //---
|
| | | const int k = ArraySize(buf);
|
| | | if(k < 1)
|
| | | return;
|
| | | //---
|
| | | if(k > m_r)
|
| | | {
|
| | | m_r = k;
|
| | | ArrayResize(m_bits, m_r, m_r);
|
| | | }
|
| | |
|
| | | //---
|
| | | CNumberUtils::ULL_LoadFromBytesBE(k, m_bits, m_s, buf, m_w);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::RobarDe(CBitBuffer &bit)
|
| | | {
|
| | | m_w = bit.m_w;
|
| | | m_s = bit.m_s;
|
| | | m_r = bit.m_r;
|
| | | ArraySwap(m_bits, bit.m_bits);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | int CBitBuffer::ToBytes(uchar &buf[], int w = 0)
|
| | | {
|
| | | //---
|
| | | const int vs_bytes = (m_s << 3);
|
| | | if(vs_bytes + w > ArraySize(buf))
|
| | | ArrayResize(buf, vs_bytes + w);
|
| | |
|
| | | //---
|
| | | const int blocks = vs_bytes >> 3; // Cuantos bloques enteros procesaremos
|
| | | const int sob = vs_bytes & 7; // % 8 cuantos sobraan
|
| | |
|
| | | //--- Ahora si
|
| | | int r = 0;
|
| | | // bloques completos
|
| | | for(; r < blocks; r++)
|
| | | {
|
| | | const ulong v = m_bits[r];
|
| | |
|
| | | //--- write
|
| | | buf[w++] = uchar(v);
|
| | | buf[w++] = uchar(v >> 8);
|
| | | buf[w++] = uchar(v >> 16);
|
| | | buf[w++] = uchar(v >> 24);
|
| | | buf[w++] = uchar(v >> 32);
|
| | | buf[w++] = uchar(v >> 40);
|
| | | buf[w++] = uchar(v >> 48);
|
| | | buf[w++] = uchar(v >> 56);
|
| | | }
|
| | | // en caso haya sobrante
|
| | | if(sob)
|
| | | {
|
| | | const ulong v = m_bits[r];
|
| | | for(int j = 0; j < (sob << 3); j += 8)
|
| | | buf[w++] = uchar(v >> j);
|
| | | }
|
| | |
|
| | |
|
| | | //---
|
| | | return w;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::Clear(void)
|
| | | {
|
| | | m_w = 0;
|
| | | m_s = 0;
|
| | | m_bits[0] = 0ULL;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::WriteDouble(const double v)
|
| | | {
|
| | | TsnBitInterprete c;
|
| | | c.double_value = v;
|
| | | WriteInteger(c.ulong_value);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::WriteFloat(const float v)
|
| | | {
|
| | | TsnBitInterprete c;
|
| | | c.float_value = v;
|
| | | WriteInteger(c.uint_value);
|
| | | }
|
| | |
|
| | |
|
2026-09-03 18:43:26 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | void CBitBuffer::WriteIntegerArray(const TInteger &v[])
|
| | | {
|
| | | const int t = ArraySize(v);
|
| | | for(int i = 0; i < t; i++)
|
| | | WriteInteger(v[i]);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | void CBitBuffer::WriteInteger(const TInteger v)
|
| | | {
|
| | | //---
|
| | | MQLARTICLES_KEYBYTES_CHECK_RES(2)
|
| | |
|
| | | //---
|
| | | const int sl = 64 - m_w; // lo que logramos flushear
|
| | | if(sl >= MQLARTICLES_BITBUFFER_BITS_SIZE(TInteger))
|
| | | {
|
| | | m_bits[m_s] |= ulong(v) << (m_w);
|
2026-09-03 19:55:19 -05:00 | | | m_w += MQLARTICLES_BITBUFFER_BITS_SIZE(TInteger);
|
2026-09-03 18:43:26 -05:00 | | | }
|
| | | else // desborda
|
| | | {
|
| | | m_bits[m_s++] |= ulong(v) << (m_w);
|
| | | m_bits[m_s] = ulong(v) >> sl;
|
2026-09-03 19:55:19 -05:00 | | | m_w = (MQLARTICLES_BITBUFFER_BITS_SIZE(TInteger) - sl);
|
2026-09-03 18:43:26 -05:00 | | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CBitBuffer::WriteBool(bool v)
|
| | | {
|
| | | MQLARTICLES_KEYBYTES_CHECK_RES(0)
|
| | | m_bits[m_s] |= ulong(v) << (m_w++);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-09-03 19:55:19 -05:00 | | | void CBitBuffer::WriteStringWPadd(const string &str)
|
2026-09-03 18:43:26 -05:00 | | | {
|
| | | //---
|
| | | int len = StringLen(str);
|
| | | int i = 0;
|
| | |
|
| | | //--- pase 1 sobre lo que hay
|
| | | const int uls_len = len >> 3;
|
| | | MQLARTICLES_KEYBYTES_CHECK_RES(uls_len)
|
| | | else
|
| | | if((i = (m_w & 7)) != 0) // Si no es multiplo de 8
|
| | | {
|
| | | // No esta alineado hay que.. alinearlo
|
| | | m_w += 8 - i;
|
| | | }
|
| | |
|
| | | //---- procesamos loq eu nos falta
|
| | | if(m_w != 0)
|
| | | {
|
| | | //---
|
| | | for(i = 0; i < len && m_w < 64; i++, m_w += 8)
|
| | | m_bits[m_s] |= ulong(str[i]) << m_w;
|
| | |
|
| | | //---
|
| | | // Si ha salido por m_w.. igual antes de cada fncino chekeamos w
|
| | | // ahi si w>=64 increma ms
|
| | | //---
|
| | | if(i >= len)
|
| | | return;
|
| | |
|
| | | //---
|
| | | // Si se llego hasta aqui quiere decir que
|
| | | // 1. aun nos queda len.. pero salimos por la condicion de m_w
|
| | | len -= i; // le quitamos loq ue recorrimos
|
| | | m_w = 0;
|
| | | m_s++; // bloque completo
|
| | | }
|
| | |
|
| | |
|
| | | //---
|
| | | int blocks = len >> 3;
|
| | | int sob = len & 7;
|
| | |
|
| | | //-- bloques completos
|
| | | blocks += m_s;
|
| | | for(; m_s < blocks; m_s++)
|
| | | {
|
| | | m_bits[m_s] = ulong(str[i++]) |
|
| | | ulong(str[i++]) << 8 |
|
| | | ulong(str[i++]) << 16 |
|
| | | ulong(str[i++]) << 24 |
|
| | | ulong(str[i++]) << 32 |
|
| | | ulong(str[i++]) << 40 |
|
| | | ulong(str[i++]) << 48 |
|
| | | ulong(str[i++]) << 56;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(sob)
|
| | | {
|
| | | sob <<= 3;
|
| | | m_bits[m_s] = 0ULL;
|
| | | for(; m_w < sob; m_w += 8)
|
2026-09-03 19:55:19 -05:00 | | | m_bits[m_s] |= ulong(str[i++]) << m_w;
|
2026-09-03 18:43:26 -05:00 | | | // m_w aumenta
|
| | | }
|
| | | }
|
| | |
|
2026-09-03 19:55:19 -05:00 | | | //---
|
2026-09-03 18:43:26 -05:00 | | | }
|
| | | //+------------------------------------------------------------------+
|
| | | #endif // MQLARTICLES_UTILS_BITS_BITFASTBUFFER_MQH
|