/// <summary> /// Create a deep copy of this instance. /// </summary> public IJSONValue DeepCopy() { IJSONValue copy = CreatePrototype(); copy.CopyValue(this); return(copy); }
/// <summary> /// Copy the value of another IJSONValue into our underlying value. /// </summary> /// <param name="value"></param> /// <returns></returns> public override void CopyValue(IJSONValue value) { if (!GetType().IsAssignableFrom(value.GetType())) { throw new Exception("Can't assign a " + value.GetType().Name + " to a " + GetType().Name); } }
/// <summary> /// Read a JSON value. /// </summary> /// <param name="path">JSON path to the value we're reading</param> /// <param name="pbr">a pushback reader</param> /// <returns>the next JSON value</returns> /// <exception cref="System.IO.IOException" /> /// <exception cref="Gavaghan.JSON.JSONException" /> public IJSONValue Read(string path, PushbackReader pbr) { IJSONValue value; char c = Demand(pbr); // is it a string? if (c == '\"') { value = OnString(path, pbr); } // is it a number? else if (Char.IsDigit(c) || (c == '-')) { value = OnNumber(path, pbr); } // is it an array? else if (c == '[') { value = OnArray(path, pbr); } // is it an object? else if (c == '{') { value = OnObject(path, pbr); } // is it a boolean? else if ((c == 't') || (c == 'f')) { value = OnBoolean(path, pbr); } // is it a null? else if (c == 'n') { value = OnNull(path, pbr); } // else, value type else { value = OnUnknown(path, pbr, c); } // unread trigger character pbr.Unread(c); // implementation specific read value.Read(path, pbr); // give subtype a chance to select a different implementation IJSONValue recast = Recast(path, value); // if value was recast, copy over original data if (recast != null) { recast.CopyValue(value); value = recast; } return(value); }
static public object GetNotNull(IJSONValue json) { if (json == null) { throw new BadTrafficException("'null' not allowed"); } return(json.Value); }
/// <summary> /// Render a JSONValue as a string. /// </summary> /// <param name="value">the IJSONValue to render</param> /// <param name="pretty">'true' to pretty-print with line feeds and indentation, 'false' /// to render on a single line.</param> /// <returns>the rendered value</returns> static public string ToString(IJSONValue value, bool pretty) { string str; using (StringWriter writer = new StringWriter()) { value.Write("", writer, pretty); str = writer.ToString(); } return(str); }
/// <summary> /// Read a JSON value (presumes the key has already been read) and set the /// underlying value. There's generally no reason to call this method /// directly. It is intended to be overridden by an extended type. /// </summary> /// <param name="path">path to the value being read</param> /// <param name="pbr">source reader</param> /// <exception cref="Gavaghan.JSON.JSONException">on grammar error</exception> /// <exception cref="System.IO.IOException">on read failure</exception> public override void Read(string path, PushbackReader pbr) { char c = JSONValueFactory.Demand(pbr); if (c != '[') { throw new JSONException(path, "Content does not appear to be an array."); } // empty array is an easy out mFactory.SkipWhitespace(pbr); c = JSONValueFactory.Demand(pbr); if (c == ']') { return; } pbr.Unread(c); // loop through values try { for (; ;) { IJSONValue value = mFactory.Read(path, pbr); mValue.Add(value); // get next non-whitespace mFactory.SkipWhitespace(pbr); c = JSONValueFactory.Demand(pbr); // is end? if (c == ']') { return; } // is more if (c == ',') { mFactory.SkipWhitespace(pbr); continue; } throw new JSONException(path, "Incorrectly formatted array: " + c); } } finally { mFactory = null; } }
/// <summary> /// Get a named value from a <code>JSONObject</code>. If the value /// doesn't exist, make a default instance and add it. /// </summary> /// <param name="jsonObj">the <code>JSONObject</code> to get a value from</param> /// <param name="name"></param> /// <param name="jsonType"></param> /// <returns></returns> static public object GetOrSet(JSONObject jsonObj, String name, Type jsonType) { object retval; // look to see if the value already exists jsonObj.TryGetValue(name, out IJSONValue jsonValue); // if it exists, it's easy - just return it after a type check if (jsonValue != null) { // make sure we got the right object type if (!jsonType.IsAssignableFrom(jsonValue.GetType())) { throw new Exception(String.Format("Value named '{0}' is of type '{1}' which is not assignable from '{2}'", name, jsonValue.GetType().Name, jsonType.Name)); } retval = jsonValue.Value; } // otherwise, create a default else { // ensure property types if (!typeof(IJSONValue).IsAssignableFrom(jsonType)) { throw new Exception(String.Format("Type '{0}' is not assignable from '{1}'", typeof(IJSONValue).Name, jsonType.Name)); } try { ConstructorInfo ctx = jsonType.GetConstructor(NO_PARAMS); if (ctx == null) { throw new Exception("'" + jsonType.Name + "' does not have a public default constructor"); } IJSONValue newJSON = (IJSONValue)ctx.Invoke(NO_ARGS); jsonObj.Add(name, newJSON); retval = newJSON.Value; } catch (TargetInvocationException exc) { throw new Exception("Constructor for '" + jsonType.Name + "' threw an exception", exc.InnerException); } } return(retval); }
/// <summary> /// Copy the value of another IJSONValue into our underlying value. /// </summary> /// <param name="value"></param> /// <returns></returns> public override void CopyValue(IJSONValue value) { if (!GetType().IsAssignableFrom(value.GetType())) { throw new Exception("Can't assign a " + value.GetType().Name + " to a " + GetType().Name); } IList <IJSONValue> source = (IList <IJSONValue>)value.Value; mValue = new List <IJSONValue>(); foreach (IJSONValue json in source) { mValue.Add(json.DeepCopy()); } }
static public string ToString(IJSONValue json) { if (json == null) { return(""); } object value = json.Value; string retval = ""; if (value != null) { retval = value.ToString(); } return(retval); }
/// <summary> /// Maps a IJSONValue onto an object which can be cast as an appropriate type /// </summary> /// <param name="T">The type to which the returned object will be cast</param> /// <param name="toMap">The IJSONValue to map onto the object</param> /// <returns>An object of type T containing the JSON information</returns> public static object MapValue(Type T, IJSONValue toMap) { if (toMap is JSONObject) { return(MapObject(T, (JSONObject)toMap)); } else if (toMap is JSONArray) { return(MapArray(T, (JSONArray)toMap)); } else if (toMap is JSONLiteral) { return(MapLiteral(T, (JSONLiteral)toMap)); } else { throw new ArgumentException("Cannot map vanilla IJSONValue."); } }
/// <summary> /// Give subtypes a chance to recast the loaded value as an <code>IJSONValue</code> /// subtype. Default implementation returns 'null' because no recast is needed. /// /// Subtypes only need to return a default instance. The <code>read()</code> /// method handles copying of data. /// </summary> /// <param name="path">JSON path to the value we're reading</param> /// <param name="value"></param> /// <returns></returns> /// <exception cref="Gavaghan.JSON.JSONException" /> protected virtual IJSONValue Recast(string path, IJSONValue value) => null;
/// <summary> /// Serialize a IJSONValue into JSON /// </summary> /// <param name="toWrite">The IJSONValue to be serialized</param> /// <returns>A string containing the serialized JSON</returns> public static string Write(IJSONValue toWrite) { return(toWrite.ToJSON()); }
/// <summary> /// Maps a IJSONValue object onto another object /// </summary> /// <typeparam name="T">The type of object to map the IJSONValue onto</typeparam> /// <param name="toMap">The IJSONValue to map onto the object</param> /// <returns>An instance of the object containing the JSON information</returns> public static T Map <T>(IJSONValue toMap) { return((T)JSONMap.MapValue(typeof(T), toMap)); }
/// <summary> /// Look for the 'type' value in a populated <code>JSONObject</code> and create a /// default instance of it. If 'value' is not a <code>JSONObject</code> or if /// 'type' value is not found, defer to the super class. /// </summary> /// <param name="path">JSON path to the value we're reading</param> /// <param name="value">the value to possibly recast</param> /// <returns>the recast value or 'null' if no recast was required</returns> /// <exception cref="Gavaghan.JSON.JSONException" /> protected override IJSONValue Recast(string path, IJSONValue value) { TypedJSONObject retval; // if it's not a JSONObject, we have nothing to do if (!(value is JSONObject)) { return(base.Recast(path, value)); } // look for a type value JSONObject valueObj = (JSONObject)value; valueObj.TryGetValue(TypedJSONObject.TYPE_KEY, out IJSONValue typeValue); // if no type found, defer to superclass if (typeValue == null) { return(base.Recast(path, value)); } // ensure typeValue is a string if (!(typeValue is JSONString)) { throw new JSONException(path, String.Format("'type' value is a '{0}' but a JSONString was expected", typeValue.GetType().Name)); } // load the new type String typeName = ((JSONString)typeValue).StringValue; Type type = Type.GetType(typeName); if (type == null) { throw new JSONException(path, String.Format("Read a JSON object with type attribute '{0}' but that class could not be found", typeName)); } // ensure the class is an appropriate subtype if (!typeof(TypedJSONObject).IsAssignableFrom(type)) { throw new JSONException(path, String.Format("Read an object of type '{0}' but that class is not assignable to 'TypedJSONObject'", typeName)); } // instantiate a default instance try { ConstructorInfo ctx = type.GetConstructor(NO_PARAMS); if (ctx == null) { throw new Exception("'" + type.Name + "' does not have a public default constructor"); } IJSONValue newJSON = (IJSONValue)ctx.Invoke(NO_ARGS); retval = (TypedJSONObject)newJSON; } catch (TargetInvocationException exc) { throw new Exception("Constructor for '" + type.Name + "' threw an exception", exc.InnerException); } return(retval); }
/// <summary> /// Copy the value of another IJSONValue into our underlying value. /// </summary> /// <param name="value"></param> /// <returns></returns> public abstract void CopyValue(IJSONValue value);
public void CopyValue(IJSONValue value) { throw new NotImplementedException(); }