Ejemplo n.º 1
0
 public virtual void Write(ResStringPool_header data)
 {
     Write(data.Header);
     _writer.Write(data.StringCount);
     _writer.Write(data.StyleCount);
     _writer.Write((uint) data.Flags);
     _writer.Write(data.StringStart);
     _writer.Write(data.StylesStart);
 }
Ejemplo n.º 2
0
        public virtual ResStringPool ReadResStringPool(ResStringPool_header header)
        {
            var pool = new ResStringPool
            {
                Header = header,
                //StringIndices = new List<uint>(),
                //StyleIndices = new List<uint>(),
                StringData = new List<string>(),
                StyleData = new List<ResStringPool_span>()
            };
            var stringIndices = new List<uint>();
            for (int i = 0; i < header.StringCount; i++)
            {
                stringIndices.Add(ReadUInt32());
            }
            for (int i = 0; i < header.StyleCount; i++)
            {
                ReadUInt32(); // Skip
            }

            long bytesLeft = header.Header.Size;
            bytesLeft -= header.Header.HeaderSize;
            bytesLeft -= 4*header.StringCount;
            bytesLeft -= 4*header.StyleCount;

            uint stringsEnd = header.StyleCount > 0 ? header.StylesStart : header.Header.Size;
            byte[] rawStringData = ReadBytes((int) stringsEnd - (int) header.StringStart);

            bytesLeft -= rawStringData.Length;

            bool isUtf8 = (header.Flags & StringPoolFlags.UTF8_FLAG) == StringPoolFlags.UTF8_FLAG;

            foreach (uint startingIndex in stringIndices)
            {
                uint pos = startingIndex;
                if (isUtf8)
                {
                    uint charLen = Helper.DecodeLengthUtf8(rawStringData, ref pos);
                    uint byteLen = Helper.DecodeLengthUtf8(rawStringData, ref pos);
                    string item = Encoding.UTF8.GetString(rawStringData, (int) pos, (int) byteLen);
                    if (item.Length != charLen)
                    {
                        Debug.WriteLine("Warning: UTF-8 string length ({0}) not matching specified length ({1}).",
                                        item.Length, charLen);
                    }
                    pool.StringData.Add(item);
                }
                else
                {
                    uint charLen = Helper.DecodeLengthUtf16(rawStringData, ref pos);
                    uint byteLen = charLen*2;
                    string item = Encoding.Unicode.GetString(rawStringData, (int) pos, (int) byteLen);
                    pool.StringData.Add(item);
                }
            }

            for (int i = 0; i < header.StyleCount; i++)
            {
                pool.StyleData.Add(ReadResStringPool_span());
            }

            bytesLeft -= header.StyleCount*12; // sizeof(ResStringPool_span) in C++

            if (bytesLeft < 0)
            {
                throw new InvalidDataException("The length of the content exceeds the ResStringPool block boundary.");
            }
            if (bytesLeft > 0)
            {
                // Padding?
                Debug.WriteLine("Warning: Garbage at the end of the StringPool block. Padding?");
                ReadBytes((int) bytesLeft);
            }

            return pool;
        }
Ejemplo n.º 3
0
        private IEnumerable <XmlParserEventCode> ParserIterator()
        {
            while (true)
            {
                ClearState();

                if (_reader.BaseStream.Position >= _reader.BaseStream.Length)
                {
                    // If we're at the end of the file, stop reading chunks.
                    // Don't try to catch an EndOfStreamException - this way,
                    // we avoid an exception being created.
                    break;
                }

                ResChunk_header header;
                try
                {
                    header = _reader.ReadResChunk_header();
                }
                catch (EndOfStreamException)
                {
                    // Keep this just in case.
                    break;
                }

                var subStream = new BoundedStream(_reader.BaseStream, header.Size - 8);
                var subReader = new ResReader(subStream);
                switch (header.Type)
                {
                case ResourceType.RES_XML_TYPE:
                    yield return(XmlParserEventCode.START_DOCUMENT);

                    _reader = subReader; // Bound whole file
                    continue;            // Don't skip content

                case ResourceType.RES_STRING_POOL_TYPE:
                    ResStringPool_header stringPoolHeader = subReader.ReadResStringPool_header(header);
                    _strings = subReader.ReadResStringPool(stringPoolHeader);
                    break;

                case ResourceType.RES_XML_RESOURCE_MAP_TYPE:
                    ResResourceMap resourceMap = subReader.ReadResResourceMap(header);
                    _resourceMap = resourceMap;
                    break;

                case ResourceType.RES_XML_START_NAMESPACE_TYPE:
                    _currentNode      = subReader.ReadResXMLTree_node(header);
                    _currentExtension = subReader.ReadResXMLTree_namespaceExt();
                    yield return(XmlParserEventCode.START_NAMESPACE);

                    break;

                case ResourceType.RES_XML_END_NAMESPACE_TYPE:
                    _currentNode      = subReader.ReadResXMLTree_node(header);
                    _currentExtension = subReader.ReadResXMLTree_namespaceExt();
                    yield return(XmlParserEventCode.END_NAMESPACE);

                    break;

                case ResourceType.RES_XML_START_ELEMENT_TYPE:
                    _currentNode = subReader.ReadResXMLTree_node(header);
                    ResXMLTree_attrExt attrExt = subReader.ReadResXMLTree_attrExt();
                    _currentExtension = attrExt;

                    _attributes = new List <ResXMLTree_attribute>();
                    for (int i = 0; i < attrExt.AttributeCount; i++)
                    {
                        _attributes.Add(subReader.ReadResXMLTree_attribute());
                    }
                    yield return(XmlParserEventCode.START_TAG);

                    break;

                case ResourceType.RES_XML_END_ELEMENT_TYPE:
                    _currentNode      = subReader.ReadResXMLTree_node(header);
                    _currentExtension = subReader.ReadResXMLTree_endElementExt();
                    yield return(XmlParserEventCode.END_TAG);

                    break;

                case ResourceType.RES_XML_CDATA_TYPE:
                    _currentNode      = subReader.ReadResXMLTree_node(header);
                    _currentExtension = subReader.ReadResXMLTree_cdataExt();
                    yield return(XmlParserEventCode.TEXT);

                    break;

                default:
#if !CORECLR
                    Console.WriteLine("Warning: Skipping chunk of type {0} (0x{1:x4})",
                                      header.Type, (int)header.Type);
#endif
                    break;
                }
                byte[] junk = subStream.ReadFully();
                if (junk.Length > 0)
                {
#if !CORECLR
                    Console.WriteLine("Warning: Skipping {0} bytes at the end of a {1} (0x{2:x4}) chunk.",
                                      junk.Length, header.Type, (int)header.Type);
#endif
                }
            }
        }