SWBF-msh-Blender-IO/addons/io_scene_swbf_msh/msh_writer.py

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