public string GetResouceName(uint? resourceId, ResStringPool strings) { if (resourceId == null) return null; uint index = 0; foreach (uint id in ResouceIds) { if (id == resourceId) { return strings.GetString(index); } index++; } return null; }
public string GetResouceName(uint?resourceId, ResStringPool strings) { if (resourceId == null) { return(null); } uint index = 0; foreach (uint id in ResouceIds) { if (id == resourceId) { return(strings.GetString(index)); } index++; } return(null); }
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; }
private IEnumerable<XmlParserEventCode> ParserIterator() { while (true) { ClearState(); ResChunk_header header; try { header = _reader.ReadResChunk_header(); } catch (EndOfStreamException) { 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: Console.WriteLine("Warning: Skipping chunk of type {0} (0x{1:x4})", header.Type, (int) header.Type); break; } byte[] junk = subStream.ReadFully(); if (junk.Length > 0) { Console.WriteLine("Warning: Skipping {0} bytes at the end of a {1} (0x{2:x4}) chunk.", junk.Length, header.Type, (int) header.Type); } } }
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 } } }