Helper methods for ICodec implementers.
Exemplo n.º 1
0
        object DecodeAttribute(Datamodel dm, bool prefix)
        {
            var type = IdToType(Reader.ReadByte());

            if (!Datamodel.IsDatamodelArrayType(type))
            {
                return(ReadValue(dm, type, EncodingVersion < 4 || prefix));
            }
            else
            {
                var count      = Reader.ReadInt32();
                var inner_type = Datamodel.GetArrayInnerType(type);
                var array      = CodecUtilities.MakeList(inner_type, count);

                foreach (var x in Enumerable.Range(0, count))
                {
                    array.Add(ReadValue(dm, inner_type, true));
                }

                return(array);
            }
        }
Exemplo n.º 2
0
        object DecodeAttribute(Datamodel dm)
        {
            var types = IdToType(Reader.ReadByte());

            if (types.Item2 == null)
            {
                return(ReadValue(dm, types.Item1, EncodingVersion < 4));
            }
            else
            {
                var count      = Reader.ReadInt32();
                var inner_type = types.Item2;
                var array      = CodecUtilities.MakeList(inner_type, count);

                foreach (var x in Enumerable.Range(0, count))
                {
                    array.Add(ReadValue(dm, inner_type, true));
                }

                return(array);
            }
        }
Exemplo n.º 3
0
        public Datamodel Decode(int encoding_version, string format, int format_version, Stream stream, DeferredMode defer_mode)
        {
            stream.Seek(0, SeekOrigin.Begin);
            while (true)
            {
                var b = stream.ReadByte();
                if (b == 0)
                {
                    break;
                }
            }
            var dm = new Datamodel(format, format_version);

            EncodingVersion = encoding_version;
            Reader          = new BinaryReader(stream, Datamodel.TextEncoding);

            if (EncodingVersion >= 9)
            {
                // Read prefix elements
                foreach (int prefix_elem in Enumerable.Range(0, Reader.ReadInt32()))
                {
                    foreach (int attr_index in Enumerable.Range(0, Reader.ReadInt32()))
                    {
                        var name  = ReadString_Raw();
                        var value = DecodeAttribute(dm, true);
                        if (prefix_elem == 0) // skip subsequent elements...are they considered "old versions"?
                        {
                            dm.PrefixAttributes[name] = value;
                        }
                    }
                }
            }

            StringDict = new StringDictionary(this, Reader);
            var num_elements = Reader.ReadInt32();

            // read index
            foreach (var i in Enumerable.Range(0, num_elements))
            {
                var type    = StringDict.ReadString();
                var name    = EncodingVersion >= 4 ? StringDict.ReadString() : ReadString_Raw();
                var id_bits = Reader.ReadBytes(16);
                var id      = new Guid(BitConverter.IsLittleEndian ? id_bits : id_bits.Reverse().ToArray());

                var elem = new Element(dm, name, id, type);
            }

            // read attributes (or not, if we're deferred)
            foreach (var elem in dm.AllElements.ToArray())
            {
                System.Diagnostics.Debug.Assert(!elem.Stub);

                var num_attrs = Reader.ReadInt32();

                foreach (var i in Enumerable.Range(0, num_attrs))
                {
                    var name = StringDict.ReadString();

                    if (defer_mode == DeferredMode.Automatic)
                    {
                        CodecUtilities.AddDeferredAttribute(elem, name, Reader.BaseStream.Position);
                        SkipAttribte();
                    }
                    else
                    {
                        elem.Add(name, DecodeAttribute(dm, false));
                    }
                }
            }
            return(dm);
        }
Exemplo n.º 4
0
        Element Decode_ParseElement(string class_name)
        {
            string  elem_class = class_name ?? Decode_NextToken();
            string  elem_name  = null;
            string  elem_id    = null;
            Element elem       = null;

            string next = Decode_NextToken();

            if (next != "{")
            {
                throw new CodecException(String.Format("Expected Element opener, got '{0}'.", next));
            }
            while (true)
            {
                next = Decode_NextToken();
                if (next == "}")
                {
                    break;
                }

                var attr_name   = next;
                var attr_type_s = Decode_NextToken();
                var attr_type   = TypeNames.FirstOrDefault(kv => kv.Value == attr_type_s.Split('_')[0]).Key;

                if (elem == null && attr_name == "id" && attr_type_s == "elementid")
                {
                    elem_id = Decode_NextToken();
                    var id            = new Guid(elem_id);
                    var local_element = DM.AllElements[id];
                    if (local_element != null)
                    {
                        elem           = local_element;
                        elem.Name      = elem_name;
                        elem.ClassName = elem_class;
                        elem.Stub      = false;
                    }
                    else if (elem_class != "$prefix_element$")
                    {
                        elem = new Element(DM, elem_name, new Guid(elem_id), elem_class);
                    }

                    continue;
                }

                if (attr_name == "name" && attr_type == typeof(string))
                {
                    elem_name = Decode_NextToken();
                    if (elem != null)
                    {
                        elem.Name = elem_name;
                    }
                    continue;
                }

                if (elem == null)
                {
                    continue;
                }

                if (attr_type_s == "element")
                {
                    elem.Add(attr_name, Decode_ParseElementId());
                    continue;
                }

                object attr_value = null;

                if (attr_type == null)
                {
                    attr_value = Decode_ParseElement(attr_type_s);
                }
                else if (attr_type_s.EndsWith("_array"))
                {
                    var array = CodecUtilities.MakeList(attr_type, 5); // assume 5 items
                    attr_value = array;

                    next = Decode_NextToken();
                    if (next != "[")
                    {
                        throw new CodecException(String.Format("Expected array opener, got '{0}'.", next));
                    }
                    while (true)
                    {
                        next = Decode_NextToken();
                        if (next == "]")
                        {
                            break;
                        }

                        if (next == "element") // Element ID reference
                        {
                            array.Add(Decode_ParseElementId());
                        }
                        else if (attr_type == typeof(Element)) // inline Element
                        {
                            array.Add(Decode_ParseElement(next));
                        }
                        else // normal value
                        {
                            array.Add(Decode_ParseValue(attr_type, next));
                        }
                    }
                }
                else
                {
                    attr_value = Decode_ParseValue(attr_type, Decode_NextToken());
                }

                if (elem != null)
                {
                    elem.Add(attr_name, attr_value);
                }
                else
                {
                    DM.PrefixAttributes[attr_name] = attr_value;
                }
            }
            return(elem);
        }