123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /*
- * ip_table.cpp
- *
- * Created on: 2022年3月10日
- * Author: pengzc
- */
- #include "ip_table.h"
- #include <zlib.h>
- #include <string>
- #include <vector>
- #include <functional>
- #include "rapidxml/rapidxml.hpp"
- #include "rapidxml/rapidxml_print.hpp"
- #include "utils/Log.h"
- #include "base/files.hpp"
- const char* IP_TABLE_FILE = "/data/ip_table.zip";
- #define XMLAppendNode(doc, name, text) { \
- xml_node<> *child = doc.allocate_node(node_element, doc.allocate_string(name), doc.allocate_string(text));\
- root->append_node(child);\
- }
- namespace i {
- static int Compress(const std::string& source, std::string* dest) {
- if (dest == NULL) {
- return -1;
- }
- dest->resize(source.size());
- uLongf dest_len = source.size();
- int ret = compress((Bytef*) dest->data(), &dest_len, (Bytef*) source.data(),
- (uLongf) source.size());
- if (ret != Z_OK) {
- dest->clear();
- return ret;
- }
- dest->resize(dest_len);
- return 0;
- }
- static int Uncompress(const std::string& source, std::string* dest) {
- if (dest == NULL) {
- return -1;
- }
- //最大支持512K
- dest->resize(1024 * 512);
- uLongf dest_len = dest->size();
- int ret = uncompress((Bytef*)dest->data(), &dest_len, (Bytef*)source.data(), (uLong)source.size());
- if (ret != Z_OK) {
- dest->clear();
- return ret;
- }
- dest->resize(dest_len);
- return 0;
- }
- int IpTable::Load(std::string* xml) {
- if (xml == NULL) {
- return -1;
- }
- std::string content = base::read_all(IP_TABLE_FILE);
- if (content.empty()) {
- LOGE("%s empty", IP_TABLE_FILE);
- return -1;
- }
- int ret = Uncompress(content, xml);
- if (ret != 0) {
- LOGD("uncompress error, %d", ret);
- return -1;
- }
- return 0;
- }
- static int WalkIpTable(std::function<int (rapidxml::xml_node<>* node)> func) {
- std::string xml;
- if (IpTable::Load(&xml) != 0) {
- return -1;
- }
- rapidxml::xml_document<> doc; // character type defaults to char
- doc.parse<0>((char*)xml.c_str()); // 0 means default parse flags
- rapidxml::xml_node<>* node = doc.first_node("map");
- if (node == NULL) {
- return -1;
- }
- node = node->first_node();
- if (node == NULL) {
- return -1;
- }
- do {
- if (func(node) != 0) {
- break;
- }
- } while ((node = node->next_sibling()) != NULL);
- return 0;
- }
- static int GetFirstNodeValue(rapidxml::xml_node<>* parent,
- const char* node_name, std::string* value) {
- if (parent == NULL) {
- return -1;
- }
- if (node_name == NULL) {
- return -1;
- }
- if (value == NULL) {
- return -1;
- }
- rapidxml::xml_node<>* node = parent->first_node(node_name);
- if (node == NULL) {
- return -1;
- }
- value->assign(node->value(), node->value_size());
- return 0;
- }
- int IpTable::Update(const std::string& map_xml) {
- if (map_xml.size() <= 0) {
- return -1;
- }
- std::string dest_xml;
- int ret = Compress(map_xml, &dest_xml);
- if (ret != 0) {
- LOGD("compress error, %d", ret);
- return -1;
- }
- LOGD("compressed %d bytes", dest_xml.size());
- return base::write_all(IP_TABLE_FILE, dest_xml) ? 0 : -1;
- }
- int IpTable::GetExtension(int building, int unit, int number, int extension,
- NetworkProfile* profile) {
- if (profile == NULL) {
- return -1;
- }
- bool find = false;
- WalkIpTable([building, unit, number, extension, profile, &find](rapidxml::xml_node<>* node) -> int {
- if (strcmp("item", node->name()) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "name", &profile->name) != 0) {
- return 0;
- }
- if (4 != sscanf(profile->name.c_str(), "%d栋%d单元%d室%d号分机",
- &profile->building, &profile->unit,
- &profile->number, &profile->extension)) {
- return 0;
- }
- if (profile->building != building
- || profile->unit != unit
- || profile->number != number
- || profile->extension != extension) {
- return 0;
- }
- if (GetFirstNodeValue(node, "code", &profile->code) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "ip", &profile->ipv4) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "gate", &profile->gateway) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "mask", &profile->sub_network_mask) != 0) {
- return 0;
- }
- find = true;
- return 1; //stop walk;
- });
- return find ? 0 : 404;
- }
- int IpTable::GetGate(int building, int unit, NetworkProfile* profile) {
- if (profile == NULL) {
- return -1;
- }
- bool find = false;
- WalkIpTable([profile, building, unit, &find](rapidxml::xml_node<>* node) -> int {
- if (strcmp("item", node->name()) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "name", &profile->name) != 0) {
- return 0;
- }
- if (2 != sscanf(profile->name.c_str(), "%d栋%d单元$",
- &profile->building, &profile->unit)) {
- return 0;
- }
- if (profile->building != building
- || profile->unit != unit) {
- return 0;
- }
- if (GetFirstNodeValue(node, "code", &profile->code) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "ip", &profile->ipv4) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "gate", &profile->gateway) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "mask", &profile->sub_network_mask) != 0) {
- return 0;
- }
- find = true;
- return 1; //stop walk;
- });
- return find ? 0 : 404;
- }
- std::string IpTable::GetVersion() {
- std::string ver;
- WalkIpTable([&ver](rapidxml::xml_node<>* node) -> int {
- if (strcmp("mapver", node->name()) != 0) {
- return 0;
- }
- if (GetFirstNodeValue(node, "ver", &ver) != 0) {
- return 0;
- }
- return 1; //stop walk;
- });
- return ver;
- }
- IpTable::IpTable() {
- // TODO 自动生成的构造函数存根
- }
- IpTable::~IpTable() {
- // TODO 自动生成的析构函数存根
- }
- } /* namespace i */
|