File: bmap_write.py

package info (click to toggle)
bmap-tools 3.9.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 760 kB
  • sloc: python: 5,822; sh: 105; makefile: 2
file content (70 lines) | stat: -rwxr-xr-x 2,758 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/python

# A super-simple standalone script (works with both Python2 / Python3 and has
# no external dependencies) to show how easily .bmap files can be parsed.
# (Also demonstrates how little code it takes - which might be a useful starting
# point for other languages)
#
# This is effectively a minimal version of 'bmaptool copy'. It only supports
# uncompressed images, it does no verification, and if the image is named
# mydata.img it assumes the corresponding bmap is named mydata.bmap

#    Copyright (C) 2018  Andrew Scheller
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import sys
import xml.etree.ElementTree as ET
import re
import os

if len(sys.argv) != 3:
    print("Usage: %s <raw-file> <output-file>" % os.path.basename(sys.argv[0]))
    sys.exit(1)
raw_file = sys.argv[1]
output_file = sys.argv[2]
if not os.path.isfile(raw_file):
    print("raw-file '%s' doesn't exist" % raw_file)
    sys.exit(1)
file_root, file_ext = os.path.splitext(raw_file)
bmap_file = file_root + ".bmap"
if not os.path.isfile(bmap_file):
    print("bmap-file '%s' doesn't exist" % bmap_file)
    sys.exit(1)

bmap_root = ET.parse(bmap_file).getroot()
blocksize = int(bmap_root.find("BlockSize").text)
with open(raw_file, "rb") as filedata:
    with open(output_file, "wb") as outdata:
        try:
            outdata.truncate(int(bmap_root.find("ImageSize").text))  # optional
        except:
            pass
        for bmap_range in bmap_root.find("BlockMap").findall("Range"):
            blockrange = bmap_range.text
            m = re.match("^\s*(\d+)\s*-\s*(\d+)\s*$", blockrange)
            if m:
                start = int(m.group(1))
                end = int(m.group(2))
            else:
                start = int(blockrange)
                end = start
            start_offset = start * blocksize
            filedata.seek(start_offset, 0)
            outdata.seek(start_offset, 0)
            for i in range(end - start + 1):
                outdata.write(filedata.read(blocksize))
        outdata.flush()
        os.fsync(outdata.fileno())