/* * ip_table.cpp * * Created on: 2022年3月10日 * Author: pengzc */ #include "ip_table.h" #include #include #include #include #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* 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 */