| 138 | return _manifest |
| 139 | |
| 140 | def write(self, fp=None, compress=True): |
| 141 | body_bio = BytesIO() |
| 142 | |
| 143 | # set serialisation version based on enabled features or original version |
| 144 | target_version = max(self.default_serialisation_version, self.meta.feature_level) |
| 145 | if self.meta.data_version == 2: |
| 146 | target_version = max(21, target_version) |
| 147 | elif self.file_manifest_list.version == 2: |
| 148 | target_version = max(20, target_version) |
| 149 | elif self.file_manifest_list.version == 1: |
| 150 | target_version = max(19, target_version) |
| 151 | elif self.meta.data_version == 1: |
| 152 | target_version = max(18, target_version) |
| 153 | |
| 154 | # Downgrade manifest if unknown newer version |
| 155 | if target_version > 21: |
| 156 | logger.warning(f'Trying to serialise an unknown target version: {target_version},' |
| 157 | f'clamping to 21.') |
| 158 | target_version = 21 |
| 159 | |
| 160 | # Ensure metadata will be correct |
| 161 | self.meta.feature_level = target_version |
| 162 | |
| 163 | self.meta.write(body_bio) |
| 164 | self.chunk_data_list.write(body_bio) |
| 165 | self.file_manifest_list.write(body_bio) |
| 166 | self.custom_fields.write(body_bio) |
| 167 | |
| 168 | self.data = body_bio.getvalue() |
| 169 | self.size_uncompressed = self.size_compressed = len(self.data) |
| 170 | self.sha_hash = hashlib.sha1(self.data).digest() |
| 171 | |
| 172 | if self.compressed or compress: |
| 173 | self.stored_as |= 0x1 |
| 174 | self.data = zlib.compress(self.data) |
| 175 | self.size_compressed = len(self.data) |
| 176 | |
| 177 | bio = fp or BytesIO() |
| 178 | |
| 179 | bio.write(struct.pack('<I', self.header_magic)) |
| 180 | bio.write(struct.pack('<I', self.header_size)) |
| 181 | bio.write(struct.pack('<I', self.size_uncompressed)) |
| 182 | bio.write(struct.pack('<I', self.size_compressed)) |
| 183 | bio.write(self.sha_hash) |
| 184 | bio.write(struct.pack('B', self.stored_as)) |
| 185 | bio.write(struct.pack('<I', target_version)) |
| 186 | bio.write(self.data) |
| 187 | |
| 188 | return bio.tell() if fp else bio.getvalue() |
| 189 | |
| 190 | def apply_delta_manifest(self, delta_manifest: Manifest): |
| 191 | added = set() |