11 bool bmap_t::is_mapped_block(size_t index
) const
13 if (index
>= m_gap_begin
&& index
< m_gap_end
)
16 if (index
>= m_gap_end
&& index
< m_next_gap_begin
)
19 if (index
>= m_blk_count
)
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
)
31 if (index
>= m_gap_end
&& index
< m_next_gap_begin
)
34 m_gap_begin
= m_next_gap_begin
;
40 static bool parse_image_size(bmap_t
&bmap
, const tinyxml2::XMLElement
* elem
)
42 auto img_size
= elem
->Int64Text();
44 set_last_err_string("Invalid image size.");
47 bmap
.set_image_size(img_size
);
51 static bool parse_block_size(bmap_t
&bmap
, const tinyxml2::XMLElement
* elem
)
53 auto blk_size
= elem
->Int64Text();
55 set_last_err_string("Invalid block size.");
58 bmap
.set_block_size(blk_size
);
62 static bool parse_blocks_count(bmap_t
&bmap
, const tinyxml2::XMLElement
* elem
)
64 auto blk_count
= elem
->Int64Text();
66 set_last_err_string("Invalid blocks count.");
69 bmap
.set_blocks_count(blk_count
);
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")) {
80 std::string text
= ch
->GetText();
82 auto f
= std::strtoul(text
.data(), nullptr, 0);
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
);
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
)
105 nt
.type
= uuu_notify::NOTIFY_CMD_INFO
;
106 nt
.str
= (char*)msg
.c_str();
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) {
118 auto dbuf
= fbuf
->request_data(0, fbuf
->size());
119 if (dbuf
== nullptr) {
123 auto err
= doc
.Parse((char*)dbuf
->data(), dbuf
->size());
124 if (err
!= tinyxml2::XML_SUCCESS
) {
128 auto elem
= doc
.FirstChildElement();
131 set_last_err_string("No bmap element");
136 if (!elem
->Attribute("version", "2.0")) {
137 set_last_err_string("Invalid bmap version. 2.0 is expected.");
142 for (auto ch
= elem
->FirstChildElement(); ch
!= nullptr; ch
= ch
->NextSiblingElement()) {
143 auto it
= handlers
.find(ch
->Name());
144 if (it
== handlers
.end())
146 if (!it
->second(bmap
, ch
))
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()) +
156 for (auto& r
: bmap
.mapped_ranges()) {
157 if (r
.first
== r
.second
)
158 info
+= "\n Range: " + std::to_string(r
.first
);
160 info
+= "\n Range: " + std::to_string(r
.first
) +
161 "-" + std::to_string(r
.second
);
163 send_info(info
+ "\n");