Ejemplo n.º 1
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal Value(ResReader reader)
 {
     var size = reader.ReadUInt16();
     reader.Skip(1); // res0
     type = (Types)reader.ReadByte();
     data = reader.ReadInt32();
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 protected Node(ResReader reader, XmlTree tree, ChunkTypes expectedType)
     : base(reader, expectedType)
 {
     this.tree = tree;
     LineNumber = reader.ReadInt32();
     Comment = StringPoolRef.Read(reader, tree.StringPool);
 }
Ejemplo n.º 3
0
            /// <summary>
            /// Read ctor
            /// </summary>
            internal Type(TypeSpec parent, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_TYPE_TYPE)
            {
                this.parent = parent;

                var id = reader.ReadByte();
                reader.Skip(3); // reserved
                if (id != parent.Id)
                {
                    throw new IOException("Type id (" + id + ") " + "doesn't match parent id (" + parent.Id + ").");
                }
                var entryCount = reader.ReadInt32();
                if (entryCount != parent.EntryCount)
                {
                    throw new IOException(string.Format("Type entry count ({0}) doesn't match parent entry count ({1})", entryCount, parent.EntryCount));
                }
                var entriesStart = reader.ReadInt32();
                configuration = new Configuration(reader);
                // Data
                var offsets = reader.ReadIntArray(entryCount);
                var dataSize = (Size - entriesStart);
                if ((dataSize % 4) != 0)
                {
                    throw new IOException("Type data size (" + dataSize + ") is not multiple of 4.");
                }
                for (var i = 0; i < entryCount; i++ )
                {
                    if (offsets[i] != NO_ENTRY)
                    {
                        var actualOffset = reader.Position;
                        var instance = EntryInstance.Read(this, reader);
                        parent.GetEntry(i).Add(instance);
                    } 
                }
            }
Ejemplo n.º 4
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 protected Node(ResReader reader, XmlTree tree, ChunkTypes expectedType)
     : base(reader, expectedType)
 {
     this.tree  = tree;
     LineNumber = reader.ReadInt32();
     Comment    = StringPoolRef.Read(reader, tree.StringPool);
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Reader ctor
 /// </summary>
 protected Chunk(ResReader reader, ChunkTypes expectedType)
     : this(reader)
 {
     if (type != expectedType)
     {
         throw new IOException(string.Format("Expected chunk of type 0x{0:X}, read 0x{1:X}.", (int)expectedType, (int)type));
     }
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Read ctor
 /// </summary>
 internal Attribute(ResReader reader, XmlTree tree)
 {
     this.tree  = tree;
     Namespace  = StringPoolRef.Read(reader, tree.StringPool);
     Name       = StringPoolRef.Read(reader, tree.StringPool);
     RawValue   = StringPoolRef.Read(reader, tree.StringPool);
     TypedValue = new Value(reader);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Read ctor
 /// </summary>
 internal Attribute(ResReader reader, XmlTree tree)
 {
     this.tree = tree;
     Namespace = StringPoolRef.Read(reader, tree.StringPool);
     Name = StringPoolRef.Read(reader, tree.StringPool);
     RawValue = StringPoolRef.Read(reader, tree.StringPool);
     TypedValue = new Value(reader);
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Reading ctor
        /// </summary>
        internal Value(ResReader reader)
        {
            var size = reader.ReadUInt16();

            reader.Skip(1); // res0
            type = (Types)reader.ReadByte();
            data = reader.ReadInt32();
        }
Ejemplo n.º 9
0
            /// <summary>
            /// Read ctor
            /// </summary>
            protected EntryInstance(Type parent, ResReader reader)
            {
                this.parent = parent;

                // header
                var size = reader.ReadUInt16();
                flags = (EntryFlags) reader.ReadUInt16();
                key = StringPoolRef.Read(reader, parent.TypeSpec.Package.KeyStrings);
            }
Ejemplo n.º 10
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal ResourceMap(ResReader reader)
     : base(reader, ChunkTypes.RES_XML_RESOURCE_MAP_TYPE)
 {
     if (Size < 8 || (Size % 4) != 0)
     {
         throw new IOException("Invalid resource ids size (" + Size + ").");
     }
     resourceIds.AddRange(reader.ReadIntArray(Size / 4 - 2));
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal ResourceMap(ResReader reader)
     : base(reader, ChunkTypes.RES_XML_RESOURCE_MAP_TYPE)
 {
     if (Size < 8 || (Size % 4) != 0)
     {
         throw new IOException("Invalid resource ids size (" + Size + ").");
     }
     resourceIds.AddRange(reader.ReadIntArray(Size / 4 - 2));
 }
Ejemplo n.º 12
0
            /// <summary>
            /// Read ctor
            /// </summary>
            protected EntryInstance(Type parent, ResReader reader)
            {
                this.parent = parent;

                // header
                var size = reader.ReadUInt16();

                flags = (EntryFlags)reader.ReadUInt16();
                key   = StringPoolRef.Read(reader, parent.TypeSpec.Package.KeyStrings);
            }
Ejemplo n.º 13
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal Table(ResReader reader)
     : base(reader, ChunkTypes.RES_TABLE_TYPE)
 {
     var packageCount = reader.ReadInt32();
     strings = new StringPool(reader);
     for (var i = 0; i < packageCount; i++)
     {
         packages.Add(new Package(this, reader));
     }
 }
Ejemplo n.º 14
0
            /// <summary>
            /// Reader ctor
            /// </summary>
            internal TypeSpec(Package parent, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_TYPE_SPEC_TYPE)
            {
                this.parent = parent;

                id = reader.ReadByte();
                reader.Skip(3); // reserved
                var entryCount = reader.ReadInt32();
                var flags = reader.ReadIntArray(entryCount).ToList();
                entries.AddRange(flags.Select(x => new Entry(this, x)));
            }
Ejemplo n.º 15
0
        /// <summary>
        /// Default ctor
        /// </summary>
        internal Table(ResReader reader)
            : base(reader, ChunkTypes.RES_TABLE_TYPE)
        {
            var packageCount = reader.ReadInt32();

            strings = new StringPool(reader);
            for (var i = 0; i < packageCount; i++)
            {
                packages.Add(new Package(this, reader));
            }
        }
Ejemplo n.º 16
0
            /// <summary>
            /// Read an entry and return it.
            /// </summary>
            internal static EntryInstance Read(Type parent, ResReader reader)
            {
                var position = reader.Position;
                var size = reader.ReadUInt16();
                var flags = (EntryFlags) reader.ReadUInt16();
                reader.Position = position;

                if ((flags & EntryFlags.Complex) != 0)
                    return new ComplexEntryInstance(parent, reader);
                return new SimpleEntryInstance(parent, reader);
            }
Ejemplo n.º 17
0
            /// <summary>
            /// Read ctor
            /// </summary>
            internal ComplexEntryInstance(Type parent, ResReader reader)
                : base(parent, reader)
            {
                var parentResId = TableRef.Read(reader);
                var count       = reader.ReadInt32();

                //reader.Skip(count*12);
                for (var i = 0; i < count; i++)
                {
                    maps.Add(new Map(this, reader));
                }
            }
Ejemplo n.º 18
0
            /// <summary>
            /// Read ctor
            /// </summary>
            internal ComplexEntryInstance(Type parent, ResReader reader)
                : base(parent, reader)
            {
                var parentResId = TableRef.Read(reader);
                var count = reader.ReadInt32();

                //reader.Skip(count*12);
                for (var i = 0; i < count; i++)
                {
                    maps.Add(new Map(this, reader));
                }
            }
Ejemplo n.º 19
0
        /// <summary>
        /// Default a length for charsize=2
        /// </summary>
        private static int DecodeLength16(ResReader reader, byte[] strings, ref int offset)
        {
            var length = reader.ReadUInt16(strings, offset);

            offset += 2;
            if ((length & 0x8000) != 0)
            {
                length  = ((length & 0x7FFF) << 16) | reader.ReadUInt16(strings, offset);
                offset += 2;
            }
            return(length);
        }
Ejemplo n.º 20
0
            /// <summary>
            /// Reader ctor
            /// </summary>
            internal TypeSpec(Package parent, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_TYPE_SPEC_TYPE)
            {
                this.parent = parent;

                id = reader.ReadByte();
                reader.Skip(3); // reserved
                var entryCount = reader.ReadInt32();
                var flags      = reader.ReadIntArray(entryCount).ToList();

                entries.AddRange(flags.Select(x => new Entry(this, x)));
            }
Ejemplo n.º 21
0
            /// <summary>
            /// Read an entry and return it.
            /// </summary>
            internal static EntryInstance Read(Type parent, ResReader reader)
            {
                var position = reader.Position;
                var size     = reader.ReadUInt16();
                var flags    = (EntryFlags)reader.ReadUInt16();

                reader.Position = position;

                if ((flags & EntryFlags.Complex) != 0)
                {
                    return(new ComplexEntryInstance(parent, reader));
                }
                return(new SimpleEntryInstance(parent, reader));
            }
Ejemplo n.º 22
0
            /// <summary>
            /// Reading ctor
            /// </summary>
            internal StartElement(ResReader reader, XmlTree tree)
                : base(reader, tree, ChunkTypes.RES_XML_START_ELEMENT_TYPE)
            {
                var attributeStart = reader.ReadUInt16();
                var attributeSize  = reader.ReadUInt16();
                var attributeCount = reader.ReadUInt16();
                var id             = reader.ReadUInt16();
                var classIndex     = reader.ReadUInt16();
                var styleIndex     = reader.ReadUInt16();

                for (var i = 0; i < attributeCount; i++)
                {
                    attributes.Add(new Attribute(reader, tree));
                }
            }
Ejemplo n.º 23
0
            /// <summary>
            /// Reading ctor
            /// </summary>
            internal StartElement(ResReader reader, XmlTree tree)
                : base(reader, tree, ChunkTypes.RES_XML_START_ELEMENT_TYPE)
            {
                var attributeStart = reader.ReadUInt16();
                var attributeSize = reader.ReadUInt16();
                var attributeCount = reader.ReadUInt16();
                var id = reader.ReadUInt16();
                var classIndex = reader.ReadUInt16();
                var styleIndex = reader.ReadUInt16();

                for (var i = 0; i < attributeCount; i++)
                {
                    attributes.Add(new Attribute(reader, tree));
                }
            }
Ejemplo n.º 24
0
        /// <summary>
        /// Helper used to read chunks and check the actual size read.
        /// </summary>
        internal static T Read <T>(ResReader reader, Func <T> readAction)
            where T : Chunk
        {
            var startPosition = reader.Position;
            var result        = readAction();
            var endPosition   = reader.Position;
            var size          = endPosition - startPosition;

            if (size != result.Size)
            {
#if DEBUG
                Debugger.Launch();
#endif
                throw new ArgumentException("Size mismatch");
            }
            return(result);
        }
Ejemplo n.º 25
0
            /// <summary>
            /// Default ctor
            /// </summary>
            internal Package(Table table, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_PACKAGE_TYPE)
            {
                this.table = table;

                id   = reader.ReadInt32();
                name = reader.ReadFixedLenghtUnicodeString(128);
                var typeStringsOffset = reader.ReadInt32();
                var lastPublicType    = reader.ReadInt32();
                var keyStringsOffset  = reader.ReadInt32();
                var lastPublicKey     = reader.ReadInt32();

                // Record offset
                var dataOffset = reader.Position;

                // Data
                typeStrings = new StringPool(reader);
                keyStrings  = new StringPool(reader);

                TypeSpec currentTypeSpec = null;

                while (reader.Position - dataOffset < DataSize)
                {
                    var chunkType = reader.PeekChunkType();
                    if (chunkType == ChunkTypes.RES_TABLE_TYPE_SPEC_TYPE)
                    {
                        currentTypeSpec = Read(reader, () => new TypeSpec(this, reader));
                        typeSpecs.Add(currentTypeSpec);
                    }
                    else if (chunkType == ChunkTypes.RES_TABLE_TYPE_TYPE)
                    {
                        if (currentTypeSpec == null)
                        {
                            throw new IOException("Invalid chunk sequence: content read before typeSpec.");
                        }
                        var parent = currentTypeSpec;
                        var type   = Read(reader, () => new Type(parent, reader));
                        currentTypeSpec.Add(type);
                    }
                    else
                    {
                        throw new IOException("Unexpected chunk type (" + chunkType + ").");
                    }
                }
            }
Ejemplo n.º 26
0
            /// <summary>
            /// Default ctor
            /// </summary>
            internal Package(Table table, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_PACKAGE_TYPE)
            {
                this.table = table;

                id = reader.ReadInt32();
                name = reader.ReadFixedLenghtUnicodeString(128);
                var typeStringsOffset = reader.ReadInt32();
                var lastPublicType = reader.ReadInt32();
                var keyStringsOffset = reader.ReadInt32();
                var lastPublicKey = reader.ReadInt32();

                // Record offset
                var dataOffset = reader.Position;

                // Data
                typeStrings = new StringPool(reader);
                keyStrings = new StringPool(reader);

                TypeSpec currentTypeSpec = null;
                while (reader.Position - dataOffset < DataSize)
                {
                    var chunkType = reader.PeekChunkType();
                    if (chunkType == ChunkTypes.RES_TABLE_TYPE_SPEC_TYPE)
                    {
                        currentTypeSpec = Read(reader, () => new TypeSpec(this, reader));
                        typeSpecs.Add(currentTypeSpec);
                    }
                    else if (chunkType == ChunkTypes.RES_TABLE_TYPE_TYPE)
                    {
                        if (currentTypeSpec == null)
                        {
                            throw new IOException("Invalid chunk sequence: content read before typeSpec.");
                        }
                        var parent = currentTypeSpec;
                        var type = Read(reader, () => new Type(parent, reader));
                        currentTypeSpec.Add(type);
                    }
                    else
                    {
                        throw new IOException("Unexpected chunk type (" + chunkType + ").");
                    }
                }
            }
Ejemplo n.º 27
0
        /// <summary>
        /// Reading ctor
        /// </summary>
        public XmlTree(ResReader reader)
            : base(reader, ChunkTypes.RES_XML_TYPE)
        {
            strings     = new StringPool(reader);
            resourceMap = new ResourceMap(reader);

            while (true)
            {
                var  tag = reader.PeekChunkType();
                Node node;
                switch (tag)
                {
                case ChunkTypes.RES_XML_START_NAMESPACE_TYPE:
                    node = new StartNamespace(reader, this);
                    break;

                case ChunkTypes.RES_XML_START_ELEMENT_TYPE:
                    node = new StartElement(reader, this);
                    break;

                case ChunkTypes.RES_XML_CDATA_TYPE:
                    node = new CData(reader, this);
                    break;

                case ChunkTypes.RES_XML_END_ELEMENT_TYPE:
                    node = new EndElement(reader, this);
                    break;

                case ChunkTypes.RES_XML_END_NAMESPACE_TYPE:
                    node = new EndNamespace(reader, this);
                    break;

                default:
                    throw new IOException(string.Format("Unexpected tag: 0x{0:X}", (int)tag));
                }

                nodes.Add(node);
                if (tag == ChunkTypes.RES_XML_END_NAMESPACE_TYPE)
                {
                    break;
                }
            }
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Default ctor
        /// </summary>
        internal StringPool(ResReader reader)
            : base(reader, ChunkTypes.RES_STRING_POOL_TYPE)
        {
            var stringCount      = reader.ReadInt32();
            var styleOffsetCount = reader.ReadInt32();
            var flags            = (StringPoolFlags)reader.ReadInt32();

            IsUtf8 = ((flags & StringPoolFlags.UTF8_FLAG) != 0);
            var stringsStart = reader.ReadInt32();
            var stylesStart  = reader.ReadInt32();

            var stringOffsets = reader.ReadIntArray(stringCount);

            if (styleOffsetCount != 0)
            {
                styleOffsets = reader.ReadIntArray(styleOffsetCount);
            }
            byte[] stringData;
            {
                var size = ((stylesStart == 0) ? Size : stylesStart) - stringsStart;
                if ((size % 4) != 0)
                {
                    throw new IOException(string.Format("String data size is not multiple of 4 ({0}).", size));
                }
                stringData = reader.ReadByteArray(size);
            }
            if (stylesStart != 0)
            {
                var size = (Size - stylesStart);
                if ((size % 4) != 0)
                {
                    throw new IOException(string.Format("Style data size is not multiple of 4 ({0}).", size));
                }
                styles = reader.ReadIntArray(size / 4);
            }

            var count = (stringOffsets != null) ? stringOffsets.Length : 0;

            for (var i = 0; i != count; ++i)
            {
                list.Add(new Entry(GetRaw(i, stringOffsets, stringData, IsUtf8, reader), -1));
            }
        }
Ejemplo n.º 29
0
            /// <summary>
            /// Read ctor
            /// </summary>
            internal Type(TypeSpec parent, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_TYPE_TYPE)
            {
                this.parent = parent;

                var id = reader.ReadByte();

                reader.Skip(3); // reserved
                if (id != parent.Id)
                {
                    throw new IOException("Type id (" + id + ") " + "doesn't match parent id (" + parent.Id + ").");
                }
                var entryCount = reader.ReadInt32();

                if (entryCount != parent.EntryCount)
                {
                    throw new IOException(string.Format("Type entry count ({0}) doesn't match parent entry count ({1})", entryCount, parent.EntryCount));
                }
                var entriesStart = reader.ReadInt32();

                configuration = new Configuration(reader);
                // Data
                var offsets  = reader.ReadIntArray(entryCount);
                var dataSize = (Size - entriesStart);

                if ((dataSize % 4) != 0)
                {
                    throw new IOException("Type data size (" + dataSize + ") is not multiple of 4.");
                }
                for (var i = 0; i < entryCount; i++)
                {
                    if (offsets[i] != NO_ENTRY)
                    {
                        var actualOffset = reader.Position;
                        var instance     = EntryInstance.Read(this, reader);
                        parent.GetEntry(i).Add(instance);
                    }
                }
            }
Ejemplo n.º 30
0
        /// <summary>
        /// Reading ctor
        /// </summary>
        public XmlTree(ResReader reader)
            : base(reader, ChunkTypes.RES_XML_TYPE)
        {
            strings = new StringPool(reader);
            resourceMap = new ResourceMap(reader);

            while (true)
            {
                var tag = reader.PeekChunkType();
                Node node;
                switch (tag)
                {
                    case ChunkTypes.RES_XML_START_NAMESPACE_TYPE:
                        node = new StartNamespace(reader, this);
                        break;
                    case ChunkTypes.RES_XML_START_ELEMENT_TYPE:
                        node = new StartElement(reader, this);
                        break;
                    case ChunkTypes.RES_XML_CDATA_TYPE:
                        node = new CData(reader, this);
                        break;
                    case ChunkTypes.RES_XML_END_ELEMENT_TYPE:
                        node = new EndElement(reader, this);
                        break;
                    case ChunkTypes.RES_XML_END_NAMESPACE_TYPE:
                        node = new EndNamespace(reader, this);
                        break;
                    default:
                        throw new IOException(string.Format("Unexpected tag: 0x{0:X}", (int)tag));
                }

                nodes.Add(node);
                if (tag == ChunkTypes.RES_XML_END_NAMESPACE_TYPE)
                    break;
            }
        }
Ejemplo n.º 31
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal EndNamespace(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_END_NAMESPACE_TYPE)
 {
 }
Ejemplo n.º 32
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal StartNamespace(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_START_NAMESPACE_TYPE)
 {
 }
Ejemplo n.º 33
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal EndElement(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_END_ELEMENT_TYPE)
 {
 }
Ejemplo n.º 34
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal CData(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_CDATA_TYPE)
 {
     Data = StringPoolRef.Read(reader, tree.StringPool);
     TypedData = new Value(reader);
 }
Ejemplo n.º 35
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal StartNamespace(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_START_NAMESPACE_TYPE)
 {
 }
Ejemplo n.º 36
0
 /// <summary>
 /// Reader ctor
 /// </summary>
 protected Chunk(ResReader reader)
 {
     type       = (ChunkTypes)reader.ReadUInt16();
     headerSize = reader.ReadUInt16();
     size       = reader.ReadInt32();
 }
Ejemplo n.º 37
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal CData(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_CDATA_TYPE)
 {
     Data      = StringPoolRef.Read(reader, tree.StringPool);
     TypedData = new Value(reader);
 }
Ejemplo n.º 38
0
 /// <summary>
 /// Read ctor
 /// </summary>
 internal SimpleEntryInstance(Type parent, ResReader reader)
     : base(parent, reader)
 {
     // Read value
     value = new Value(reader);
 }
Ejemplo n.º 39
0
            /// <summary>
            /// Read ctor
            /// </summary>
            internal Configuration(ResReader reader)
            {
                var size = reader.ReadInt32();

                data = reader.ReadByteArray(size - 4);
            }
Ejemplo n.º 40
0
 /// <summary>
 /// Read a 32-bit unsigned int from the given offset.
 /// </summary>
 private int GetInt32(int offset)
 {
     return(ResReader.DecodeInt32(data, offset, UseBigEndian));
 }
Ejemplo n.º 41
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal EndNamespace(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_END_NAMESPACE_TYPE)
 {
 }
Ejemplo n.º 42
0
 /// <summary>
 /// Reading ctor
 /// </summary>
 internal EndElement(ResReader reader, XmlTree tree)
     : base(reader, tree, ChunkTypes.RES_XML_END_ELEMENT_TYPE)
 {
 }
Ejemplo n.º 43
0
        /// <summary>
        /// Returns raw string (without any styling information) at specified index.
        /// Returns null if index is invalid or object was not initialized.
        /// </summary>
        private static string GetRaw(int index, int[] stringOffsets, byte[] strings, bool isUtf8, ResReader reader)
        {
            if (index < 0 || (stringOffsets == null) || (index >= stringOffsets.Length))
            {
                return(null);
            }
            var offset = stringOffsets[index];
            int length;

            if (isUtf8)
            {
                // charsize = 1
                // Decode length
                var u16Length = DecodeLength8(strings, ref offset);
                length = DecodeLength8(strings, ref offset);
                return(AndroidEncodings.UTF8.GetString(strings, offset, length));
            }

            // charsize = 2
            length = DecodeLength16(reader, strings, ref offset);
            var data = new char[length];

            for (var i = 0; i < length; i++)
            {
                data[i] = (char)reader.ReadUInt16(strings, offset);
                offset += 2;
            }
            return(new string(data));
        }
Ejemplo n.º 44
0
 /// <summary>
 /// Read ctor
 /// </summary>
 internal SimpleEntryInstance(Type parent, ResReader reader)
     : base(parent, reader)
 {
     // Read value
     value = new Value(reader);
 }