ip_table.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * ip_table.cpp
  3. *
  4. * Created on: 2022年3月10日
  5. * Author: pengzc
  6. */
  7. #include "ip_table.h"
  8. #include <zlib.h>
  9. #include <string>
  10. #include <vector>
  11. #include <functional>
  12. #include "rapidxml/rapidxml.hpp"
  13. #include "rapidxml/rapidxml_print.hpp"
  14. #include "utils/Log.h"
  15. #include "base/files.hpp"
  16. const char* IP_TABLE_FILE = "/data/ip_table.zip";
  17. #define XMLAppendNode(doc, name, text) { \
  18. xml_node<> *child = doc.allocate_node(node_element, doc.allocate_string(name), doc.allocate_string(text));\
  19. root->append_node(child);\
  20. }
  21. namespace i {
  22. static int Compress(const std::string& source, std::string* dest) {
  23. if (dest == NULL) {
  24. return -1;
  25. }
  26. dest->resize(source.size());
  27. uLongf dest_len = source.size();
  28. int ret = compress((Bytef*) dest->data(), &dest_len, (Bytef*) source.data(),
  29. (uLongf) source.size());
  30. if (ret != Z_OK) {
  31. dest->clear();
  32. return ret;
  33. }
  34. dest->resize(dest_len);
  35. return 0;
  36. }
  37. static int Uncompress(const std::string& source, std::string* dest) {
  38. if (dest == NULL) {
  39. return -1;
  40. }
  41. //最大支持512K
  42. dest->resize(1024 * 512);
  43. uLongf dest_len = dest->size();
  44. int ret = uncompress((Bytef*)dest->data(), &dest_len, (Bytef*)source.data(), (uLong)source.size());
  45. if (ret != Z_OK) {
  46. dest->clear();
  47. return ret;
  48. }
  49. dest->resize(dest_len);
  50. return 0;
  51. }
  52. int IpTable::Load(std::string* xml) {
  53. if (xml == NULL) {
  54. return -1;
  55. }
  56. std::string content = base::read_all(IP_TABLE_FILE);
  57. if (content.empty()) {
  58. LOGE("%s empty", IP_TABLE_FILE);
  59. return -1;
  60. }
  61. int ret = Uncompress(content, xml);
  62. if (ret != 0) {
  63. LOGD("uncompress error, %d", ret);
  64. return -1;
  65. }
  66. return 0;
  67. }
  68. static int WalkIpTable(std::function<int (rapidxml::xml_node<>* node)> func) {
  69. std::string xml;
  70. if (IpTable::Load(&xml) != 0) {
  71. return -1;
  72. }
  73. rapidxml::xml_document<> doc; // character type defaults to char
  74. doc.parse<0>((char*)xml.c_str()); // 0 means default parse flags
  75. rapidxml::xml_node<>* node = doc.first_node("map");
  76. if (node == NULL) {
  77. return -1;
  78. }
  79. node = node->first_node();
  80. if (node == NULL) {
  81. return -1;
  82. }
  83. do {
  84. if (func(node) != 0) {
  85. break;
  86. }
  87. } while ((node = node->next_sibling()) != NULL);
  88. return 0;
  89. }
  90. static int GetFirstNodeValue(rapidxml::xml_node<>* parent,
  91. const char* node_name, std::string* value) {
  92. if (parent == NULL) {
  93. return -1;
  94. }
  95. if (node_name == NULL) {
  96. return -1;
  97. }
  98. if (value == NULL) {
  99. return -1;
  100. }
  101. rapidxml::xml_node<>* node = parent->first_node(node_name);
  102. if (node == NULL) {
  103. return -1;
  104. }
  105. value->assign(node->value(), node->value_size());
  106. return 0;
  107. }
  108. int IpTable::Update(const std::string& map_xml) {
  109. if (map_xml.size() <= 0) {
  110. return -1;
  111. }
  112. std::string dest_xml;
  113. int ret = Compress(map_xml, &dest_xml);
  114. if (ret != 0) {
  115. LOGD("compress error, %d", ret);
  116. return -1;
  117. }
  118. LOGD("compressed %d bytes", dest_xml.size());
  119. return base::write_all(IP_TABLE_FILE, dest_xml) ? 0 : -1;
  120. }
  121. int IpTable::GetExtension(int building, int unit, int number, int extension,
  122. NetworkProfile* profile) {
  123. if (profile == NULL) {
  124. return -1;
  125. }
  126. bool find = false;
  127. WalkIpTable([building, unit, number, extension, profile, &find](rapidxml::xml_node<>* node) -> int {
  128. if (strcmp("item", node->name()) != 0) {
  129. return 0;
  130. }
  131. if (GetFirstNodeValue(node, "name", &profile->name) != 0) {
  132. return 0;
  133. }
  134. if (4 != sscanf(profile->name.c_str(), "%d栋%d单元%d室%d号分机",
  135. &profile->building, &profile->unit,
  136. &profile->number, &profile->extension)) {
  137. return 0;
  138. }
  139. if (profile->building != building
  140. || profile->unit != unit
  141. || profile->number != number
  142. || profile->extension != extension) {
  143. return 0;
  144. }
  145. if (GetFirstNodeValue(node, "code", &profile->code) != 0) {
  146. return 0;
  147. }
  148. if (GetFirstNodeValue(node, "ip", &profile->ipv4) != 0) {
  149. return 0;
  150. }
  151. if (GetFirstNodeValue(node, "gate", &profile->gateway) != 0) {
  152. return 0;
  153. }
  154. if (GetFirstNodeValue(node, "mask", &profile->sub_network_mask) != 0) {
  155. return 0;
  156. }
  157. find = true;
  158. return 1; //stop walk;
  159. });
  160. return find ? 0 : 404;
  161. }
  162. int IpTable::GetGate(int building, int unit, NetworkProfile* profile) {
  163. if (profile == NULL) {
  164. return -1;
  165. }
  166. bool find = false;
  167. WalkIpTable([profile, building, unit, &find](rapidxml::xml_node<>* node) -> int {
  168. if (strcmp("item", node->name()) != 0) {
  169. return 0;
  170. }
  171. if (GetFirstNodeValue(node, "name", &profile->name) != 0) {
  172. return 0;
  173. }
  174. if (2 != sscanf(profile->name.c_str(), "%d栋%d单元$",
  175. &profile->building, &profile->unit)) {
  176. return 0;
  177. }
  178. if (profile->building != building
  179. || profile->unit != unit) {
  180. return 0;
  181. }
  182. if (GetFirstNodeValue(node, "code", &profile->code) != 0) {
  183. return 0;
  184. }
  185. if (GetFirstNodeValue(node, "ip", &profile->ipv4) != 0) {
  186. return 0;
  187. }
  188. if (GetFirstNodeValue(node, "gate", &profile->gateway) != 0) {
  189. return 0;
  190. }
  191. if (GetFirstNodeValue(node, "mask", &profile->sub_network_mask) != 0) {
  192. return 0;
  193. }
  194. find = true;
  195. return 1; //stop walk;
  196. });
  197. return find ? 0 : 404;
  198. }
  199. std::string IpTable::GetVersion() {
  200. std::string ver;
  201. WalkIpTable([&ver](rapidxml::xml_node<>* node) -> int {
  202. if (strcmp("mapver", node->name()) != 0) {
  203. return 0;
  204. }
  205. if (GetFirstNodeValue(node, "ver", &ver) != 0) {
  206. return 0;
  207. }
  208. return 1; //stop walk;
  209. });
  210. return ver;
  211. }
  212. IpTable::IpTable() {
  213. // TODO 自动生成的构造函数存根
  214. }
  215. IpTable::~IpTable() {
  216. // TODO 自动生成的析构函数存根
  217. }
  218. } /* namespace i */