123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * ResXMLTreeNode.cpp
- *
- * Created on: May 26, 2018
- * Author: hp
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "android-xml.h"
- #include "ResXMLTreeNode.h"
- #include "XMLNameSpace.h"
- ResXMLTreeNode::ResXMLTreeNode(bool root) :
- _root(root) {
- }
- ResXMLTreeNode::ResXMLTreeNode(const ResStringPool& string_pool,
- const char* data) {
- ResXMLTree_node header;
- memcpy(&header, data, sizeof(ResChunk_header));
- ResXMLTree_attrExt attrs;
- memcpy(&attrs, data + header.header.headerSize, sizeof(ResXMLTree_attrExt));
- printf("AttributeStart: %i\n", attrs.attributeStart);
- printf("AttributeSize: %i\n", attrs.attributeSize);
- printf("AttributeCount: %i\n", attrs.attributeCount);
- _name = string_pool.get(attrs.name.index);
- _ns = string_pool.get(attrs.ns.index);
- for (int i = 0; i < attrs.attributeCount; ++i) {
- ResXMLTree_attribute attribute;
- memcpy(&attribute,
- data + header.header.headerSize + sizeof(ResXMLTree_attrExt)
- + (i * attrs.attributeSize),
- sizeof(ResXMLTree_attribute));
- ResXMLTreeNodeAttribute* parsed_attribute = new ResXMLTreeNodeAttribute;
- parsed_attribute->ns = string_pool.get(attribute.ns.index);
- parsed_attribute->name = string_pool.get(attribute.name.index);
- parsed_attribute->rawValue = string_pool.get(attribute.rawValue.index);
- parsed_attribute->typedValue = ResValue(string_pool,
- attribute.typedValue);
- add_attribute(parsed_attribute);
- }
- }
- void ResXMLTreeNode::add_attribute(ResXMLTreeNodeAttribute* attribute) {
- ++_num_attributes;
- _attributes = (ResXMLTreeNodeAttribute**) realloc(_attributes,
- _num_attributes * sizeof(ResXMLTreeNodeAttribute*));
- _attributes[_num_attributes - 1] = attribute;
- }
- void ResXMLTreeNode::add_child(ResXMLTreeNode* child) {
- ++_num_children;
- _children = (ResXMLTreeNode**) realloc(_children,
- _num_children * sizeof(ResXMLTreeNode*));
- _children[_num_children - 1] = child;
- child->_parent = this;
- }
- uint32_t ResXMLTreeNode::serialize(ResStringPool& string_pool, char** data) {
- uint32_t size = 0;
- // TODO this is kind of meh
- if (_root) {
- *data = (char*) malloc(0);
- } else {
- uint32_t datasize = sizeof(ResXMLTree_node)
- + sizeof(ResXMLTree_attrExt);
- *data = (char*) malloc(datasize);
- memset(*data, 0, datasize);
- uint32_t attributesStart = datasize;
- for (int i = 0; i < _num_attributes; ++i) {
- // TODO: HACK HACK HACK
- if (strcmp(_name, "uses-permission") == 0) {
- if (! (strncmp(_attributes[i]->rawValue, "android.", 7) == 0)
- || (strncmp(_attributes[i]->rawValue, "com.android", 11) == 0)) {
- printf("Skipping node due to godot permission\n");
- return 0;
- }
- }
- datasize += sizeof(ResXMLTree_attribute);
- *data = (char*) realloc(*data, datasize);
- memset(*data + datasize - sizeof(ResXMLTree_attribute), 0,
- sizeof(ResXMLTree_attribute));
- ResXMLTree_attribute* attribute =
- (ResXMLTree_attribute*) ((char*) *data + attributesStart
- + i * sizeof(ResXMLTree_attribute));
- attribute->name = string_pool.put(_attributes[i]->name);
- attribute->ns = string_pool.put(_attributes[i]->ns);
- attribute->rawValue = string_pool.put(_attributes[i]->rawValue);
- attribute->typedValue = _attributes[i]->typedValue.serialize(
- string_pool);
- }
- ResXMLTree_node* header = (ResXMLTree_node*) *data;
- ResXMLTree_attrExt* attrs = (ResXMLTree_attrExt*) ((char*) *data
- + sizeof(ResXMLTree_node));
- header->comment.index = -1;
- header->lineNumber = ++g_lineno;
- header->header.headerSize = sizeof(ResXMLTree_node);
- header->header.size = datasize;
- header->header.type = RES_XML_START_ELEMENT_TYPE;
- attrs->attributeCount = _num_attributes;
- // TODO what does this mean exactly?
- attrs->attributeStart = 20;
- attrs->attributeSize = sizeof(ResXMLTree_attribute);
- attrs->classIndex = 0;
- attrs->idIndex = 0;
- attrs->styleIndex = 0;
- attrs->name = string_pool.put(_name);
- attrs->ns = string_pool.put(_ns);
- size += datasize;
- }
- for (int i = 0; i < _num_children; ++i) {
- char* child;
- uint32_t child_size = 0;
- child_size = _children[i]->serialize(string_pool, &child);
- *data = (char*) realloc(*data, size + child_size);
- memcpy(*data + size, child, child_size);
- size += child_size;
- free(child);
- }
- if (!_root) {
- size += sizeof(ResXMLTree_node) + sizeof(ResXMLTree_endElementExt);
- *data = (char*) realloc(*data, size);
- ResXMLTree_node* header = (ResXMLTree_node*) ((char*) *data + size
- - sizeof(ResXMLTree_node) - sizeof(ResXMLTree_endElementExt));
- ResXMLTree_endElementExt* end_header =
- (ResXMLTree_endElementExt*) ((char*) *data + size
- - sizeof(ResXMLTree_endElementExt));
- header->comment.index = -1;
- header->lineNumber = ++g_lineno;
- header->header.headerSize = sizeof(ResXMLTree_node);
- header->header.size = sizeof(ResXMLTree_node)
- + sizeof(ResXMLTree_endElementExt);
- header->header.type = RES_XML_END_ELEMENT_TYPE;
- end_header->name = string_pool.put(_name);
- end_header->ns = string_pool.put(_ns);
- }
- return size;
- }
- void ResXMLTreeNode::dump(const XMLNameSpace* ns, bool ns_declared) {
- // Gross, sorry
- if (!_root) {
- if (!ns_declared)
- printf("<%s ", _name);
- else if (ns)
- printf("<%s xmlns:%s=\"%s\" ", _name, ns->_name, ns->_uri);
- for (int i = 0; i < _num_attributes; ++i) {
- if (_attributes[i]->ns && ns) {
- printf("%s:", ns->get(_attributes[i]->ns));
- }
- const char* typedValue = _attributes[i]->typedValue.to_string();
- printf("%s=\"%s\" ", _attributes[i]->name, typedValue);
- free((void*) typedValue);
- }
- if (!_num_children) {
- printf("/>\n");
- return;
- }
- printf(">\n");
- }
- for (int i = 0; i < _num_children; ++i) {
- _children[i]->dump(ns, _root);
- }
- if (!_root)
- printf("</%s>\n", _name);
- }
- ResXMLTreeNode::~ResXMLTreeNode() {
- for (int i = 0; i < _num_attributes; ++i) {
- delete _attributes[i];
- }
- free((void*) _attributes);
- for (int i = 0; i < _num_children; ++i) {
- delete _children[i];
- }
- free((void*) _children);
- }
|