A document object model which can describe a serialised object.
예제 #1
0
파일: Serialise.cs 프로젝트: sachgits/Myre
        private static Node CreateNode(Dom dom, object value)
        {
            if (value == null)
            {
                return(null);
            }

            if (value is ICustomSerialisable)
            {
                return((value as ICustomSerialisable).Serialise());
            }

            var type = value.GetType();

            if (IsParsable(type))
            {
                return(CreateLiteral(value));
            }

            if (value is IList)
            {
                return(CreateList(value as IList, type, dom));
            }

            if (value is IDictionary)
            {
                return(CreateDictionary(value as IDictionary, type, dom));
            }

            return(CreateObject(value, type, dom));
        }
예제 #2
0
파일: Serialise.cs 프로젝트: sachgits/Myre
        private static NodeReference SerialiseObject(Dom dom, object item)
        {
            if (item == null)
            {
                return(new NodeReference(dom, null));
            }

            Node node;

            if (item.GetType().IsValueType)
            {
                node = Dom.CreateNode(dom, item);
                return(new NodeReference(dom, node));
            }
            else
            {
                if (dom.referenceTypeNodes.TryGetValue(item, out node))
                {
                    if (node.SharedReferenceID == null)
                    {
                        node.SharedReferenceID = dom.sharedReferences.Count;
                        dom.sharedReferences.Add(node.SharedReferenceID.Value, node);
                    }

                    return(new NodeReference(dom, node));
                }
                else
                {
                    node = Dom.CreateNode(dom, item);
                    dom.referenceTypeNodes[item] = node;
                    return(new NodeReference(dom, node));
                }
            }
        }
예제 #3
0
            public override object Deserialise(Dom dom, IKernel kernel, Type expectedType)
            {
                var type     = Type ?? expectedType;
                var instance = CreateInstance(type, kernel);

                foreach (var item in Children)
                {
                    if (item.Value.GetNode() == null)
                    {
                        continue;
                    }

                    var field = FindField(type, item.Key);

                    if (!field.IsValid)
                    {
                        continue;
                    }

                    var value = DeserialiseNode(dom, item.Value.GetNode(), kernel, field.Type);
                    field.Set(instance, value);
                }

                return(instance);
            }
예제 #4
0
            public override void Write(Stream stream, int indent)
            {
                // write type name
                base.Write(stream, indent);

                // start list
                Dom.Write(stream, "[");
                Dom.NewLine(stream, indent + 1);

                // write children
                for (int i = 0; i < Children.Count; i++)
                {
                    var item = Children[i];
                    item.Write(stream, indent + 1);

                    if (i < Children.Count - 1)
                    {
                        // comma separated
                        Dom.Write(stream, ",");
                        Dom.NewLine(stream, indent + 1);
                    }
                    else
                    {
                        Dom.NewLine(stream, indent);
                    }
                }

                // end list
                Dom.Write(stream, "]");
            }
예제 #5
0
            public override object Deserialise(Dom dom, IKernel kernel, Type expectedType)
            {
                var type = Type ?? expectedType;

                if (type.IsArray)
                {
                    var instance = Array.CreateInstance(type.GetElementType(), Children.Count);

                    for (int i = 0; i < Children.Count; i++)
                    {
                        var child = Children[i].GetNode().Deserialise(dom, kernel, type.GetElementType());
                        instance.SetValue(child, i);
                    }

                    return(instance);
                }
                else
                {
                    var instance = CreateInstance(type, kernel);

                    IList list = instance as IList;
                    foreach (var item in Children)
                    {
                        var child = DeserialiseNode(dom, item.GetNode(), kernel, typeof(object));
                        list.Add(child);
                    }

                    return(list);
                }
            }
예제 #6
0
파일: Load.cs 프로젝트: sachgits/Myre
        private static void ParseSharedReferences(StreamReader reader, Dom dom)
        {
            if (reader.Peek() != 'R')
            {
                return;
            }

            // skip over R[
            reader.Read();
            reader.Read();

            SkipWhitespace(reader);

            while ((char)reader.Peek() != ']')
            {
                // read first element
                var key = ParseIdentifier(reader);
                var id  = int.Parse(key);

                //skip over separator :
                var separator = (char)reader.Read();

                // read node
                var value = ParseItem(reader, dom);

                dom.sharedReferences.Add(id, value.GetNode());
                SkipWhitespace(reader);
            }

            // skip over ]
            reader.Read();
        }
예제 #7
0
 private static void NewLine(Stream stream, int indent)
 {
     Dom.Write(stream, "\n");
     for (int i = 0; i < indent; i++)
     {
         Dom.Write(stream, "  ");
     }
 }
예제 #8
0
            public virtual void Write(Stream stream, int indent)
            {
                // write type name
                string name = GetTypeName(Type);

                Dom.Write(stream, name);
                Dom.Write(stream, " ");
            }
예제 #9
0
파일: Serialise.cs 프로젝트: sachgits/Myre
        public static Dom Serialise(object value, IKernel kernel)
        {
            var dom = new Dom(kernel);

            dom.Root = SerialiseObject(dom, value);
            dom.referenceTypeNodes.Clear();
            return(dom);
        }
예제 #10
0
            public override object Deserialise(Dom dom, IKernel kernel, Type expectedType)
            {
                if (Type == typeof(string))
                {
                    return(Value);
                }

                FindParseMethod();
                return(parseMethod.Invoke(null, new object[] { Value.Unescape() }));
            }
예제 #11
0
파일: Load.cs 프로젝트: sachgits/Myre
 public static Dom Load(Stream stream, IKernel kernel)
 {
     using (var reader = new StreamReader(stream, Encoding.Unicode))
     {
         var dom = new Dom(kernel);
         ParseSharedReferences(reader, dom);
         dom.Root = ParseItem(reader, dom);
         return(dom);
     }
 }
예제 #12
0
파일: Load.cs 프로젝트: TomGillen/Myre
 public static Dom Load(Stream stream, IKernel kernel)
 {
     using (var reader = new StreamReader(stream, Encoding.Unicode))
     {
         var dom = new Dom(kernel);
         ParseSharedReferences(reader, dom);
         dom.Root = ParseItem(reader, dom);
         return dom;
     }
 }
예제 #13
0
파일: Load.cs 프로젝트: sachgits/Myre
        private static Node ParseCollection(StreamReader reader, Type type, Dom dom)
        {
            List <CollectionNode> nodes = new List <CollectionNode>();

            // skip over [
            reader.Read();
            SkipWhitespace(reader);

            // read children
            bool isDictionary = false;

            while ((char)reader.Peek() != ']')
            {
                var node = new CollectionNode();

                // read first element
                node.First = ParseItem(reader, dom);

                var seperator = (char)reader.Peek();
                if (seperator == ':')
                {
                    // found dictionary key/value separator
                    reader.Read();

                    // read value
                    node.Second  = ParseItem(reader, dom);
                    isDictionary = true;
                }

                // skip over ,
                if ((char)reader.Peek() == ',')
                {
                    reader.Read();
                }

                nodes.Add(node);
                SkipWhitespace(reader);
            }

            // skip over ]
            reader.Read();

            if (isDictionary)
            {
                return(CreateDictionary(type, nodes));
            }
            else
            {
                return(CreateList(type, nodes));
            }
        }
예제 #14
0
 private static object CreateInstance(Dom dom, Node node, IKernel kernel, Type expectedType)
 {
     if (typeof(ICustomSerialisable).IsAssignableFrom(node.Type))
     {
         var type     = node.Type ?? expectedType;
         var instance = CreateInstance(type, kernel) as ICustomSerialisable;
         instance.Deserialise(node);
         return(instance);
     }
     else
     {
         return(node.Deserialise(dom, kernel, expectedType));
     }
 }
예제 #15
0
파일: Serialise.cs 프로젝트: sachgits/Myre
        private static Node CreateList(IList list, Type type, Dom dom)
        {
            var node = new ListNode();

            node.Type     = type;
            node.Children = new List <NodeReference>();

            foreach (var item in list)
            {
                var serialisedItem = SerialiseObject(dom, item);
                node.Children.Add(serialisedItem);
            }

            return(node);
        }
예제 #16
0
파일: Dom.cs 프로젝트: sachgits/Myre
            public void Write(Stream stream, int indent)
            {
                if (id == null && node != null && node.SharedReferenceID != null)
                {
                    id = node.SharedReferenceID;
                }

                if (id != null)
                {
                    Dom.Write(stream, string.Format("#{0}", id.Value));
                }
                else
                {
                    GetNode().Write(stream, indent);
                }
            }
예제 #17
0
            public override object Deserialise(Dom dom, IKernel kernel, Type expectedType)
            {
                var type     = Type ?? expectedType;
                var instance = CreateInstance(type, kernel);

                IDictionary dictionary = instance as IDictionary;

                foreach (var item in Children)
                {
                    var key   = DeserialiseNode(dom, item.Key.GetNode(), kernel, typeof(object));
                    var value = DeserialiseNode(dom, item.Value.GetNode(), kernel, typeof(object));
                    dictionary.Add(key, value);
                }

                return(dictionary);
            }
예제 #18
0
파일: Serialise.cs 프로젝트: sachgits/Myre
        private static Node CreateDictionary(IDictionary dictionary, Type type, Dom dom)
        {
            var node = new DictionaryNode();

            node.Type     = type;
            node.Children = new Dictionary <NodeReference, NodeReference>();

            foreach (DictionaryEntry item in dictionary)
            {
                var serialisedKey   = SerialiseObject(dom, item.Key);
                var serialisedValue = SerialiseObject(dom, item.Value);
                node.Children.Add(serialisedKey, serialisedValue);
            }

            return(node);
        }
예제 #19
0
        private static object DeserialiseNode(Dom dom, Node node, IKernel kernel, Type expectedType)
        {
            if (node.SharedReferenceID == null)
            {
                return(CreateInstance(dom, node, kernel, expectedType));
            }

            var    id = node.SharedReferenceID.Value;
            object value;

            if (!dom.sharedInstances.TryGetValue(id, out value))
            {
                value = CreateInstance(dom, node, kernel, expectedType);
                dom.sharedInstances[id] = value;
            }

            return(value);
        }
예제 #20
0
파일: Load.cs 프로젝트: sachgits/Myre
        private static Node ParseNode(StreamReader reader, Type type, Dom dom)
        {
            SkipWhitespace(reader);

            switch (reader.Peek())
            {
            case '"':
                return(ParseLiteral(reader, type));

            case '{':
                return(ParseObject(reader, type, dom));

            case '[':
                return(ParseCollection(reader, type, dom));

            default:
                return(null);
            }
        }
예제 #21
0
            public override void Write(Stream stream, int indent)
            {
                // write type name
                base.Write(stream, indent);

                // start dictionary
                Dom.Write(stream, "[");
                Dom.NewLine(stream, indent + 1);

                // write children
                foreach (var item in Children.Select((kvp, i) => new { Key = kvp.Key, Value = kvp.Value, index = i }))
                {
                    // write key:
                    item.Key.Write(stream, indent + 1);
                    Dom.Write(stream, ": ");

                    // write value
                    if (item.Value.GetNode() == null)
                    {
                        Dom.Write(stream, "null");
                    }
                    else
                    {
                        item.Value.Write(stream, indent + 1);
                    }

                    if (item.index < Children.Count - 1)
                    {
                        // comma separated
                        Dom.Write(stream, ",");
                        Dom.NewLine(stream, indent + 1);
                    }
                    else
                    {
                        Dom.NewLine(stream, indent);
                    }
                }

                // end dictionary
                Dom.Write(stream, "]");
            }
예제 #22
0
            public override void Write(Stream stream, int indent)
            {
                // write type name
                base.Write(stream, indent);

                // start object
                Dom.Write(stream, "{");
                Dom.NewLine(stream, indent + 1);

                // write fields
                foreach (var item in Children.Select((kvp, i) => new { Key = kvp.Key, Value = kvp.Value, index = i }))
                {
                    // write field name:
                    Dom.Write(stream, item.Key);
                    Dom.Write(stream, ": ");

                    // write value
                    if (item.Value.GetNode() == null)
                    {
                        Dom.Write(stream, "null");
                    }
                    else
                    {
                        item.Value.Write(stream, indent + 1);
                    }

                    if (item.index < Children.Count - 1)
                    {
                        // comma separate
                        Dom.Write(stream, ",");
                        Dom.NewLine(stream, indent + 1);
                    }
                    else
                    {
                        Dom.NewLine(stream, indent);
                    }
                }

                // end object
                Dom.Write(stream, "}");
            }
예제 #23
0
파일: Load.cs 프로젝트: sachgits/Myre
        private static NodeReference ParseItem(StreamReader reader, Dom dom)
        {
            SkipWhitespace(reader);

            var type = ParseTypeName(reader);

            SkipWhitespace(reader);

            if (reader.Peek() == '#')
            {
                reader.Read();
                var value = ParseIdentifier(reader);
                var id    = int.Parse(value);
                return(new NodeReference(dom, id));
            }
            else
            {
                var node = ParseNode(reader, type, dom);
                return(new NodeReference(dom, node));
            }
        }
예제 #24
0
파일: Load.cs 프로젝트: sachgits/Myre
        private static Node ParseObject(StreamReader reader, Type type, Dom dom)
        {
            var children = new Dictionary <string, NodeReference>();

            // skip over {
            reader.Read();
            SkipWhitespace(reader);

            // read members
            while ((char)reader.Peek() != '}')
            {
                // read member name
                var ident = ParseIdentifier(reader);

                // skip over :
                reader.Read();

                // read value
                var value = ParseItem(reader, dom);
                SkipWhitespace(reader);

                // skip over ,
                if ((char)reader.Peek() == ',')
                {
                    reader.Read();
                }

                children.Add(ident, value);
                SkipWhitespace(reader);
            }

            // skip over }
            reader.Read();

            // create object node
            return(new ObjectNode()
            {
                Type = type, Children = children
            });
        }
예제 #25
0
        private void WriteSharedReferences(Stream stream)
        {
            if (sharedReferences.Count == 0)
            {
                return;
            }

            // start dictionary
            Dom.Write(stream, "R[");
            Dom.NewLine(stream, 1);

            // write children
            foreach (var item in sharedReferences.Select((kvp, i) => new { Key = kvp.Key, Value = kvp.Value, index = i }))
            {
                // write key:
                Dom.Write(stream, item.Key.ToString());
                Dom.Write(stream, ": ");

                // write value
                item.Value.Write(stream, 1);

                if (item.index < sharedReferences.Count - 1)
                {
                    // comma separated
                    Dom.Write(stream, ",");
                    Dom.NewLine(stream, 1);
                }
                else
                {
                    Dom.NewLine(stream, 0);
                }
            }

            // end dictionary
            Dom.Write(stream, "]");
            Dom.NewLine(stream, 0);
        }
예제 #26
0
파일: Serialise.cs 프로젝트: sachgits/Myre
        private static Node CreateObject(object value, Type type, Dom dom)
        {
            var fap  = GetFieldsAndProperties(type);
            var node = new ObjectNode();

            node.Type     = type;
            node.Children = new Dictionary <string, NodeReference>();

            foreach (var field in fap.Fields)
            {
                var fieldValue      = field.GetValue(value);
                var serialisedValue = SerialiseObject(dom, fieldValue);
                node.Children.Add(field.Name, serialisedValue);
            }

            foreach (var property in fap.Properties)
            {
                var fieldValue      = property.GetValue(value, null);
                var serialisedValue = SerialiseObject(dom, fieldValue);
                node.Children.Add(property.Name, serialisedValue);
            }

            return(node);
        }
예제 #27
0
파일: Dom.cs 프로젝트: Quantumplation/Myre
 public NodeReference(Dom dom, Node node)
 {
     this.dom = dom;
     this.node = node;
     this.id = null;
 }
예제 #28
0
파일: Load.cs 프로젝트: TomGillen/Myre
        private static void ParseSharedReferences(StreamReader reader, Dom dom)
        {
            if (reader.Peek() != 'R')
                return;

            // skip over R[
            reader.Read();
            reader.Read();

            SkipWhitespace(reader);

            while ((char)reader.Peek() != ']')
            {
                // read first element
                var key = ParseIdentifier(reader);
                var id = int.Parse(key);

                //skip over separator :
                var separator = (char)reader.Read();

                // read node
                var value = ParseItem(reader, dom);

                dom.sharedReferences.Add(id, value.GetNode());
                SkipWhitespace(reader);
            }

            // skip over ]
            reader.Read();
        }
예제 #29
0
파일: Load.cs 프로젝트: TomGillen/Myre
        private static Node ParseObject(StreamReader reader, Type type, Dom dom)
        {
            var children = new Dictionary<string, NodeReference>();

            // skip over {
            reader.Read();
            SkipWhitespace(reader);

            // read members
            while ((char)reader.Peek() != '}')
            {
                // read member name
                var ident = ParseIdentifier(reader);

                // skip over :
                reader.Read();

                // read value
                var value = ParseItem(reader, dom);
                SkipWhitespace(reader);

                // skip over ,
                if ((char)reader.Peek() == ',')
                    reader.Read();

                children.Add(ident, value);
                SkipWhitespace(reader);
            }

            // skip over }
            reader.Read();

            // create object node
            return new ObjectNode() { Type = type, Children = children };
        }
예제 #30
0
파일: Load.cs 프로젝트: TomGillen/Myre
        private static Node ParseNode(StreamReader reader, Type type, Dom dom)
        {
            SkipWhitespace(reader);

            switch (reader.Peek())
            {
                case '"':
                    return ParseLiteral(reader, type);

                case '{':
                    return ParseObject(reader, type, dom);

                case '[':
                    return ParseCollection(reader, type, dom);

                default:
                    return null;
            }
        }
예제 #31
0
파일: Load.cs 프로젝트: TomGillen/Myre
        private static NodeReference ParseItem(StreamReader reader, Dom dom)
        {
            SkipWhitespace(reader);

            var type = ParseTypeName(reader);

            SkipWhitespace(reader);

            if (reader.Peek() == '#')
            {
                reader.Read();
                var value = ParseIdentifier(reader);
                var id = int.Parse(value);
                return new NodeReference(dom, id);
            }
            else
            {
                var node = ParseNode(reader, type, dom);
                return new NodeReference(dom, node);
            }
        }
예제 #32
0
파일: Load.cs 프로젝트: TomGillen/Myre
        private static Node ParseCollection(StreamReader reader, Type type, Dom dom)
        {
            List<CollectionNode> nodes = new List<CollectionNode>();

            // skip over [
            reader.Read();
            SkipWhitespace(reader);

            // read children
            bool isDictionary = false;
            while ((char)reader.Peek() != ']')
            {
                var node = new CollectionNode();

                // read first element
                node.First = ParseItem(reader, dom);

                var seperator = (char)reader.Peek();
                if (seperator == ':')
                {
                    // found dictionary key/value separator
                    reader.Read();

                    // read value
                    node.Second = ParseItem(reader, dom);
                    isDictionary = true;
                }

                // skip over ,
                if ((char)reader.Peek() == ',')
                    reader.Read();

                nodes.Add(node);
                SkipWhitespace(reader);
            }

            // skip over ]
            reader.Read();

            if (isDictionary)
                return CreateDictionary(type, nodes);
            else
                return CreateList(type, nodes);
        }
예제 #33
0
파일: Dom.cs 프로젝트: sachgits/Myre
 public NodeReference(Dom dom, int id)
 {
     this.dom  = dom;
     this.node = null;
     this.id   = id;
 }
예제 #34
0
 public override void Write(Stream stream, int indent)
 {
     base.Write(stream, indent);
     Dom.Write(stream, string.Format("\"{0}\"", Value));
 }
예제 #35
0
파일: Dom.cs 프로젝트: Quantumplation/Myre
 public NodeReference(Dom dom, int id)
 {
     this.dom = dom;
     this.node = null;
     this.id = id;
 }
예제 #36
0
 public abstract object Deserialise(Dom dom, IKernel kernel, Type expectedType);
예제 #37
0
파일: Dom.cs 프로젝트: sachgits/Myre
 public NodeReference(Dom dom, Node node)
 {
     this.dom  = dom;
     this.node = node;
     this.id   = null;
 }