Biblioteca2/Include/Telegram/jason.mqh
super.admin 464d030eb2 convert
2025-05-30 14:43:36 +02:00

868 lines
43 KiB
MQL5

//+------------------------------------------------------------------ß
//| JAson |
//| This software is licensed under the MIT https://goo.gl/eyJgHe |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006-2017"
#property version "1.08"
#property strict
#define DEBUG_PRINT false
//------------------------------------------------------------------ enum enJAType
enum enJAType { jtUNDEF,jtNULL,jtBOOL,jtINT,jtDBL,jtSTR,jtARRAY,jtOBJ };
//------------------------------------------------------------------ class CJAVal
class CJAVal
{
public:
virtual void Clear()
{
m_parent=NULL;
m_key="";
m_type=jtUNDEF;
m_bv=false;
m_iv=0;
m_dv=0;
m_sv="";
ArrayResize(m_e,0);
}
virtual bool Copy(const CJAVal &a)
{
m_key=a.m_key;
CopyData(a);
return true;
}
virtual void CopyData(const CJAVal &a)
{
m_type=a.m_type;
m_bv=a.m_bv;
m_iv=a.m_iv;
m_dv=a.m_dv;
m_sv=a.m_sv;
CopyArr(a);
}
virtual void CopyArr(const CJAVal &a)
{
int n=ArrayResize(m_e,ArraySize(a.m_e));
for(int i=0; i<n; i++)
{
m_e[i]=a.m_e[i];
m_e[i].m_parent=GetPointer(this);
}
}
public:
CJAVal m_e[];
string m_key;
string m_lkey;
CJAVal *m_parent;
enJAType m_type;
bool m_bv;
long m_iv;
double m_dv;
string m_sv;
static int code_page;
public:
CJAVal()
{
Clear();
}
CJAVal(CJAVal *aparent,enJAType atype)
{
Clear();
m_type=atype;
m_parent=aparent;
}
CJAVal(enJAType t,string a)
{
Clear();
FromStr(t,a);
}
CJAVal(const int a)
{
Clear();
m_type=jtINT;
m_iv=a;
m_dv=(double)m_iv;
m_sv=IntegerToString(m_iv);
m_bv=m_iv!=0;
}
CJAVal(const long a)
{
Clear();
m_type=jtINT;
m_iv=a;
m_dv=(double)m_iv;
m_sv=IntegerToString(m_iv);
m_bv=m_iv!=0;
}
CJAVal(const double a)
{
Clear();
m_type=jtDBL;
m_dv=a;
m_iv=(long)m_dv;
m_sv=DoubleToString(m_dv);
m_bv=m_iv!=0;
}
CJAVal(const bool a)
{
Clear();
m_type=jtBOOL;
m_bv=a;
m_iv=m_bv;
m_dv=m_bv;
m_sv=IntegerToString(m_iv);
}
CJAVal(const CJAVal &a)
{
Clear();
Copy(a);
}
~CJAVal()
{
Clear();
}
public:
virtual bool IsNumeric()
{
return m_type==jtDBL || m_type==jtINT;
}
virtual CJAVal *FindKey(string akey)
{
for(int i=ArraySize(m_e)-1; i>=0; --i) if(m_e[i].m_key==akey) return GetPointer(m_e[i]);
return NULL;
}
virtual CJAVal *HasKey(string akey,enJAType atype=jtUNDEF);
virtual CJAVal *operator[](string akey);
virtual CJAVal *operator[](int i);
void operator=(const CJAVal &a)
{
Copy(a);
}
void operator=(const int a)
{
m_type=jtINT;
m_iv=a;
m_dv=(double)m_iv;
m_bv=m_iv!=0;
}
void operator=(const long a)
{
m_type=jtINT;
m_iv=a;
m_dv=(double)m_iv;
m_bv=m_iv!=0;
}
void operator=(const double a)
{
m_type=jtDBL;
m_dv=a;
m_iv=(long)m_dv;
m_bv=m_iv!=0;
}
void operator=(const bool a)
{
m_type=jtBOOL;
m_bv=a;
m_iv=(long)m_bv;
m_dv=(double)m_bv;
}
void operator=(string a)
{
m_type=(a!=NULL)?jtSTR:jtNULL;
m_sv=a;
m_iv=StringToInteger(m_sv);
m_dv=StringToDouble(m_sv);
m_bv=a!=NULL;
}
bool operator==(const int a)
{
return m_iv==a;
}
bool operator==(const long a)
{
return m_iv==a;
}
bool operator==(const double a)
{
return m_dv==a;
}
bool operator==(const bool a)
{
return m_bv==a;
}
bool operator==(string a)
{
return m_sv==a;
}
bool operator!=(const int a)
{
return m_iv!=a;
}
bool operator!=(const long a)
{
return m_iv!=a;
}
bool operator!=(const double a)
{
return m_dv!=a;
}
bool operator!=(const bool a)
{
return m_bv!=a;
}
bool operator!=(string a)
{
return m_sv!=a;
}
long ToInt() const
{
return m_iv;
}
double ToDbl() const
{
return m_dv;
}
bool ToBool() const
{
return m_bv;
}
string ToStr()
{
return m_sv;
}
virtual void FromStr(enJAType t,string a)
{
m_type=t;
switch(m_type)
{
case jtBOOL:
m_bv=(StringToInteger(a)!=0);
m_iv=(long)m_bv;
m_dv=(double)m_bv;
m_sv=a;
break;
case jtINT:
m_iv=StringToInteger(a);
m_dv=(double)m_iv;
m_sv=a;
m_bv=m_iv!=0;
break;
case jtDBL:
m_dv=StringToDouble(a);
m_iv=(long)m_dv;
m_sv=a;
m_bv=m_iv!=0;
break;
case jtSTR:
m_sv=Unescape(a);
m_type=(m_sv!=NULL)?jtSTR:jtNULL;
m_iv=StringToInteger(m_sv);
m_dv=StringToDouble(m_sv);
m_bv=m_sv!=NULL;
break;
}
}
virtual string GetStr(char &js[],int i,int slen)
{
#ifdef __MQL4__
if(slen<=0) return "";
#endif
char cc[];
ArrayCopy(cc,js,0,i,slen);
return CharArrayToString(cc, 0, WHOLE_ARRAY, CJAVal::code_page);
}
virtual void Set(const CJAVal &a)
{
if(m_type==jtUNDEF) m_type=jtOBJ;
CopyData(a);
}
virtual void Set(const CJAVal &list[]);
virtual CJAVal *Add(const CJAVal &item)
{
if(m_type==jtUNDEF) m_type=jtARRAY; /*ASSERT(m_type==jtOBJ || m_type==jtARRAY);*/ return AddBase(item);
}
virtual CJAVal *Add(const int a)
{
CJAVal item(a);
return Add(item);
}
virtual CJAVal *Add(const long a)
{
CJAVal item(a);
return Add(item);
}
virtual CJAVal *Add(const double a)
{
CJAVal item(a);
return Add(item);
}
virtual CJAVal *Add(const bool a)
{
CJAVal item(a);
return Add(item);
}
virtual CJAVal *Add(string a)
{
CJAVal item(jtSTR,a);
return Add(item);
}
virtual CJAVal *AddBase(const CJAVal &item)
{
int c=ArraySize(m_e);
ArrayResize(m_e,c+1);
m_e[c]=item;
m_e[c].m_parent=GetPointer(this);
return GetPointer(m_e[c]);
}
virtual CJAVal *New()
{
if(m_type==jtUNDEF) m_type=jtARRAY; /*ASSERT(m_type==jtOBJ || m_type==jtARRAY);*/ return NewBase();
}
virtual CJAVal *NewBase()
{
int c=ArraySize(m_e);
ArrayResize(m_e,c+1);
return GetPointer(m_e[c]);
}
virtual string Escape(string a);
virtual string Unescape(string a);
public:
virtual void Serialize(string &js,bool bf=false,bool bcoma=false);
virtual string Serialize()
{
string js;
Serialize(js);
return js;
}
virtual bool Deserialize(char &js[],int slen,int &i);
virtual bool ExtrStr(char &js[],int slen,int &i);
virtual bool Deserialize(string js,int acp=CP_ACP)
{
int i=0;
Clear();
CJAVal::code_page=acp;
char arr[];
int slen=StringToCharArray(js,arr,0,WHOLE_ARRAY,CJAVal::code_page);
return Deserialize(arr,slen,i);
}
virtual bool Deserialize(char &js[],int acp=CP_ACP)
{
int i=0;
Clear();
CJAVal::code_page=acp;
return Deserialize(js,ArraySize(js),i);
}
};
int CJAVal::code_page=CP_ACP;
//------------------------------------------------------------------ HasKey
CJAVal *CJAVal::HasKey(string akey,enJAType atype/*=jtUNDEF*/)
{
for(int i=0; i<ArraySize(m_e); i++) if(m_e[i].m_key==akey)
{
if(atype==jtUNDEF || atype==m_e[i].m_type) return GetPointer(m_e[i]);
break;
}
return NULL;
}
//------------------------------------------------------------------ operator[]
CJAVal *CJAVal::operator[](string akey)
{
if(m_type==jtUNDEF) m_type=jtOBJ;
CJAVal *v=FindKey(akey);
if(v) return v;
CJAVal b(GetPointer(this),jtUNDEF);
b.m_key=akey;
v=Add(b);
return v;
}
//------------------------------------------------------------------ operator[]
CJAVal *CJAVal::operator[](int i)
{
if(m_type==jtUNDEF) m_type=jtARRAY;
while(i>=ArraySize(m_e))
{
CJAVal b(GetPointer(this),jtUNDEF);
if(CheckPointer(Add(b))==POINTER_INVALID) return NULL;
}
return GetPointer(m_e[i]);
}
//------------------------------------------------------------------ Set
void CJAVal::Set(const CJAVal &list[])
{
if(m_type==jtUNDEF) m_type=jtARRAY;
int n=ArrayResize(m_e,ArraySize(list));
for(int i=0; i<n; ++i)
{
m_e[i]=list[i];
m_e[i].m_parent=GetPointer(this);
}
}
//------------------------------------------------------------------ Serialize
void CJAVal::Serialize(string &js,bool bkey/*=false*/,bool coma/*=false*/)
{
if(m_type==jtUNDEF) return;
if(coma) js+=",";
if(bkey) js+=StringFormat("\"%s\":", m_key);
int _n=ArraySize(m_e);
switch(m_type)
{
case jtNULL:
js+="null";
break;
case jtBOOL:
js+=(m_bv?"true":"false");
break;
case jtINT:
js+=IntegerToString(m_iv);
break;
case jtDBL:
js+=DoubleToString(m_dv);
break;
case jtSTR:
{
string ss=Escape(m_sv);
if(StringLen(ss)>0) js+=StringFormat("\"%s\"",ss);
else js+="null";
}
break;
case jtARRAY:
js+="[";
for(int i=0; i<_n; i++) m_e[i].Serialize(js,false,i>0);
js+="]";
break;
case jtOBJ:
js+="{";
for(int i=0; i<_n; i++) m_e[i].Serialize(js,true,i>0);
js+="}";
break;
}
}
//------------------------------------------------------------------ Deserialize
bool CJAVal::Deserialize(char &js[],int slen,int &i)
{
string num="0123456789+-.eE";
int i0=i;
for(; i<slen; i++)
{
char c=js[i];
if(c==0) break;
switch(c)
{
case '\t':
case '\r':
case '\n':
case ' ': // skip
i0=i+1;
break;
case '[': // the beginning of the object. create an object and take it from js
{
i0=i+1;
if(m_type!=jtUNDEF)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // if the value already has a type, then this is an error
return false;
}
m_type=jtARRAY; // set the type
i++;
CJAVal val(GetPointer(this),jtUNDEF);
while(val.Deserialize(js,slen,i))
{
if(val.m_type!=jtUNDEF) Add(val);
if(val.m_type==jtINT || val.m_type==jtDBL || val.m_type==jtARRAY) i++;
val.Clear();
val.m_parent=GetPointer(this);
if(js[i]==']') break;
i++;
if(i>=slen)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false;
}
}
return js[i]==']' || js[i]==0;
}
break;
case ']':
if(!m_parent) return false;
return m_parent.m_type==jtARRAY; // end of array, current value must be an array
case ':':
{
if(m_lkey=="")
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false;
}
CJAVal val(GetPointer(this),jtUNDEF);
CJAVal *oc=Add(val); // object type is not defined yet
oc.m_key=m_lkey;
m_lkey=""; // set the key name
i++;
if(!oc.Deserialize(js,slen,i))
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false;
}
break;
}
case ',': // value separator // value type must already be defined
i0=i+1;
if(!m_parent && m_type!=jtOBJ)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false;
}
else if(m_parent)
{
if(m_parent.m_type!=jtARRAY && m_parent.m_type!=jtOBJ)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false;
}
if(m_parent.m_type==jtARRAY && m_type==jtUNDEF) return true;
}
break;
// primitives can ONLY be in an array / or on their own
case '{': // the beginning of the object. create an object and take it from js
i0=i+1;
if(m_type!=jtUNDEF)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // type error
return false;
}
m_type=jtOBJ; // set type of value
i++;
if(!Deserialize(js,slen,i))
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // pull it out
return false;
}
return js[i]=='}' || js[i]==0;
break;
case '}':
return m_type==jtOBJ; // end of object, current value must be object
case 't':
case 'T': // start true
case 'f':
case 'F': // start false
if(m_type!=jtUNDEF)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // type error
return false;
}
m_type=jtBOOL; // set type
if(i+3<slen)
{
if(StringCompare(GetStr(js, i, 4), "true", false)==0)
{
m_bv=true;
i+=3;
return true;
}
}
if(i+4<slen)
{
if(StringCompare(GetStr(js, i, 5), "false", false)==0)
{
m_bv=false;
i+=4;
return true;
}
}
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false; //wrong type or end of line
break;
case 'n':
case 'N': // start null
if(m_type!=jtUNDEF)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // type error
return false;
}
m_type=jtNULL; // set type of value
if(i+3<slen) if(StringCompare(GetStr(js,i,4),"null",false)==0)
{
i+=3;
return true;
}
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false; // not NULL or end of line
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
case '+':
case '.': // start of number
{
if(m_type!=jtUNDEF)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // type error
return false;
}
bool dbl=false;// set typo of value
int is=i;
while(js[i]!=0 && i<slen)
{
i++;
if(StringFind(num,GetStr(js,i,1))<0) break;
if(!dbl) dbl=(js[i]=='.' || js[i]=='e' || js[i]=='E');
}
m_sv=GetStr(js,is,i-is);
if(dbl)
{
m_type=jtDBL;
m_dv=StringToDouble(m_sv);
m_iv=(long)m_dv;
m_bv=m_iv!=0;
}
else
{
m_type=jtINT; // clarified the value type
m_iv=StringToInteger(m_sv);
m_dv=(double)m_iv;
m_bv=m_iv!=0;
}
i--;
return true; // moved back a character and exited
break;
}
case '\"': // start or end of line
if(m_type==jtOBJ) // if the type is still undefined and the key is not set
{
i++;
int is=i;
if(!ExtrStr(js,slen,i))
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // this is the key, go to the end of line
return false;
}
m_lkey=GetStr(js,is,i-is);
}
else
{
if(m_type!=jtUNDEF)
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); // type error
return false;
}
m_type=jtSTR; // set type of value
i++;
int is=i;
if(!ExtrStr(js,slen,i))
{
if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__));
return false;
}
FromStr(jtSTR,GetStr(js,is,i-is));
return true;
}
break;
}
}
return true;
}
//------------------------------------------------------------------ ExtrStr
bool CJAVal::ExtrStr(char &js[],int slen,int &i)
{
for(; js[i]!=0 && i<slen; i++)
{
char c=js[i];
if(c=='\"') break; // end if line
if(c=='\\' && i+1<slen)
{
i++;
c=js[i];
switch(c)
{
case '/':
case '\\':
case '\"':
case 'b':
case 'f':
case 'r':
case 'n':
case 't':
break; // allowed
case 'u': // \uXXXX
{
i++;
for(int j=0; j<4 && i<slen && js[i]!=0; j++,i++)
{
if(!((js[i]>='0' && js[i]<='9') || (js[i]>='A' && js[i]<='F') || (js[i]>='a' && js[i]<='f')))
{
if(DEBUG_PRINT)Print(m_key+" "+CharToString(js[i])+" "+string(__LINE__)); // not hex
return false;
}
}
i--;
break;
}
default:
break; /*{ return false; } // unresolved escaped character */
}
}
}
return true;
}
//------------------------------------------------------------------ Escape
string CJAVal::Escape(string a)
{
ushort as[], s[];
int n=StringToShortArray(a, as);
if(ArrayResize(s, 2*n)!=2*n) return NULL;
int j=0;
for(int i=0; i<n; i++)
{
switch(as[i])
{
case '\\':
s[j]='\\';
j++;
s[j]='\\';
j++;
break;
case '"':
s[j]='\\';
j++;
s[j]='"';
j++;
break;
case '/':
s[j]='\\';
j++;
s[j]='/';
j++;
break;
case 8:
s[j]='\\';
j++;
s[j]='b';
j++;
break;
case 12:
s[j]='\\';
j++;
s[j]='f';
j++;
break;
case '\n':
s[j]='\\';
j++;
s[j]='n';
j++;
break;
case '\r':
s[j]='\\';
j++;
s[j]='r';
j++;
break;
case '\t':
s[j]='\\';
j++;
s[j]='t';
j++;
break;
default:
s[j]=as[i];
j++;
break;
}
}
a=ShortArrayToString(s,0,j);
return a;
}
//------------------------------------------------------------------ Unescape
string CJAVal::Unescape(string a)
{
ushort as[], s[];
int n=StringToShortArray(a, as);
if(ArrayResize(s, n)!=n) return NULL;
int j=0,i=0;
while(i<n)
{
ushort c=as[i];
if(c=='\\' && i<n-1)
{
switch(as[i+1])
{
case '\\':
c='\\';
i++;
break;
case '"':
c='"';
i++;
break;
case '/':
c='/';
i++;
break;
case 'b':
c=8; /*08='\b'*/;
i++;
break;
case 'f':
c=12;/*0c=\f*/ i++;
break;
case 'n':
c='\n';
i++;
break;
case 'r':
c='\r';
i++;
break;
case 't':
c='\t';
i++;
break;
/*
case 'u': // \uXXXX
{
i+=2; ushort k=0;
for(int jj=0; jj<4 && i<n; jj++,i++)
{
c=as[i]; ushort h=0;
if(c>='0' && c<='9') h=c-'0';
else if(c>='A' && c<='F') h=c-'A'+10;
else if(c>='a' && c<='f') h=c-'a'+10;
else break; // не hex
k+=h*(ushort)pow(16,(3-jj));
}
i--;
c=k;
break;
}
*/
}
}
s[j]=c;
j++;
i++;
}
a=ShortArrayToString(s,0,j);
return a;
}
//+------------------------------------------------------------------+