/// <summary>
        /// Create a deep copy of this instance.
        /// </summary>
        public IJSONValue DeepCopy()
        {
            IJSONValue copy = CreatePrototype();

            copy.CopyValue(this);
            return(copy);
        }
示例#2
0
 /// <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);
        }
示例#4
0
 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);
        }
示例#6
0
        /// <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);
        }
示例#8
0
        /// <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());
            }
        }
示例#9
0
        static public string ToString(IJSONValue json)
        {
            if (json == null)
            {
                return("");
            }

            object value = json.Value;

            string retval = "";

            if (value != null)
            {
                retval = value.ToString();
            }

            return(retval);
        }
示例#10
0
 /// <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.");
     }
 }
示例#11
0
 /// <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;
示例#12
0
 /// <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());
 }
示例#13
0
 /// <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));
 }
示例#14
0
        /// <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);
        }
示例#15
0
 /// <summary>
 /// Copy the value of another IJSONValue into our underlying value.
 /// </summary>
 /// <param name="value"></param>
 /// <returns></returns>
 public abstract void CopyValue(IJSONValue value);
示例#16
0
 public void CopyValue(IJSONValue value)
 {
     throw new NotImplementedException();
 }