72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
|
|
import io
|
|
import struct
|
|
|
|
class Writer:
|
|
def __init__(self, file, chunk_id: str, parent=None):
|
|
self.file = file
|
|
self.size: int = 0
|
|
self.size_pos = None
|
|
self.parent = parent
|
|
|
|
self.file.write(bytes(chunk_id[0:4], "ascii"))
|
|
|
|
def __enter__(self):
|
|
self.size_pos = self.file.tell()
|
|
self.file.write(struct.pack(f"<I", 0))
|
|
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
if self.size > self.MAX_SIZE:
|
|
raise OverflowError(f".msh file overflowed max size. size = {self.size} MAX_SIZE = {self.MAX_SIZE}")
|
|
|
|
if (self.size % 4) > 0:
|
|
padding = 4 - (self.size % 4)
|
|
self.write_bytes(bytes([0 for i in range(padding)]))
|
|
|
|
head_pos = self.file.tell()
|
|
self.file.seek(self.size_pos)
|
|
self.file.write(struct.pack(f"<I", self.size))
|
|
self.file.seek(head_pos)
|
|
|
|
if self.parent is not None:
|
|
self.parent.size += self.size
|
|
|
|
def write_bytes(self, packed_bytes):
|
|
self.size += len(packed_bytes)
|
|
self.file.write(packed_bytes)
|
|
|
|
def write_string(self, string: str):
|
|
self.write_bytes(bytes(string, "utf-8"))
|
|
self.write_bytes(b'\0')
|
|
|
|
def write_i8(self, *ints):
|
|
self.write_bytes(struct.pack(f"<{len(ints)}b", *ints))
|
|
|
|
def write_u8(self, *ints):
|
|
self.write_bytes(struct.pack(f"<{len(ints)}B", *ints))
|
|
|
|
def write_i16(self, *ints):
|
|
self.write_bytes(struct.pack(f"<{len(ints)}h", *ints))
|
|
|
|
def write_u16(self, *ints):
|
|
self.write_bytes(struct.pack(f"<{len(ints)}H", *ints))
|
|
|
|
def write_i32(self, *ints):
|
|
self.write_bytes(struct.pack(f"<{len(ints)}i", *ints))
|
|
|
|
def write_u32(self, *ints):
|
|
self.write_bytes(struct.pack(f"<{len(ints)}I", *ints))
|
|
|
|
def write_f32(self, *floats):
|
|
self.write_bytes(struct.pack(f"<{len(floats)}f", *floats))
|
|
|
|
def create_child(self, child_id: str):
|
|
child = Writer(self.file, chunk_id=child_id, parent=self)
|
|
self.size += 8
|
|
|
|
return child
|
|
|
|
MAX_SIZE: int = 2147483647 - 8
|