///|
fn patch_kind_name(kind : PatchKind) -> String {
match kind {
PatchAdd => "add"
PatchRemove => "remove"
PatchReplace => "replace"
}
}
///|
fn join_region_names(names : Array[String]) -> String {
let mut result = ""
for index, name in names {
if index > 0 {
result = result + ","
}
result = result + name
}
if result.length() == 0 {
"unmapped"
} else {
result
}
}
///|
pub fn render_layout_text(layout : ImageLayout) -> String {
let mut result = "firmware-layout segments=" +
layout.segment_count().to_string() +
" mapped-bytes=" +
layout.mapped_bytes().to_string() +
" unmapped-bytes=" +
layout.unmapped_bytes().to_string() +
" fully-mapped=" +
layout.fully_mapped_segments().to_string() +
" partially-mapped=" +
layout.partially_mapped_segments().to_string() +
" unmapped=" +
layout.unmapped_segments().to_string()
match layout.entry_region() {
Some(value) => result = result + " entry-region=" + value
None => ()
}
for placement in layout.placements() {
result = result +
"\nsegment start=" +
hex_address(placement.start()) +
" end=" +
hex_address(placement.end_exclusive()) +
" mapped=" +
placement.mapped_bytes().to_string() +
" unmapped=" +
placement.unmapped_bytes().to_string() +
" regions=" +
join_region_names(placement.region_names())
}
result
}
///|
pub fn render_layout_json(layout : ImageLayout) -> String {
let placements : Array[Json] = []
for placement in layout.placements() {
let regions : Array[Json] = []
for name in placement.region_names() {
regions.push(Json::string(name))
}
placements.push(
Json::object({
"start": Json::string(hex_address(placement.start())),
"end_exclusive": Json::string(hex_address(placement.end_exclusive())),
"mapped_bytes": Json::string(placement.mapped_bytes().to_string()),
"unmapped_bytes": Json::string(placement.unmapped_bytes().to_string()),
"regions": Json::array(regions),
}),
)
}
Json::object({
"type": Json::string("firmware_image_layout"),
"accepted": Json::boolean(layout.accepted()),
"segment_count": Json::number(layout.segment_count().to_double()),
"mapped_bytes": Json::string(layout.mapped_bytes().to_string()),
"unmapped_bytes": Json::string(layout.unmapped_bytes().to_string()),
"fully_mapped_segments": Json::number(
layout.fully_mapped_segments().to_double(),
),
"partially_mapped_segments": Json::number(
layout.partially_mapped_segments().to_double(),
),
"unmapped_segments": Json::number(layout.unmapped_segments().to_double()),
"entry_region": match layout.entry_region() {
Some(value) => Json::string(value)
None => Json::null()
},
"placements": Json::array(placements),
}).stringify()
}
///|
pub fn render_patch_text(patch : ImagePatch) -> String {
let mut result = "firmware-patch hunks=" +
patch.hunks().length().to_string() +
" added=" +
patch.added_bytes().to_string() +
" removed=" +
patch.removed_bytes().to_string() +
" changed=" +
patch.changed_bytes().to_string()
for hunk in patch.hunks() {
result = result +
"\n" +
patch_kind_name(hunk.kind()) +
" address=" +
hex_address(hunk.address()) +
" before=" +
encode_hex_bytes(hunk.before()) +
" after=" +
encode_hex_bytes(hunk.after())
}
result
}
///|
pub fn render_patch_json(patch : ImagePatch) -> String {
let hunks : Array[Json] = []
for hunk in patch.hunks() {
hunks.push(
Json::object({
"kind": Json::string(patch_kind_name(hunk.kind())),
"address": Json::string(hex_address(hunk.address())),
"length": Json::number(hunk.length().to_double()),
"before": Json::string(encode_hex_bytes(hunk.before())),
"after": Json::string(encode_hex_bytes(hunk.after())),
}),
)
}
Json::object({
"type": Json::string("firmware_image_patch"),
"old_entry": optional_address_json(patch.old_entry()),
"new_entry": optional_address_json(patch.new_entry()),
"added_bytes": Json::number(patch.added_bytes().to_double()),
"removed_bytes": Json::number(patch.removed_bytes().to_double()),
"changed_bytes": Json::number(patch.changed_bytes().to_double()),
"hunks": Json::array(hunks),
}).stringify()
}