public static iesJSON CreateErrorObject() { iesJSON j=new iesJSON(); j._value=null; j._jsonType="error"; j._value_valid=false; j._jsonString="!error!"; j._jsonString_valid=false; j._status=-1; return j; }
// Create a single-node iesJSON with the _value set to singleObj public static iesJSON CreateItem(object singleObj, bool IncludeStats=false) { object o=singleObj; iesJSON j=new iesJSON(); j._jsonType=GetObjType(o); if (IncludeStats) { j.TrackStats=true; } switch(j._jsonType) { case "int": case "int32": case "integer": o=System.Convert.ToDouble((int)o); j._jsonType="number"; break; case "int16": case "short": o=System.Convert.ToDouble((short)o); j._jsonType="number"; break; case "int64": case "long": o=System.Convert.ToDouble((long)o); j._jsonType="number"; break; case "float": o=System.Convert.ToDouble((float)o); j._jsonType="number"; break; case "decimal": o=System.Convert.ToDouble((decimal)o); j._jsonType="number"; break; case "double": o=(double)o; j._jsonType="number"; break; } switch(j._jsonType) { case "string": case "number": case "boolean": case "null": j._value=o; j._value_valid=true; j._status=0; break; default: j.AddStatusMessage("ERROR: Invalid type: '" + j._jsonType + "' [err-47]"); j._jsonType=""; j._status=-47; j._value_valid=false; break; } return j; }
public AEnumerator(iesJSON inst) { this.instance = inst; }
// CreateEmptyObject() // This accomplishes the same thing as iesJSON("{}") but avoids recursive loops within the class by simply setting up the Object without any parsing. // This is also faster than calling iesJSON("{}") public static iesJSON CreateEmptyObject() { iesJSON j=new iesJSON(); j._value=new System.Collections.Generic.List<object>(); j._jsonType="object"; j._value_valid=true; j._jsonString="{}"; j._jsonString_valid=false; //j._status already = 0 return j; }
// FUTURE: // Merge() // Make a clone/duplicate of "this" iesJSON (for all sub-items, make a copy of them as well down the entire tree) public iesJSON Clone(bool BuildValue=true,bool BuildString=true) { if (stats!=null) { IncStats("stat_Clone"); } iesJSON j=new iesJSON(); j.UseFlexJson=UseFlexJson; j.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j.SerializeVoidJSON(this, BuildValue, BuildString); return j; }
public iesJSON GetStatsBase(iesJSON addToJSON, bool DoNotReturnNull = false) { iesJSON j; if (stats==null) { if (DoNotReturnNull==false) { return null; } else { j=CreateEmptyObject(); j.NoStatsOrMsgs=true; return j; } } j=addToJSON; if (j==null) { j=CreateEmptyObject(); j.NoStatsOrMsgs=true; } double d; string k; foreach (object o in stats) { iesJSON p; p=(iesJSON)o; // If this is an numeric statistic, add it together. k=(p.Key.ToString()) + ""; if ((substr(k,0,5)=="stat_") && ((p.jsonType)=="number")) { d=j.GetDouble(k,0); j.AddToObjBase(k,d + p.ValueDbl); } // If this is a message list (error message list) then append the messages if (k=="StatusMessages") { foreach(object m in ((iesJSON)o)) { j.AddToArray("StatusMessages",m); } } } return j; }
private int AddToObjBase333(iesJSON oJ, int fMode,ref string tmpStatusMsg2) { if (stats!=null) { IncStats("stat_AddToObjBase2"); } int ret=-1,k; System.Collections.Generic.List<Object> v; if (_status!=0) { return ret; } // *** Requires that this is a json "object" if (_jsonType!="object") { return ret; } if (oJ.Key=="") { return ret; } // Key must be set to a valid 'key' string k=this.IndexOfKey(oJ.Key); v=(System.Collections.Generic.List<Object>)this._value; if (k>=0) { // *** Key already exists. if (fMode==1) { return -11; } // *** Key already exists. try { this.InvalidateJsonString(1); if (fMode>0) { v[k]=oJ; // Replace k-th element with new item } else { // ASSUME REMOVE ONLY v.RemoveAt(k); } ret=0; } catch { } } else { // *** Key does NOT exist if ((fMode==2) || (fMode<=-1)) { return -12; } // *** Key does not exist. //try { this.InvalidateJsonString(1); v.Add(oJ); ret=0; //} catch { } } return ret; }
// *** Clear() // *** src=0 indicates outside source is invalidating us // *** src=1 indicates we are invalidating ourself (a routine in this object) //DEFAULT-PARAMETERS //public void Clear() { Clear(true,0); } //public void Clear(bool ClearParent) { Clear(ClearParent,0); } //public void Clear(bool ClearParent,int src) { public void Clear(bool ClearParent=true,int src=0,bool bClearStats=false) { if (stats!=null) { if (bClearStats) { ClearStats(true); } else { IncStats("stat_Clear"); if (src==0) { IncStats("stat_ClearFromOther"); } if (src==1) { IncStats("stat_ClearFromSelf"); } } } _status=0; _jsonType=""; _value=null; _value_valid=false; InvalidateJsonString(src); // *** Resets _jsonString and _jsonString_valid (and notifies Parent of changes) endpos=0; if (ClearParent) { Parent=null; } }
public void SerializeList(object vList,bool BuildValue, bool BuildString) { //Note: _value and _jsonString have already been cleared string s="["; iesJSON j2; int cnt=0; if (BuildValue) { _value=new System.Collections.Generic.List<Object>(); _value_valid=true; _jsonType="array"; } foreach (object v in (System.Collections.Generic.List<Object>)vList) { j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; object v2=v; j2.Serialize(v2,BuildValue,BuildString); if (j2.Status==0) { if (BuildString) { if (cnt>0) { s=s + ","; } s=s + j2.jsonString; } if (BuildValue) { j2.Parent=this; ((System.Collections.Generic.List<Object>)_value).Add(j2); } cnt=cnt+1; } else { // *** raise error! StatusErr(-94,"Failed to serialize object @ " + cnt + " (e-94) [" + j2.StatusMessage + "]"); break; } } //Next s=s + "]"; if (BuildString) { _jsonString=s; _jsonString_valid=true; } }
// *** splitstr() // *** Used to split a reference string such as "O\'Brien".23."color" // *** The above reference would get from a json object, the O'Brien parameter in an object, then lookup the 23rd record in the array, // *** and look up the "color" parameter in that object. Although this split follows the conventions of a json string (for simplicity) // *** it should not start with a "[" symbol, and typically does not contain boolean, object, array, or null entries. //DEFAULT-PARAMETERS //public object splitstr(string strInput) { return splitstr(strInput, '.'); } //public object splitstr(string strInput, char Separator) { public System.Collections.Generic.List<Object> splitstr(string strInput, char Separator='.') { iesJSON j2; int pStatus; int ptr; string c; System.Collections.Generic.List<object> s; // *** Create an array of objects. Each can be a value(string,number,boolean,object,array,null) // *** but typically should only be 'string' or 'number' for the internal use within GetObj() and GetStr() s=new System.Collections.Generic.List<Object>(); ptr=0; pStatus=1; while (ptr<=strInput.Length) { j2=null; findnext(strInput,ptr); switch (pStatus) { case 1: // *** This should be a JSON item: object, array, string, boolean, number, or null j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j2.Deserialize(strInput,ptr,true); if (j2.Status==0) { if ((j2.jsonType=="string") || (j2.jsonType=="number")) { // *** For all cases: Object, Array, String, Number, Boolean, or null s.Add(j2.Value); ptr=j2.endpos; pStatus=2; } else { pStatus=3; } // ERROR } else { pStatus=3; } //ERROR break; case 2: c=substr(strInput,ptr,1); if (c==(Separator + "")) { ptr=ptr+1; pStatus=1; } else { pStatus=3; } //ERROR break; } // switch if (pStatus==3) { return null; } // *** Indicates an error in string format } //do j2=null; return s; }
public void SerializeCollectionKeys(object vList,bool BuildValue,bool BuildString) { //Note: _value and _jsonString have already been cleared string s="{",t; iesJSON j2; int cnt=0; bool fProcessed=false; if (BuildValue) { _value=new System.Collections.Generic.List<Object>(); _value_valid=true; _jsonType="object"; } if (vList==null) { return; } //Return with an empty object t=GetObjType(vList); // *************************************** DICTIONARY if (t.IndexOf("dictionary")>=0) { fProcessed=true; System.Collections.Generic.Dictionary<string,object> vList2=(System.Collections.Generic.Dictionary<string,object>) vList; //System.Collections.ObjectModel.Collection<object> vList2=(System.Collections.ObjectModel.Collection<object>) vList; foreach ( System.Collections.Generic.KeyValuePair<string, object> kvp in vList2 ) { string v=kvp.Key; object o=kvp.Value; j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j2.Serialize(o,BuildValue,BuildString); j2.Key=v; if (j2.Status==0) { if (BuildString) { if (cnt>0) { s=s + ","; } s=s + "\"" + v + "\":" + j2.jsonString; } if (BuildValue) { j2.Parent=this; ((System.Collections.Generic.List<Object>)_value).Add(j2); } cnt=cnt+1; } else { // *** raise error! StatusErr(-93,"Failed to serialize collection key @ " + cnt + " key=" + v + " (e-93) [" + j2.StatusMessage + "]"); break; } } // Next } // *************************************** HTML FORM RESPONSE if (t.IndexOf("http")>=0) { fProcessed=true; //System.Collections.Generic.Dictionary<string,object> vList2=(System.Collections.Generic.Dictionary<string,object>) vList; //System.Collections.ObjectModel.Collection<object> vList2=(System.Collections.ObjectModel.Collection<object>) vList; System.Collections.Specialized.NameValueCollection vList2 = (System.Collections.Specialized.NameValueCollection)vList; foreach (string v in vList2) { object o = vList2[v]; j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j2.Serialize(o,BuildValue,BuildString); j2.Key=v; if (j2.Status==0) { if (BuildString) { if (cnt>0) { s=s + ","; } s=s + "\"" + v + "\":" + j2.jsonString; } if (BuildValue) { j2.Parent=this; ((System.Collections.Generic.List<Object>)_value).Add(j2); } cnt=cnt+1; } else { // *** raise error! StatusErr(-93,"Failed to serialize collection key @ " + cnt + " key=" + v + " (e-93) [" + j2.StatusMessage + "]"); break; } } // Next } if (fProcessed==false) { _status=-87; AddStatusMessage("ERROR: Failed to process collection. Type not valid: '" + t + "' [err-87]"); } s=s + "}"; if (BuildString) { _jsonString=s; _jsonString_valid=true; } }
// FUTURE: we can end up in an infinite loop if index does contain a "." but it is inside quotes which makes it a JSON reference. public bool ReplaceAt(string index, iesJSON newItem) { if (ValidateValue()==false) { AddStatusMessage("ERROR: Unable to validate/Deserialize the value. [err445]"); return false; } // *** Unable to validate/Deserialize the value else { if(String.IsNullOrEmpty(index)) { return ReplaceAt(0,newItem); } if(index.IndexOf(".")<0) { // Does not contain a ".", so this must be a referencing a "Key" if (_jsonType!="object") { return false; } int i=this.IndexOfKey(index); newItem.Key=index; // Set the key value of the new item. if (i<0) { this.AddToObjBase(index,newItem); } else { this.ReplaceAt(i,newItem); } } else { // First determine parent object iesJSON p; object k=null; p=this.GetParentObj(index,ref k); if (p==null) { return false; } p.ReplaceAt(k+"",newItem); // FUTURE: what do we do if k is numeric? } } return true; }
public bool ReplaceAt(int index, iesJSON newItem, bool OverrideKey=false) { if (ValidateValue()==false) { AddStatusMessage("ERROR: Unable to validate/Deserialize the value. [err443]"); return false; } // *** Unable to validate/Deserialize the value else { if (_jsonType=="object" || _jsonType=="array") { try { ((System.Collections.Generic.List<object>)_value)[index]=newItem; } catch { return false; } } else { if (index==0) { // Replace this item VALUE _value=newItem.Value; _jsonType=newItem.jsonType; if (OverrideKey==true) {_key=newItem.Key;} // USUALLY WE DO NOT CHANGE THE KEY - THIS IS ID WITHIN THE PARENT OBJECT. _value_valid=true; InvalidateJsonString(1); } else { // Index is invalid - must be 0 for a non-array/non-object return false; } } } return true; }
public static iesJSON CreateNull() { iesJSON j=new iesJSON(); j._value=null; j._jsonType="null"; j._value_valid=true; j._jsonString="null"; j._jsonString_valid=true; j._status=0; return j; }
private void DeserializeArray() { iesJSON j2; int pStatus; string c; // *** Create an array of objects. Each can be a value(string,number,boolean,object,array,null) _jsonType="array"; System.Collections.Generic.List<Object> v=new System.Collections.Generic.List<Object>(); endpos=endpos+1; // *** IMPORTANT! Move past [ symbol pStatus=1; do { j2=null; findnext(); // *** Check if we are past the end of the string if (endpos>_jsonString.Length) { StatusErr(-41,"Past end of string before we found the ] symbol as the end of the object @" + endpos + " (e-41)"); _value=v; return; } switch (pStatus) { case 1: // *** This should be a JSON item: object, array, string, boolean, number, or null j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j2.Deserialize(_jsonString,endpos,true); if (j2.Status!=0) { if (j2.Status==-11) { // *** This is actually legitimate. All white space can indicate an empty array. For example [] // *** Here we are lenient and also allow a missing item. // *** For example [, NOTE! In this case, the missing item does NOT count as an element of the array! // *** if you want to skip an item legitimately, use NULL For example [NULL, pStatus=2; } else { StatusErr(-42,"Failed to find item in JSON array @" + endpos + " (e-42) [" + j2.StatusMessage + "]"); } } else { // *** For all cases: object, array, string, number, boolean, null - keep the entire JSON object. j2.Parent=this; v.Add(j2); endpos=j2.endpos; pStatus=2; } j2=null; break; case 2: c=substr(_jsonString,endpos,1); if (c!="," && c!="]") { StatusErr(-43,"Expected , symbol to separate value in JSON array @" + endpos + " (e-43)"); } else { endpos=endpos+1; // *** if we found ] then successful completion of deserializing the object if (c=="]") { _value=v; return; } pStatus=1; } break; } // End Select } while (_status==0); //Loop j2=null; _value=v; }
//DEFAULT-PARAMETERS //public int AddToArrayBase(object oItem) { return AddToArrayBase(oItem, -1); } //public int AddToArrayBase(object oItem, int atPosition) { public int AddToArrayBase(iesJSON oJ, int atPosition=-1) { if (stats!=null) { IncStats("stat_AddToArrayBase"); } int ret=-1; if (_status!=0) { return ret; } if (_jsonType!="array") { return ret; } // *** Requires that this is a json "array" this.InvalidateJsonString(1); try { if ((atPosition<0) || (atPosition>=((System.Collections.Generic.List<Object>)_value).Count)) { ((System.Collections.Generic.List<Object>)_value).Add(oJ); } else { ((System.Collections.Generic.List<Object>)_value).Insert(atPosition,oJ); } ret=0; } catch { } return ret; }
private void DeserializeObject() { iesJSON j2; string Key=""; int pStatus; // *** Look for name:value pairs as a Dictionary object _jsonType="object"; System.Collections.Generic.List<Object> v=new System.Collections.Generic.List<Object>(); endpos=endpos+1; // *** IMPORTANT! Move past { symbol pStatus=1; do { j2=null; findnext(); // *** Check if we are past the end of the string if (endpos>=_jsonString.Length) { StatusErr(-15,"Past end of string before we found the } symbol as the end of the object @" + endpos + " (e-15)"); _value=v; return; } switch (pStatus) { case 1: // *** Get KEY: This MUST be a string with the name of the parameter j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j2.Deserialize(_jsonString,endpos,true); if (j2.Status!=0) { if (j2.Status==-11) { // *** This is actually legitimate. All white space can indicate an empty object. For example {} // *** Here we are lenient and also allow a missing parameter. For example {, pStatus=4; } else { StatusErr(-18,"Failed to find parameter name in parameter:value pair @" + endpos + " (e-18) [" + j2.StatusMessage + "]"); } } else { if (j2.jsonType!="string") { StatusErr(-19,"Parameter name in parameter:value pair must be a quoted string @" + endpos + " (-e19)"); } else { Key=j2.ValueString; endpos=j2.endpos; pStatus=2; } } break; case 2: if (substr(_jsonString,endpos,1)!=":") { StatusErr(-16,"Expected : symbol in parameter:value pair @" + endpos + " (e-16)"); } else { endpos=endpos+1; pStatus=3; } break; case 3: j2=new iesJSON(); j2.UseFlexJson=UseFlexJson; j2.ALLOW_SINGLE_QUOTE_STRINGS=ALLOW_SINGLE_QUOTE_STRINGS; j2.Deserialize(_jsonString,endpos,true); int newendpos=j2.endpos; // Check for blank=null (return status -11 and _jsonType=null) if ((j2.Status==-11) && (j2.jsonType=="null") && (_UseFlexJson==true)) { // Note: j2.status=-11 indicates nothing was found where there should have been a value - for FLEX JSON this is legitimate. j2=CreateItem(null); } if (j2.Status!=0) { StatusErr(-21,"Failed to find value in parameter:value pair. @" + endpos + " (e-21) [" + j2.StatusMessage + "]"); } else { // Note: Above, j2.status=-11 indicates nothing was found where there should have been a value - for FLEX JSON this is legitimate. // *** For all cases: object, array, string, number, boolean, or null j2.Parent=this; j2._key=Key; v.Add(j2); // FUTURE: THIS IS WRONG! WE MUST CHECK TO SEE IF THE KEY ALREADY EXISTS! endpos=newendpos; pStatus=4; } j2=null; break; case 4: string c; c=substr(_jsonString,endpos,1); if (c!="," && c!="}") { StatusErr(-17,"Expected , symbol to separate value pairs @" + endpos + " (e-17)"); } else { endpos=endpos+1; // *** if we found } then successful completion of deserializing the object if (c=="}") { _value=v; return; } pStatus=1; } break; } //End Select } while (_status==0); // Do Loop j2=null; _value=v; }
// ClearStats() - Clear current stats // ContinueToTrackStats=true leaves them ready for new stats, false stops the tracking process public void ClearStats(bool ContinueToTrackStats=true) { stats=null; if ((ContinueToTrackStats) && (NoStatsOrMsgs==false)) { TrackStats=true; } else { TrackStats=false; } if ((_status!=0) || (_value_valid!=true)) { return; } // Cannot iterate through an array/object if it is not valid. if ((this._jsonType=="object") || (this._jsonType=="array")) { foreach(object o in this) { if (NoStatsOrMsgs==false) { ((iesJSON)o).ClearStats(ContinueToTrackStats); } else { ((iesJSON)o).ClearStats(false); ((iesJSON)o).NoStatsOrMsgs=true; } } } }
private void SerializeVoidJSON(iesJSON oJSON, bool BuildValue, bool BuildString) { //Note: _value and _jsonString have already been cleared //Have JSON object serialize itself and give us the string... if (BuildString==true) { _jsonString=oJSON.jsonString; _jsonString_valid=true; // *** This does not indicate valid syntax, only indicates that _jsonString is filled in. } if (BuildValue == true) { if ((oJSON.jsonType!="object") && (oJSON.jsonType!="array")) { // Just need to copy this one node _value=oJSON.Value; _value_valid=true; _jsonType=oJSON.jsonType; } else { // oJSON is either an object or an array System.Collections.Generic.List<Object> newList=new System.Collections.Generic.List<Object>(); foreach(object o in oJSON) { newList.Add(((iesJSON)o).Clone(BuildValue,BuildString)); } _value=newList; _value_valid=true; _jsonType=oJSON.jsonType; } } if (oJSON.Status!=0) { // *** Something we did caused the oJSON object to become invalid this.Clear(false,1); _status=-10; // *** Indicate an invalid JSON result. } }
// Clone "this" iesJSON into a specified iesJSON object. // Make a clone/duplicate of "this" iesJSON (for all sub-items, make a copy of them as well down the entire tree) // NOTE! Clears the destination object first! public bool CloneTo(iesJSON toJSONobj, bool BuildValue=true,bool BuildString=true) { if (stats!=null) { IncStats("stat_CloneTo"); } if (toJSONobj==null) { return false; } try { toJSONobj.Clear(); // Make sure there is nothing in the destination object. toJSONobj.SerializeVoidJSON(this, BuildValue, BuildString); } catch {return false; } return true; }
// *** Get Stats for this object AND ALL CHILD iesJSON OBJECTS public iesJSON GetStatsAll(ref iesJSON addToJSON) { iesJSON j; j=GetStatsBase(addToJSON); //If addToJSON is null, this will create a JSON object if ((_status!=0) || (_value_valid!=true)) { return j; } // Cannot iterate through an array/object if it is not valid. if ((_jsonType=="object") || (_jsonType=="array")) { foreach (object o in ((System.Collections.Generic.List<object>)_value)) { GetStatsAll(ref j); // Adds the stats to j } } return j; }