Example #1
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));
            }
        }
Example #2
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));
            }
        }
Example #3
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);
        }
Example #4
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);
        }