Beispiel #1
0
        /**
         * read String pool, for apk binary xml file and resource table.
         */
        public static async Task <StringPool> readStringPool(ByteBuffer buffer, StringPoolHeader stringPoolHeader)
        {
            long beginPos = buffer.position();

            long[] offsets = new long[(int)stringPoolHeader.getStringCount()];
            // read strings offset
            if (stringPoolHeader.getStringCount() > 0)
            {
                for (int idx = 0; idx < stringPoolHeader.getStringCount(); idx++)
                {
                    offsets[idx] = Buffers.readUInt(buffer);
                }
            }
            // read flag
            // the string index is sorted by the string values if true
            bool sorted = (stringPoolHeader.getFlags() & StringPoolHeader.SORTED_FLAG) != 0;
            // string use utf-8 format if true, otherwise utf-16
            bool utf8 = (stringPoolHeader.getFlags() & StringPoolHeader.UTF8_FLAG) != 0;

            // read strings. the head and metas have 28 bytes
            long stringPos = beginPos + stringPoolHeader.getStringsStart() - stringPoolHeader.getHeaderSize();

            buffer.position((int)stringPos);

            StringPoolEntry[] entries = new StringPoolEntry[offsets.Length];
            for (int i = 0; i < offsets.Length; i++)
            {
                entries[i] = new StringPoolEntry(i, stringPos + offsets[i]);
            }

            string     lastStr    = null;
            long       lastOffset = -1;
            StringPool stringPool = new StringPool((int)stringPoolHeader.getStringCount());

            foreach (StringPoolEntry entry in entries)
            {
                if (entry.getOffset() == lastOffset)
                {
                    stringPool.set(entry.getIdx(), lastStr);
                    continue;
                }

                buffer.position((int)entry.getOffset());
                lastOffset = entry.getOffset();
                string str = await ParseUtils.readString(buffer, utf8);

                lastStr = str;
                stringPool.set(entry.getIdx(), str);
            }

            // read styles
            if (stringPoolHeader.getStyleCount() > 0)
            {
                // now we just skip it
            }

            buffer.position((int)(beginPos + stringPoolHeader.getBodySize()));

            return(stringPool);
        }
Beispiel #2
0
        private async Task <ChunkHeader> readChunkHeader()
        {
            // finished
            if (!buffer.hasRemaining())
            {
                return(null);
            }

            long begin     = buffer.position();
            int  chunkType = await Buffers.readUShort(buffer);

            int headerSize = await Buffers.readUShort(buffer);

            long chunkSize = Buffers.readUInt(buffer);

            switch (chunkType)
            {
            case ChunkType.XML:
                return(new XmlHeader(chunkType, headerSize, chunkSize));

            case ChunkType.STRING_POOL:
                StringPoolHeader stringPoolHeader = new StringPoolHeader(chunkType, headerSize, chunkSize);
                stringPoolHeader.setStringCount(Buffers.readUInt(buffer));
                stringPoolHeader.setStyleCount(Buffers.readUInt(buffer));
                stringPoolHeader.setFlags(Buffers.readUInt(buffer));
                stringPoolHeader.setStringsStart(Buffers.readUInt(buffer));
                stringPoolHeader.setStylesStart(Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(stringPoolHeader);

            case ChunkType.XML_RESOURCE_MAP:
                buffer.position((int)(begin + headerSize));
                return(new XmlResourceMapHeader(chunkType, headerSize, chunkSize));

            case ChunkType.XML_START_NAMESPACE:
            case ChunkType.XML_END_NAMESPACE:
            case ChunkType.XML_START_ELEMENT:
            case ChunkType.XML_END_ELEMENT:
            case ChunkType.XML_CDATA:
                XmlNodeHeader header = new XmlNodeHeader(chunkType, headerSize, chunkSize);
                header.setLineNum((int)Buffers.readUInt(buffer));
                header.setCommentRef((int)Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(header);

            case ChunkType.NULL:
                return(new NullHeader(chunkType, headerSize, chunkSize));

            default:
                throw new ParserException("Unexpected chunk type:" + chunkType);
            }
        }
Beispiel #3
0
        private async Task <ChunkHeader> readChunkHeader()
        {
            long begin = buffer.position();

            int chunkType = await Buffers.readUShort(buffer);

            int headerSize = await Buffers.readUShort(buffer);

            long chunkSize = Buffers.readUInt(buffer);

            switch (chunkType)
            {
            case ChunkType.TABLE:
                ResourceTableHeader resourceTableHeader = new ResourceTableHeader(chunkType,
                                                                                  headerSize, chunkSize);
                resourceTableHeader.setPackageCount(Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(resourceTableHeader);

            case ChunkType.STRING_POOL:
                StringPoolHeader stringPoolHeader = new StringPoolHeader(chunkType, headerSize,
                                                                         chunkSize);
                stringPoolHeader.setStringCount(Buffers.readUInt(buffer));
                stringPoolHeader.setStyleCount(Buffers.readUInt(buffer));
                stringPoolHeader.setFlags(Buffers.readUInt(buffer));
                stringPoolHeader.setStringsStart(Buffers.readUInt(buffer));
                stringPoolHeader.setStylesStart(Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(stringPoolHeader);

            case ChunkType.TABLE_PACKAGE:
                PackageHeader packageHeader = new PackageHeader(chunkType, headerSize, chunkSize);
                packageHeader.setId(Buffers.readUInt(buffer));
                packageHeader.setName(ParseUtils.readStringUTF16(buffer, 128));
                packageHeader.setTypeStrings(Buffers.readUInt(buffer));
                packageHeader.setLastPublicType(Buffers.readUInt(buffer));
                packageHeader.setKeyStrings(Buffers.readUInt(buffer));
                packageHeader.setLastPublicKey(Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(packageHeader);

            case ChunkType.TABLE_TYPE_SPEC:
                TypeSpecHeader typeSpecHeader = new TypeSpecHeader(chunkType, headerSize, chunkSize);
                typeSpecHeader.setId(Buffers.readUByte(buffer));
                typeSpecHeader.setRes0(Buffers.readUByte(buffer));
                typeSpecHeader.setRes1(await Buffers.readUShort(buffer));
                typeSpecHeader.setEntryCount(Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(typeSpecHeader);

            case ChunkType.TABLE_TYPE:
                TypeHeader typeHeader = new TypeHeader(chunkType, headerSize, chunkSize);
                typeHeader.setId(Buffers.readUByte(buffer));
                typeHeader.setRes0(Buffers.readUByte(buffer));
                typeHeader.setRes1(await Buffers.readUShort(buffer));
                typeHeader.setEntryCount(Buffers.readUInt(buffer));
                typeHeader.setEntriesStart(Buffers.readUInt(buffer));
                typeHeader.setConfig(readResTableConfig());
                buffer.position((int)(begin + headerSize));
                return(typeHeader);

            case ChunkType.TABLE_LIBRARY:
                //DynamicRefTable
                LibraryHeader libraryHeader = new LibraryHeader(chunkType, headerSize, chunkSize);
                libraryHeader.setCount(Buffers.readUInt(buffer));
                buffer.position((int)(begin + headerSize));
                return(libraryHeader);

            case ChunkType.NULL:
            //buffer.skip((int) (chunkSize - headerSize));
            default:
                throw new ParserException("Unexpected chunk Type: 0x" + chunkType.ToString("X"));
            }
        }