fix 'ret' have not initialized
[mfgtools.git] / libuuu / bmap.cpp
blob1ee2d1093f599b6a3282a7a7de39fe56d840bca1
1 #include <map>
2 #include <tinyxml2.h>
4 #include "bmap.h"
5 #include "buffer.h"
6 #include "libcomm.h"
7 #include "libuuu.h"
9 extern int g_verbose;
11 bool bmap_t::is_mapped_block(size_t index) const
13 if (index >= m_gap_begin && index < m_gap_end)
14 return false;
16 if (index >= m_gap_end && index < m_next_gap_begin)
17 return true;
19 if (index >= m_blk_count)
20 return false;
22 m_gap_begin = 0;
24 for(auto iter = m_blk_map.begin(); iter != m_blk_map.end(); ++iter) {
25 m_gap_end = iter->first;
26 m_next_gap_begin = iter->second + 1;
28 if (index >= m_gap_begin && index < m_gap_end)
29 return false;
31 if (index >= m_gap_end && index < m_next_gap_begin)
32 return true;
34 m_gap_begin = m_next_gap_begin;
37 return true;
40 static bool parse_image_size(bmap_t &bmap, const tinyxml2::XMLElement* elem)
42 auto img_size = elem->Int64Text();
43 if (img_size <= 0) {
44 set_last_err_string("Invalid image size.");
45 return false;
47 bmap.set_image_size(img_size);
48 return true;
51 static bool parse_block_size(bmap_t &bmap, const tinyxml2::XMLElement* elem)
53 auto blk_size = elem->Int64Text();
54 if (blk_size <= 0) {
55 set_last_err_string("Invalid block size.");
56 return false;
58 bmap.set_block_size(blk_size);
59 return true;
62 static bool parse_blocks_count(bmap_t &bmap, const tinyxml2::XMLElement* elem)
64 auto blk_count = elem->Int64Text();
65 if (blk_count <= 0) {
66 set_last_err_string("Invalid blocks count.");
67 return false;
69 bmap.set_blocks_count(blk_count);
70 return true;
73 static bool parse_block_map(bmap_t &bmap, const tinyxml2::XMLElement* elem)
75 for (auto ch = elem->FirstChildElement(); ch != nullptr; ch = ch->NextSiblingElement()) {
76 if (strcmp(ch->Name(), "Range")) {
77 continue;
80 std::string text = ch->GetText();
82 auto f = std::strtoul(text.data(), nullptr, 0);
83 auto l = f;
85 auto pos = text.find('-');
86 if (pos != std::string::npos)
87 l = std::strtoul(text.data() + pos + 1, nullptr, 0);
89 bmap.set_mapped_range(f, l);
92 return true;
95 static const std::map<std::string, bool (*)(bmap_t &, const tinyxml2::XMLElement*)> handlers{
96 { "ImageSize", parse_image_size },
97 { "BlockSize", parse_block_size },
98 { "BlocksCount", parse_blocks_count },
99 { "BlockMap", parse_block_map },
102 void send_info(std::string msg)
104 uuu_notify nt;
105 nt.type = uuu_notify::NOTIFY_CMD_INFO;
106 nt.str = (char*)msg.c_str();
107 call_notify(nt);
110 bool load_bmap(const std::string& filename, bmap_t& bmap)
112 tinyxml2::XMLDocument doc;
113 auto fbuf = get_file_buffer(filename, true);
114 if (fbuf == nullptr) {
115 return -1;
118 auto dbuf = fbuf->request_data(0, fbuf->size());
119 if (dbuf == nullptr) {
120 return -1;
123 auto err = doc.Parse((char*)dbuf->data(), dbuf->size());
124 if (err != tinyxml2::XML_SUCCESS) {
125 return -1;
128 auto elem = doc.FirstChildElement();
130 if (!elem) {
131 set_last_err_string("No bmap element");
132 return -1;
135 if (elem) {
136 if (!elem->Attribute("version", "2.0")) {
137 set_last_err_string("Invalid bmap version. 2.0 is expected.");
138 return -1;
142 for (auto ch = elem->FirstChildElement(); ch != nullptr; ch = ch->NextSiblingElement()) {
143 auto it = handlers.find(ch->Name());
144 if (it == handlers.end())
145 continue;
146 if (!it->second(bmap, ch))
147 return -1;
150 if (g_verbose) {
151 auto info = std::string("\nUsing block map:") +
152 "\n ImageSize: " + std::to_string(bmap.image_size()) +
153 "\n BlockSize: " + std::to_string(bmap.block_size()) +
154 "\n BlocksCount: " + std::to_string(bmap.blocks_count()) +
155 "\n BlockMap:";
156 for (auto& r: bmap.mapped_ranges()) {
157 if (r.first == r.second)
158 info += "\n Range: " + std::to_string(r.first);
159 else
160 info += "\n Range: " + std::to_string(r.first) +
161 "-" + std::to_string(r.second);
163 send_info(info + "\n");
166 return true;