Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e18eb508 authored by Doug Zongker's avatar Doug Zongker Committed by Baligh Uddin
Browse files

add support for the 'fill' chunk type to sparse_img

Bug: 17987996
Change-Id: Ia661e87877e52274a991ceb77bbed93b7e6218f2
(cherry picked from commit 629c7cc8)
parent c70ae578
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -77,12 +77,16 @@ class SparseImage(object):
        else:
          care_data.append(pos)
          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
          f.seek(data_sz, os.SEEK_CUR)

      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:
        if data_sz != 0:
@@ -130,24 +134,29 @@ class SparseImage(object):
    for s, e in ranges:
      to_read = e-s
      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.
      p = filepos + ((s - chunk_start) * self.blocksize)
      remain = chunk_len - (s - chunk_start)

      f.seek(p, os.SEEK_SET)
      this_read = min(remain, to_read)
      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

      while to_read > 0:
        # continue with following chunks if this range spans multiple chunks.
        idx += 1
        chunk_start, chunk_len, filepos = self.offset_map[idx]
        f.seek(filepos, os.SEEK_SET)
        chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
        this_read = min(chunk_len, to_read)
        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

  def LoadFileBlockMap(self, fn):
@@ -177,10 +186,16 @@ class SparseImage(object):
    for s, e in remaining:
      for b in range(s, e):
        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]
        if filepos is not None:
          filepos += (b-chunk_start) * 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:
          zero_blocks.append(b)