ResXMLTreeNode.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * ResXMLTreeNode.cpp
  3. *
  4. * Created on: May 26, 2018
  5. * Author: hp
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "android-xml.h"
  11. #include "ResXMLTreeNode.h"
  12. #include "XMLNameSpace.h"
  13. ResXMLTreeNode::ResXMLTreeNode(bool root) :
  14. _root(root) {
  15. }
  16. ResXMLTreeNode::ResXMLTreeNode(const ResStringPool& string_pool,
  17. const char* data) {
  18. ResXMLTree_node header;
  19. memcpy(&header, data, sizeof(ResChunk_header));
  20. ResXMLTree_attrExt attrs;
  21. memcpy(&attrs, data + header.header.headerSize, sizeof(ResXMLTree_attrExt));
  22. printf("AttributeStart: %i\n", attrs.attributeStart);
  23. printf("AttributeSize: %i\n", attrs.attributeSize);
  24. printf("AttributeCount: %i\n", attrs.attributeCount);
  25. _name = string_pool.get(attrs.name.index);
  26. _ns = string_pool.get(attrs.ns.index);
  27. for (int i = 0; i < attrs.attributeCount; ++i) {
  28. ResXMLTree_attribute attribute;
  29. memcpy(&attribute,
  30. data + header.header.headerSize + sizeof(ResXMLTree_attrExt)
  31. + (i * attrs.attributeSize),
  32. sizeof(ResXMLTree_attribute));
  33. ResXMLTreeNodeAttribute* parsed_attribute = new ResXMLTreeNodeAttribute;
  34. parsed_attribute->ns = string_pool.get(attribute.ns.index);
  35. parsed_attribute->name = string_pool.get(attribute.name.index);
  36. parsed_attribute->rawValue = string_pool.get(attribute.rawValue.index);
  37. parsed_attribute->typedValue = ResValue(string_pool,
  38. attribute.typedValue);
  39. add_attribute(parsed_attribute);
  40. }
  41. }
  42. void ResXMLTreeNode::add_attribute(ResXMLTreeNodeAttribute* attribute) {
  43. ++_num_attributes;
  44. _attributes = (ResXMLTreeNodeAttribute**) realloc(_attributes,
  45. _num_attributes * sizeof(ResXMLTreeNodeAttribute*));
  46. _attributes[_num_attributes - 1] = attribute;
  47. }
  48. void ResXMLTreeNode::add_child(ResXMLTreeNode* child) {
  49. ++_num_children;
  50. _children = (ResXMLTreeNode**) realloc(_children,
  51. _num_children * sizeof(ResXMLTreeNode*));
  52. _children[_num_children - 1] = child;
  53. child->_parent = this;
  54. }
  55. uint32_t ResXMLTreeNode::serialize(ResStringPool& string_pool, char** data) {
  56. uint32_t size = 0;
  57. // TODO this is kind of meh
  58. if (_root) {
  59. *data = (char*) malloc(0);
  60. } else {
  61. uint32_t datasize = sizeof(ResXMLTree_node)
  62. + sizeof(ResXMLTree_attrExt);
  63. *data = (char*) malloc(datasize);
  64. memset(*data, 0, datasize);
  65. uint32_t attributesStart = datasize;
  66. for (int i = 0; i < _num_attributes; ++i) {
  67. // TODO: HACK HACK HACK
  68. if (strcmp(_name, "uses-permission") == 0) {
  69. if (! (strncmp(_attributes[i]->rawValue, "android.", 7) == 0)
  70. || (strncmp(_attributes[i]->rawValue, "com.android", 11) == 0)) {
  71. printf("Skipping node due to godot permission\n");
  72. return 0;
  73. }
  74. }
  75. datasize += sizeof(ResXMLTree_attribute);
  76. *data = (char*) realloc(*data, datasize);
  77. memset(*data + datasize - sizeof(ResXMLTree_attribute), 0,
  78. sizeof(ResXMLTree_attribute));
  79. ResXMLTree_attribute* attribute =
  80. (ResXMLTree_attribute*) ((char*) *data + attributesStart
  81. + i * sizeof(ResXMLTree_attribute));
  82. attribute->name = string_pool.put(_attributes[i]->name);
  83. attribute->ns = string_pool.put(_attributes[i]->ns);
  84. attribute->rawValue = string_pool.put(_attributes[i]->rawValue);
  85. attribute->typedValue = _attributes[i]->typedValue.serialize(
  86. string_pool);
  87. }
  88. ResXMLTree_node* header = (ResXMLTree_node*) *data;
  89. ResXMLTree_attrExt* attrs = (ResXMLTree_attrExt*) ((char*) *data
  90. + sizeof(ResXMLTree_node));
  91. header->comment.index = -1;
  92. header->lineNumber = ++g_lineno;
  93. header->header.headerSize = sizeof(ResXMLTree_node);
  94. header->header.size = datasize;
  95. header->header.type = RES_XML_START_ELEMENT_TYPE;
  96. attrs->attributeCount = _num_attributes;
  97. // TODO what does this mean exactly?
  98. attrs->attributeStart = 20;
  99. attrs->attributeSize = sizeof(ResXMLTree_attribute);
  100. attrs->classIndex = 0;
  101. attrs->idIndex = 0;
  102. attrs->styleIndex = 0;
  103. attrs->name = string_pool.put(_name);
  104. attrs->ns = string_pool.put(_ns);
  105. size += datasize;
  106. }
  107. for (int i = 0; i < _num_children; ++i) {
  108. char* child;
  109. uint32_t child_size = 0;
  110. child_size = _children[i]->serialize(string_pool, &child);
  111. *data = (char*) realloc(*data, size + child_size);
  112. memcpy(*data + size, child, child_size);
  113. size += child_size;
  114. free(child);
  115. }
  116. if (!_root) {
  117. size += sizeof(ResXMLTree_node) + sizeof(ResXMLTree_endElementExt);
  118. *data = (char*) realloc(*data, size);
  119. ResXMLTree_node* header = (ResXMLTree_node*) ((char*) *data + size
  120. - sizeof(ResXMLTree_node) - sizeof(ResXMLTree_endElementExt));
  121. ResXMLTree_endElementExt* end_header =
  122. (ResXMLTree_endElementExt*) ((char*) *data + size
  123. - sizeof(ResXMLTree_endElementExt));
  124. header->comment.index = -1;
  125. header->lineNumber = ++g_lineno;
  126. header->header.headerSize = sizeof(ResXMLTree_node);
  127. header->header.size = sizeof(ResXMLTree_node)
  128. + sizeof(ResXMLTree_endElementExt);
  129. header->header.type = RES_XML_END_ELEMENT_TYPE;
  130. end_header->name = string_pool.put(_name);
  131. end_header->ns = string_pool.put(_ns);
  132. }
  133. return size;
  134. }
  135. void ResXMLTreeNode::dump(const XMLNameSpace* ns, bool ns_declared) {
  136. // Gross, sorry
  137. if (!_root) {
  138. if (!ns_declared)
  139. printf("<%s ", _name);
  140. else if (ns)
  141. printf("<%s xmlns:%s=\"%s\" ", _name, ns->_name, ns->_uri);
  142. for (int i = 0; i < _num_attributes; ++i) {
  143. if (_attributes[i]->ns && ns) {
  144. printf("%s:", ns->get(_attributes[i]->ns));
  145. }
  146. const char* typedValue = _attributes[i]->typedValue.to_string();
  147. printf("%s=\"%s\" ", _attributes[i]->name, typedValue);
  148. free((void*) typedValue);
  149. }
  150. if (!_num_children) {
  151. printf("/>\n");
  152. return;
  153. }
  154. printf(">\n");
  155. }
  156. for (int i = 0; i < _num_children; ++i) {
  157. _children[i]->dump(ns, _root);
  158. }
  159. if (!_root)
  160. printf("</%s>\n", _name);
  161. }
  162. ResXMLTreeNode::~ResXMLTreeNode() {
  163. for (int i = 0; i < _num_attributes; ++i) {
  164. delete _attributes[i];
  165. }
  166. free((void*) _attributes);
  167. for (int i = 0; i < _num_children; ++i) {
  168. delete _children[i];
  169. }
  170. free((void*) _children);
  171. }