//+------------------------------------------------------------------ß //| 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=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)) { 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; i0) 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) { 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; // конец массива, текущее значение должны быть массивом case ':': { if(m_lkey=="") { if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); return false; } CJAVal val(GetPointer(this),jtUNDEF); CJAVal *oc=Add(val); // тип объекта пока не определён oc.m_key=m_lkey; m_lkey=""; // задали имя ключа i++; if(!oc.Deserialize(js,slen,i)) { if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); return false; } break; } case ',': // разделитель значений // тип значения уже должен быть определён 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; // примитивы могут быть ТОЛЬКО в массиве / либо самостоятельно case '{': // начало объекта. создаем объект и забираем его из js i0=i+1; if(m_type!=jtUNDEF) { if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); return false; }// ошибка типа m_type=jtOBJ; // задали тип значения i++; if(!Deserialize(js,slen,i)) { if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); return false; } // вытягиваем его return js[i]=='}' || js[i]==0; break; case '}': return m_type==jtOBJ; // конец объекта, текущее значение должно быть объектом case 't': case 'T': // начало true case 'f': case 'F': // начало false if(m_type!=jtUNDEF) { if(DEBUG_PRINT)Print(m_key+" "+string(__LINE__)); return false; } // ошибка типа m_type=jtBOOL; // задали тип значения if(i+3='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__)); return false; } // не hex } i--; break; } default: break; /*{ return false; } // неразрешенный символ с экранированием */ } } } 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='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; } //+------------------------------------------------------------------+