TSNStd/Src/String/Buffer.mqh
Nique_372 1dc77364ec
2026-10-09 12:56:38 -05:00

176 lines
6.4 KiB
MQL5

//+------------------------------------------------------------------+
//| Buffer.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com"
#property strict
#ifndef TSNSTD_SRC_STRING_BUFFER_MQH
#define TSNSTD_SRC_STRING_BUFFER_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include <TSN\\Tables\\Bits.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define MQLARTICLES_STRINGBUFF_CMP_IGUAL (0)
#define MQLARTICLES_STRINGBUFF_CMP_MAYOR (1)
#define MQLARTICLES_STRINGBUFF_CMP_MENOR (2)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Clase para trabajr con uchar como buffer para string como tal
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CStringBuffer
{
public:
CStringBuffer(void) {}
~CStringBuffer(void) {}
//--- Find
// normal
static __forceinline int Find(const uchar c, const uchar& in[], int pos, int len, int s_res = 0);
static int FindSwar(const uchar c, const uchar& in[], int pos, int len, int s_res = 0);
// rfind
static __forceinline int RFind(const uchar c, const uchar& in[], int pos, int s_res = 0);
//--- Trim
static void Trim(const uchar &in[], int& len, int &start);
//--- Cmp
static uchar CmpLex(const uchar& in[], int pos, int len, const string& other);
static uchar CmpLex(const uchar &in[], int pos, int len, const uchar& other[], int other_pos, int other_len);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static uchar CStringBuffer::CmpLex(const uchar &in[], int pos, int len, const string &other)
{
//--- iniciales
const int l = StringLen(other);
const int common = fmin(l, len);
//--- iter
for(int i = 0; i < common; i++, pos++)
if(in[pos] != uchar(other[i]))
return in[pos] < uchar(other[i]) ? MQLARTICLES_STRINGBUFF_CMP_MENOR : MQLARTICLES_STRINGBUFF_CMP_MAYOR;
//--- vemos si el len es igual
if(l == len)
return MQLARTICLES_STRINGBUFF_CMP_IGUAL;
//--- ultimo
return len < l ? MQLARTICLES_STRINGBUFF_CMP_MENOR : MQLARTICLES_STRINGBUFF_CMP_MAYOR;
}
//+------------------------------------------------------------------+
static uchar CStringBuffer::CmpLex(const uchar &in[], int pos, int len, const uchar& other[], int other_pos, int other_len)
{
//--- iniciales
const int common = fmin(other_len, len);
//--- iter
for(int i = 0; i < common; i++, pos++, other_pos++)
if(in[pos] != other[other_pos])
return in[pos] < other[other_pos] ? MQLARTICLES_STRINGBUFF_CMP_MENOR : MQLARTICLES_STRINGBUFF_CMP_MAYOR;
//--- vemos si el len es igual
if(other_len == len)
return MQLARTICLES_STRINGBUFF_CMP_IGUAL;
//--- ultimo
return len < other_len ? MQLARTICLES_STRINGBUFF_CMP_MENOR : MQLARTICLES_STRINGBUFF_CMP_MAYOR;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static __forceinline int CStringBuffer::Find(const uchar c, const uchar& in[], int pos, int len, int s_res = 0)
{
len += pos;
for(; pos < len; pos++)
if(in[pos] == c)
return pos - s_res;
return -1;
}
//+------------------------------------------------------------------+
static int CStringBuffer::FindSwar(const uchar c, const uchar& in[], int pos, int len, int s_res = 0)
{
//---
len += pos;
const ulong mask = TSNTABLES_SWAR_REPLY8(c);
for(; pos + 7 < len; pos += 8)
{
const ulong chunk = (ulong)in[pos]
| (ulong)in[pos + 1] << 8
| (ulong)in[pos + 2] << 16
| (ulong)in[pos + 3] << 24
| (ulong)in[pos + 4] << 32
| (ulong)in[pos + 5] << 40
| (ulong)in[pos + 6] << 48
| (ulong)in[pos + 7] << 56;
//---
const ulong x = chunk ^ mask;
const ulong has_x = TSNTABLES_SWAR_HAS(x);
if(has_x == 0)
continue;
//---
const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_x);
return (pos + TSNTABLES_CTZ_64_GET_BYTE(flag_real)) - s_res;
}
//---
for(; pos < len; pos++)
if(in[pos] == c)
return pos - s_res;
//---
return -1;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static __forceinline int CStringBuffer::RFind(const uchar c, const uchar &in[], int pos, int s_res = 0)
{
//---
for(; pos >= 0; pos--)
if(in[pos] == c)
return pos - s_res;
//---
return -1;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CStringBuffer::Trim(const uchar &in[], int& len, int &start)
{
//--- end
int end = (start + len) - 1;
while(end >= 0 && in[end] < 33)
end--;
//--- start
while(start < len && in[start] < 33)
start++;
//---
len = (end - start) + 1;
}
}
//+------------------------------------------------------------------+
#endif // TSNSTD_SRC_STRING_BUFFER_MQH