Beispiel #1
0
 protected void Validate(IJsonDict source)
 {
     EnsureValueIsType <IJsonDict>(source, "data");
     EnsureValueIsType <IJsonList>(source, "keys");
     EnsureValueIsType <IJsonList>(source, "values");
     EnsureValueIsType <Boolean>(source, "sensitive", mustExist: false);
 }
Beispiel #2
0
 public void Import(IJsonDict source)
 {
     foreach (JsonKey kvp in source)
     {
         this[kvp.Key] = kvp.Value;
     }
 }
Beispiel #3
0
 public override IEnumerable <IEnumerable> GetContainers(IJsonDict source)
 {
     EnsureValueIsType <IJsonList>(source);
     return(new List <IEnumerable> {
         (IJsonList)source["data"]
     });
 }
Beispiel #4
0
        public override BodyTarget Deserialize(IJsonDict source)
        {
            EnsureValueIsType <int>(source);
            int bodyId = (int)source["data"];

            return(BodyTarget.CreateOrGetExisting(GetBodyById(bodyId), serializer.SharedObjects));
        }
Beispiel #5
0
        public void ResolveReferences(ICollectionHandler handler, IJsonDict item)
        {
            deserializerState            = new DeserializerStateInfo();
            deserializerState.references = new Dictionary <object, IJsonDict>();
            deserializerState.pending    = new Stack <IEnumerable>(handler.GetContainers(item));
            deserializerState.results    = new Dictionary <IJsonDict, object>();

            object referenceId = item.GetValueOrDefault("ref");

            if (referenceId != null)
            {
                deserializerState.references[referenceId] = item;
            }

            IEnumerable enumerable;

            while (deserializerState.pending.Count > 0)
            {
                enumerable = deserializerState.pending.Pop();
                // Debug.Log(string.Format("Processing queued item {0}", idgen.GetId(enumerable, out dummy)));

                var list = enumerable as IJsonList;
                if (list != null)
                {
                    for (int index = 0; index < list.Count; ++index)
                    {
                        if ((item = list[index] as IJsonDict) == null)
                        {
                            continue;                                             // Not an object
                        }
                        if ((item = ResolveItem(item)) == null)
                        {
                            continue;                                      // Replacement not needed
                        }
                        list[index] = item;
                    }
                    continue;
                }
                var dict = enumerable as IJsonDict;
                if (dict != null)
                {
                    foreach (JsonKey kvp in dict)
                    {
                        if ((item = kvp.Value as IJsonDict) == null)
                        {
                            continue;                                           // Not an object
                        }
                        if ((item = ResolveItem(item)) == null)
                        {
                            continue;                                      // Replacement not needed.
                        }
                        dict[kvp.Key] = item;
                    }
                    continue;
                }
                throw new SerializationException(string.Format("Unexpected enumerable of type {0}", enumerable.GetType().FullName));
            }
        }
Beispiel #6
0
 /// <summary>
 /// Returns the object type identifier from the specified JSON Dict.  Raises an exception if no type identifier is specified.
 /// </summary>
 /// <param name="input"></param>
 protected object GetTypeIdentifier(IJsonDict input)
 {
     try
     {
         return(input["type"]);
     } catch (KeyNotFoundException) {
         throw new SerializationException("Object type not declared.");
     }
 }
Beispiel #7
0
        public override TCollection Deserialize(IJsonDict source)
        {
            EnsureValueIsType <IJsonList>(source);
            TCollection result = (TCollection)Factory.Invoke(new object[0]);

            serializer.deserializerState.results[source] = result;

            AddItems(
                result,
                ((IJsonList)source["data"]).Cast <object>().Select(element => (TItem)(serializer.Deserialize(element)))
                );
            return(result);
        }
Beispiel #8
0
        public object Deserialize(object input)
        {
            if (input == null)
            {
                throw new SerializationException("Encountered NULL while deserializing input.");
            }
            // Primitives.
            input = Structure.FromPrimitive(input);
            if (input is Structure)
            {
                return((Structure)input);
            }
            IJsonDict dict = input as IJsonDict;

            if (dict == null)
            {
                throw new SerializationException("Deserializing from a " + input.GetType().Name + " is unsupported.");
            }
            // Get the deserializer for this object.
            // This will fail and throw an exception(by design) on unsupported types.
            // "ref" is also considered an unsupported type.  If we see it here, it's either the top-level element
            // (in which case there are no other elements it could possibly be referencing), or we somehow failed
            // to replace it during the reference replacement run.
            TypeHandler        handler = registry.GetDeserializer(GetTypeIdentifier(dict)).CreateHandler(this);
            ICollectionHandler ich     = handler as ICollectionHandler;
            object             result;

            if (ich != null)
            {
                // If we have a collection handler and haven't scanned for backrefs yet, scan for them.
                if (deserializerState == null)
                {
                    ResolveReferences(ich, dict);
                }
                // Is this something we've already resolved?  If so, return that reference.
                result = deserializerState.results.GetValueOrDefault(dict);
                if (result != null)
                {
                    return(result);
                }
            }
            result = handler.ProxyDeserialize(dict);
            if (ich != null)
            {
                deserializerState.results[dict] = result;
            }
            return(result);
        }
Beispiel #9
0
        public override IEnumerable <IEnumerable> GetContainers(IJsonDict source)
        {
            this.Validate(source);
            var result = new List <IEnumerable>(3);

            if (source.ContainsKey("data"))
            {
                result.Add((IJsonDict)source["data"]);
            }
            if (source.ContainsKey("keys"))
            {
                result.Add((IJsonList)source["keys"]);
            }
            if (source.ContainsKey("values"))
            {
                result.Add((IJsonList)source["values"]);
            }
            return(result);
        }
Beispiel #10
0
        public override VesselTarget Deserialize(IJsonDict source)
        {
            EnsureValueIsType <string>(source);
            Guid vesselId;

            try
            {
                vesselId = new Guid((string)source["data"]);
            }
            catch (Exception ex)
            {
                throw new SerializationException("Provided vessel GUID is invalid.", ex);
            }
            Vessel vessel = GetVesselById(vesselId);

            if (vessel == null)
            {
                return(null);                 // kOS won't really like this, but meh.
            }
            return(VesselTarget.CreateOrGetExisting(vessel, serializer.SharedObjects));
        }
Beispiel #11
0
        protected List <double> GetElements(IJsonDict source, int numElements = 0)
        {
            EnsureValueIsType <IJsonList>(source);
            IJsonList value = (IJsonList)source["data"];

            if (numElements != 0 && value.Count != numElements)
            {
                throw new SerializationException(
                          string.Format(
                              "{0} object: Expected data field to contain {1} elements, but it contained {2} instead.",
                              this.info.Name, numElements, value.Count
                              )
                          );
            }
            try
            {
                return(value.Cast <double>().ToList());
            } catch (InvalidCastException) {
                throw new SerializationException(string.Format("{0} object: All elements of data must be numeric values.", info.Name));
            }
        }
Beispiel #12
0
        public override Direction Deserialize(IJsonDict source)
        {
            EnsureValueIsType <string>(source, "from", false, true);
            string directionType = (string)source.GetValueOrDefault("from", null);
            int    numElements   = 0;

            switch (directionType)
            {
            case null:
                break;

            case "quaternion":
                numElements = 4;
                break;

            case "euler":
            case "vector":
                numElements = 3;
                break;

            default:
                throw new SerializationException(string.Format("{0} object: 'from' must be one of (\"quaternioun\", \"euler\", \"vector\", or null).", info.Name));
            }
            var elements = GetElements(source, numElements);

            switch (elements.Count)
            {
            case 3:     // From Euler angles (default) or vector (explicit)
                return(new Direction(new Vector3d(elements[0], elements[1], elements[2]), directionType != "vector"));

            case 4:     // Quaternion
                return(new Direction(new QuaternionD(elements[0], elements[1], elements[2], elements[3])));

            default:
                throw new SerializationException(string.Format("{0} object: data field must contain exactly 3 or 4 elements.", info.Name));
            }
        }
Beispiel #13
0
        public override Lexicon Deserialize(IJsonDict source)
        {
            Validate(source);
            bool caseSensitive = (bool)source.GetValueOrDefault("sensitive", false);
            var  data          = (IJsonDict)source["data"];
            var  keys          = (IJsonList)source["keys"];
            var  values        = (IJsonList)source["values"];

            if (keys.Count != values.Count)
            {
                throw new SerializationException("Dict must have the same number of values as it has keys.");
            }
            var output = new Lexicon();

            output.SetSuffix("CASESENSITIVE", caseSensitive);
            serializer.deserializerState.results[source] = output;
            data.Select(kvp => output[(Structure)serializer.Deserialize(kvp.Key)] = (Structure)serializer.Deserialize(kvp.Value));

            foreach (var kvp in data.Select(x => new KeyValuePair <Structure, Structure>((Structure)serializer.Deserialize(x.Key), (Structure)serializer.Deserialize(x.Value))))
            {
                output[kvp.Key] = kvp.Value;
            }
            return(output);
        }
Beispiel #14
0
        public override Vector Deserialize(IJsonDict source)
        {
            var elements = GetElements(source, 3);

            return(new Vector(elements[0], elements[1], elements[2]));
        }
Beispiel #15
0
 public abstract IEnumerable <IEnumerable> GetContainers(IJsonDict source);
Beispiel #16
0
        /// <summary>
        /// Helper function for resolving references.  Updates the passed list of references.  Returns a non-null value if the parent container should replace
        /// its current item with the returned item.
        /// </summary>
        /// <param name="references"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        internal IJsonDict ResolveItem(IJsonDict item)
        {
            object typeId   = GetTypeIdentifier(item);
            object objectId = item.GetValueOrDefault("ref");
            // Debug.Log(string.Format("Identified object of type {0} -- object ID: {1}", typeId, objectId));
            IJsonDict referenced = (objectId == null) ? null : deserializerState.references.GetValueOrDefault(objectId);

            if (typeId as string == "ref")   // Found a reference
            {
                if (objectId == null)
                {
                    throw new SerializationException("Found a missing or null reference ID.");
                }
                // This works because we don't want to replace if the item didn't exist (and thus would return NULL),
                // and we do want to replace if it did (and thus would return an actual value)
                if (referenced == null)
                {
                    // Debug.Log(string.Format("Adding new pending reference to {0}", objectId));
                    deserializerState.references[objectId] = item;
                }
                else
                {
                    // Debug.Log(string.Format("Replacing reference with actual object of type ", referenced["type"]));
                }
                return(referenced);
            }
            // Still here?  Okay.
            // Nested container check.
            TypeHandler handler = registry.GetDeserializer(typeId).CreateHandler(this);

            if (handler is ICollectionHandler)
            {
                // FIXME: See if this code is actually needed.
                if (item.ContainsKey("_visited"))
                {
                    Debug.LogWarning("*** WARNING ***: Container already visited.");
                }
                else
                {
                    item["_visited"] = true;
                    foreach (var container in ((ICollectionHandler)handler).GetContainers(item))
                    {
                        deserializerState.pending.Push(container);
                    }
                }
            }

            if (objectId == null)
            {
                return(null);                  // Unreferenced object, nothing to do.
            }
            if (referenced == null)
            {
                deserializerState.references[objectId] = item;
                // Debug.Log("Saving reference.");
            }
            else
            {
                // Already references something else.  Let's hope it's a reference.
                if (GetTypeIdentifier(referenced) as string != "ref")
                {
                    // ... nope.  Complain loudly.
                    throw new SerializationException(string.Format("Object reference '{0}' refers to multiple non-reference objects", objectId));
                }
                // Everything we've previously seen up until now points to the old object.  It's way too much of a hassle to replace it, so...
                // instead we clear it and copy all of our data to it.
                // Debug.Log(string.Format("Copying over to actual object of type ", referenced["type"]));
                referenced.Clear();
                foreach (JsonKey kvp in item)
                {
                    referenced[kvp.Key] = kvp.Value;    // Resistance is futile.  You will be assimilated.
                }
                // Debug.Log("Done copying over");
            }
            return(referenced);
        }
Beispiel #17
0
 public object ProxyDeserialize(IJsonDict source)
 {
     return(DeserializeMethod.Invoke(this, new object[] { source }));
 }