add support for the 'fill' chunk type to sparse_img

Change-Id: Ia661e87877e52274a991ceb77bbed93b7e6218f2
This commit is contained in:
Doug Zongker 2014-10-15 15:55:50 -07:00
parent decb2fb4d4
commit 629c7cc84d

View file

@ -77,12 +77,16 @@ class SparseImage(object):
else: else:
care_data.append(pos) care_data.append(pos)
care_data.append(pos + chunk_sz) care_data.append(pos + chunk_sz)
offset_map.append((pos, chunk_sz, f.tell())) offset_map.append((pos, chunk_sz, f.tell(), None))
pos += chunk_sz pos += chunk_sz
f.seek(data_sz, os.SEEK_CUR) f.seek(data_sz, os.SEEK_CUR)
elif chunk_type == 0xCAC2: elif chunk_type == 0xCAC2:
raise ValueError("Fill chunks are not supported") fill_data = f.read(4)
care_data.append(pos)
care_data.append(pos + chunk_sz)
offset_map.append((pos, chunk_sz, None, fill_data))
pos += chunk_sz
elif chunk_type == 0xCAC3: elif chunk_type == 0xCAC3:
if data_sz != 0: if data_sz != 0:
@ -130,24 +134,29 @@ class SparseImage(object):
for s, e in ranges: for s, e in ranges:
to_read = e-s to_read = e-s
idx = bisect.bisect_right(self.offset_index, s) - 1 idx = bisect.bisect_right(self.offset_index, s) - 1
chunk_start, chunk_len, filepos = self.offset_map[idx] chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
# for the first chunk we may be starting partway through it. # for the first chunk we may be starting partway through it.
p = filepos + ((s - chunk_start) * self.blocksize)
remain = chunk_len - (s - chunk_start) remain = chunk_len - (s - chunk_start)
f.seek(p, os.SEEK_SET)
this_read = min(remain, to_read) this_read = min(remain, to_read)
yield f.read(this_read * self.blocksize) if filepos is not None:
p = filepos + ((s - chunk_start) * self.blocksize)
f.seek(p, os.SEEK_SET)
yield f.read(this_read * self.blocksize)
else:
yield fill_data * (this_read * (self.blocksize >> 2))
to_read -= this_read to_read -= this_read
while to_read > 0: while to_read > 0:
# continue with following chunks if this range spans multiple chunks. # continue with following chunks if this range spans multiple chunks.
idx += 1 idx += 1
chunk_start, chunk_len, filepos = self.offset_map[idx] chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
f.seek(filepos, os.SEEK_SET)
this_read = min(chunk_len, to_read) this_read = min(chunk_len, to_read)
yield f.read(this_read * self.blocksize) if filepos is not None:
f.seek(filepos, os.SEEK_SET)
yield f.read(this_read * self.blocksize)
else:
yield fill_data * (this_read * (self.blocksize >> 2))
to_read -= this_read to_read -= this_read
def LoadFileBlockMap(self, fn): def LoadFileBlockMap(self, fn):
@ -177,10 +186,16 @@ class SparseImage(object):
for s, e in remaining: for s, e in remaining:
for b in range(s, e): for b in range(s, e):
idx = bisect.bisect_right(self.offset_index, b) - 1 idx = bisect.bisect_right(self.offset_index, b) - 1
chunk_start, chunk_len, filepos = self.offset_map[idx] chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
filepos += (b-chunk_start) * self.blocksize if filepos is not None:
f.seek(filepos, os.SEEK_SET) filepos += (b-chunk_start) * self.blocksize
data = f.read(self.blocksize) f.seek(filepos, os.SEEK_SET)
data = f.read(self.blocksize)
else:
if fill_data == reference[:4]: # fill with all zeros
data = reference
else:
data = None
if data == reference: if data == reference:
zero_blocks.append(b) zero_blocks.append(b)