atrcopy/atrcopy/mame.py

66 lines
1.9 KiB
Python

import zipfile
import numpy as np
from . import errors
from .segments import SegmentData, EmptySegment, ObjSegment
from .diskimages import DiskImageBase
from .utils import to_numpy
import logging
log = logging.getLogger(__name__)
class MameZipImage(DiskImageBase):
def __init__(self, rawdata, filename=""):
self.zipdata = rawdata
fh = self.zipdata.bufferedio
if zipfile.is_zipfile(fh):
with zipfile.ZipFile(fh) as zf:
self.check_zip_size(zf)
self.create_rawdata(zf)
else:
raise errors.InvalidDiskImage("Not a MAME zip file")
DiskImageBase.__init__(self, self.rawdata, filename)
def __str__(self):
return "MAME Zip file, %d ROMs, orig_size=%d, uncompressed=%d" % (len(self.zip_segment_info), len(self.zipdata), len(self.rawdata))
def setup(self):
self.check_size()
def strict_check(self):
pass
def relaxed_check(self):
pass
def check_zip_size(self, zf):
for item in zf.infolist():
_, r = divmod(item.file_size, 16)
if r > 0:
raise errors.InvalidDiskImage("zip entry not 16 byte multiple")
def create_rawdata(self, zf):
roms = []
segment_info = []
offset = 0
for item in zf.infolist():
rom = np.frombuffer(zf.open(item).read(), dtype=np.uint8)
roms.append(rom)
segment_info.append((offset, item.file_size, item.filename, item.CRC))
offset += item.file_size
data = np.concatenate(roms)
self.zip_segment_info = segment_info
self.rawdata = SegmentData(data)
def check_size(self):
pass
def parse_segments(self):
r = self.rawdata
self.segments = []
for offset, size, name, crc in self.zip_segment_info:
end = offset + size
self.segments.append(ObjSegment(r[offset:end], 0, offset, offset, end, name=name))