MQLArticles/Utils/FA/String/Conv.mqh
2026-09-12 19:41:52 -05:00

236 lines
6.8 KiB
MQL5

//+------------------------------------------------------------------+
//| Conv.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_FA_STRING_CONV_MQH
#define MQLARTICLES_UTILS_FA_STRING_CONV_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include <TSN\\BInt\\Def.mqh>
#include <TSN\\Tables\\Basic.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CStringConvert
{
private:
public:
CStringConvert(void) {}
~CStringConvert(void) {}
//---
// static int s_len;
//--- to value genericos
template <typename T>
static void ToValueNSigned(const string& str, int& pos, T& v, const int s_len);
template <typename T>
static void ToValueNUnsigned(const string& str, int& pos, T& v, const int s_len);
//--- to number signed
static __forceinline void ToValue(const string& str, int& pos, long& v, const int s_len) { ToValueNSigned(str, pos, v, s_len); }
static __forceinline void ToValue(const string& str, int& pos, int& v, const int s_len) { ToValueNSigned(str, pos, v, s_len); }
static __forceinline void ToValue(const string& str, int& pos, short& v, const int s_len) { ToValueNSigned(str, pos, v, s_len); }
//--- ungisend
static __forceinline void ToValue(const string& str, int& pos, ulong& v, const int s_len) { ToValueNUnsigned(str, pos, v, s_len); }
static __forceinline void ToValue(const string& str, int& pos, uint& v, const int s_len) { ToValueNUnsigned(str, pos, v, s_len); }
static __forceinline void ToValue(const string& str, int& pos, ushort& v, const int s_len) { ToValueNUnsigned(str, pos, v, s_len); }
static __forceinline void ToValue(const string& str, int& pos, uchar& v, const int s_len) { ToValueNUnsigned(str, pos, v, s_len); }
//---
static void ToValue(const string& str, int& pos, double& v, const int s_len);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//int CStringConvert::s_len = 0;
#define MQLARTICLES_STRINGCONVERT_SINGCHEK(VAL, NV) \
if(ch > 9) \
{ \
if(++pos >= s_len) \
return; \
if(ch == 29) \
VAL = NV; \
ch = (uchar)str[pos] ^ '0'; \
} \
#define MQLARTICLES_STRINGCONVERT_DBL_F double(iv ^ (mask & (1LL << 63)))
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CStringConvert::ToValue(const string &str, int &pos, double &v, const int s_len)
{
//---
long iv = 0;
uchar ch = (uchar)str[pos] ^ '0';
long mask = 0;
//---
MQLARTICLES_STRINGCONVERT_SINGCHEK(mask, -1)
//--- integer
while(true)
{
if(ch > 9)
{
v = MQLARTICLES_STRINGCONVERT_DBL_F;
break;
}
long c = (iv << 3) + (iv << 1) + ch;
if(c < 0)
{
// no entra el actual
int ez = 1; //
while(true)
{
if(++pos >= s_len)
break;
ch = (uchar)str[pos] ^ '0';
if(ch > 9)
break;
ez++;
}
v = MQLARTICLES_STRINGCONVERT_DBL_F * g_Pow10[ez];
break;
}
iv = c;
if(++pos >= s_len)
{
v = MQLARTICLES_STRINGCONVERT_DBL_F;
break;
}
ch = (uchar)str[pos] ^ '0';
}
//---
if(ch == 30 || (ch | 0x20) == 117)
{
//---
if(ch == 30)
{
if(++pos >= s_len)
return;
long frac_int = 0;
int fract_digits = 0;
while(true)
{
ch = (uchar)str[pos] ^ '0';
if(ch > 9)
break;
frac_int = (frac_int << 3) + (frac_int << 1) + ch;
fract_digits++;
if(++pos >= s_len)
break;
}
v += frac_int * g_Exp10[fract_digits];
}
//---
if((ch | 0x20) == 117)
{
if(++pos >= s_len)
return;
//---
bool exp_sign = true;
ch = (uchar)str[pos] ^ '0';
MQLARTICLES_STRINGCONVERT_SINGCHEK(exp_sign, false)
//---
ushort exp_val = 0;
while(true)
{
if(ch > 9)
break;
exp_val = (exp_val << 3) + (exp_val << 1) + ch;
if(++pos >= s_len)
break;
ch = (uchar)str[pos] ^ '0';
}
v *= (exp_sign) ? g_Pow10[exp_val] : g_Exp10[exp_val];
}
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename T>
static void CStringConvert::ToValueNSigned(const string &str, int& pos, T& v, const int s_len)
{
//---
v = 0;
uchar ch = (uchar)str[pos] ^ '0';
T mask = 0;
//---
MQLARTICLES_STRINGCONVERT_SINGCHEK(mask, -1)
//---
while(true)
{
if(ch > 9)
break;
v = (v << 3) + (v << 1) + ch;
if(v < 0) // overflow
{
v = NUMBERUTILS_MAX_VALUE_OFT_SIGNED(T) ^ mask;
return;
}
if(++pos >= s_len)
break;
ch = (uchar)str[pos] ^ '0';
}
//--
v ^= mask;
v -= mask;
}
//+------------------------------------------------------------------+
template <typename T>
static void CStringConvert::ToValueNUnsigned(const string &str, int& pos, T& v, const int s_len)
{
//---
v = 0;
uchar ch = (uchar)str[pos] ^ '0';
//---
if(ch > 9)
{
if(++pos >= s_len)
return;
ch = (uchar)str[pos] ^ '0';
}
//---
while(true)
{
if(ch > 9)
break;
v = (v << 3) + (v << 1) + ch;
if(v < ch) // overflow
{
v = NUMBERUTILS_MAX_VALUE_OFT_USIGNED(T);
return;
}
if(++pos >= s_len)
break;
ch = (uchar)str[pos] ^ '0';
}
}
}
#endif // MQLARTICLES_UTILS_FA_STRING_CONV_MQH
//+------------------------------------------------------------------+