123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "android-xml.h"
- #include "ResStringPool.h"
- #include "ResXMLTreeNode.h"
- #include "XMLNameSpace.h"
- uint32_t g_lineno = 0;
- int main(int argc, char **argv) {
- FILE* fp = fopen(argv[1], "rb");
- if (!fp) {
- perror("Error opening file");
- exit(1);
- }
- fseek(fp, 0, SEEK_END);
- uint32_t filesize = ftell(fp);
- rewind(fp);
- fprintf(stderr, "Got %i bytes of data\n", filesize);
- char* data = (char*) malloc(filesize);
- if (!data) {
- perror("Error allocating");
- exit(1);
- }
- fread(data, 1, filesize, fp);
- fclose(fp);
- uint32_t filepos = 0;
- ResChunk_header cur_header;
- memcpy(&cur_header, data + filepos, sizeof(ResChunk_header));
- if (cur_header.type != RES_XML_TYPE) {
- fprintf(stderr, "Not an Android binary XML file\n");
- exit(1);
- }
- if (cur_header.size != filesize) {
- fprintf(stderr, "Header size does not match filesize\n");
- exit(1);
- }
- filepos += cur_header.headerSize;
- ResXMLTreeNode root(true);
- ResXMLTreeNode* cur = &root;
- ResStringPool* stringpool = nullptr;
- XMLNameSpace* ns = nullptr;
- char* resource_map = nullptr;
- uint32_t resource_map_size = 0;
- while (filepos < filesize) {
- memcpy(&cur_header, data + filepos, sizeof(ResChunk_header));
- switch (cur_header.type) {
- case RES_STRING_POOL_TYPE: {
- fprintf(stderr, "RES_STRING_POOL_TYPE\n");
- stringpool = new ResStringPool(data + filepos);
- break;
- }
- case RES_XML_RESOURCE_MAP_TYPE: {
- fprintf(stderr, "RES_XML_RESOURCE_MAP_TYPE\n");
-
- resource_map = (char*) malloc(cur_header.size);
- resource_map_size = cur_header.size;
- memcpy(resource_map, data + filepos, cur_header.size);
- break;
- }
- case RES_XML_END_NAMESPACE_TYPE:
- fprintf(stderr, "RES_XML_END_NAMESPACE_TYPE\n");
- break;
- case RES_XML_CDATA_TYPE: {
- printf(
- "Sorry found XML_CDATA_TYPE don't know how to deal with that\n");
- exit(1);
- }
- case RES_XML_LAST_CHUNK_TYPE:
- fprintf(stderr, "RES_XML_LAST_CHUNK_TYPE\n");
- break;
- case RES_XML_START_ELEMENT_TYPE: {
- ResXMLTreeNode* node = new ResXMLTreeNode(*stringpool,
- data + filepos);
- cur->add_child(node);
- cur = node;
- break;
- }
- case RES_XML_END_ELEMENT_TYPE: {
- cur = cur->_parent;
- break;
- }
- case RES_XML_START_NAMESPACE_TYPE: {
- fprintf(stderr, "RES_XML_START_NAMESPACE_TYPE\n");
- ns = new XMLNameSpace(*stringpool, data + filepos);
- break;
- }
- default:
- fprintf(stderr, "Unknown chunk type 0x%03X\n", cur_header.type);
- exit(1);
- }
- filepos += cur_header.size;
- }
- char* xml_serialized;
- uint32_t xml_serialized_size;
- xml_serialized_size = root.serialize(*stringpool, &xml_serialized);
- fprintf(stderr, "XML serialized to %i bytes\n", xml_serialized_size);
- fprintf(stderr, "XML resource map was %i bytes\n", resource_map_size);
- FILE* out = fopen(argv[2], "wb");
- char* ns_serialzed;
- uint32_t ns_serialized_size = 0;
- if (ns) {
- ns_serialized_size = ns->serialize(*stringpool, &ns_serialzed);
- fprintf(stderr, "Namespace serialized to %i bytes\n",
- ns_serialized_size);
- }
- char* ns_end_serialzed;
- uint32_t ns_end_serialized_size = 0;
- if (ns) {
- ns_end_serialized_size = ns->serialize_end(*stringpool,
- &ns_end_serialzed);
- fprintf(stderr, "Namespace end serialized to %i bytes\n",
- ns_end_serialized_size);
- }
- char* stringpool_serialized;
- uint32_t stringpool_serialized_size;
- stringpool_serialized_size = stringpool->serialize(&stringpool_serialized);
- fprintf(stderr, "Stringpool serialized to %i bytes\n",
- stringpool_serialized_size);
- uint32_t serialized_size = sizeof(ResChunk_header) + xml_serialized_size
- + stringpool_serialized_size + resource_map_size
- + ns_serialized_size + ns_end_serialized_size;
- fprintf(stderr, "Total size: %i bytes\n", serialized_size);
- ResChunk_header header;
- header.headerSize = sizeof(ResChunk_header);
- header.size = serialized_size;
- header.type = RES_XML_TYPE;
- fwrite(&header, sizeof(ResChunk_header), 1, out);
- fwrite(stringpool_serialized, stringpool_serialized_size, 1, out);
- fwrite(resource_map, resource_map_size, 1, out);
- fwrite(ns_serialzed, ns_serialized_size, 1, out);
- fwrite(xml_serialized, xml_serialized_size, 1, out);
- fwrite(ns_end_serialzed, ns_end_serialized_size, 1, out);
- fclose(out);
-
- stringpool->dump();
- free(xml_serialized);
- free(stringpool_serialized);
- free(ns_serialzed);
- free(data);
- free(resource_map);
- delete (stringpool);
- delete (ns);
- }
|