refactor section file generation to make it more generic
This commit is contained in:
parent
d6eb3868ec
commit
8c138247e0
@ -90,7 +90,7 @@ class Yaml2Mcl:
|
|||||||
exportEntitiesFileName = "entities.cs"
|
exportEntitiesFileName = "entities.cs"
|
||||||
|
|
||||||
print("export entities to file: '" + exportEntitiesFileName + "'")
|
print("export entities to file: '" + exportEntitiesFileName + "'")
|
||||||
manager.save_entities_to_file(exportEntitiesFileName)
|
manager.save_entities_to_file(exportEntitiesFileName, outputFileName)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@ -115,78 +115,17 @@ class MemoryLibraryManager (MochaLibraryManager):
|
|||||||
|
|
||||||
guids = guid_db.to_list()
|
guids = guid_db.to_list()
|
||||||
|
|
||||||
f = open(self.filename, "wb")
|
from .sectionfile import SectionFile, Section, GuidSection, InstancesSection, AttributesSection, RelationshipsSection, StringTableSection, ResourcesSection
|
||||||
f.write("MCX!".encode('utf-8'))
|
f = SectionFile("MCX!", 2.0, 15)
|
||||||
|
f.open(self.filename)
|
||||||
|
|
||||||
# version
|
f.sections.append(GuidSection("GUIDTable", guids))
|
||||||
import struct
|
f.sections.append(InstancesSection("Instances", insts))
|
||||||
ba = bytearray(struct.pack("f", 2.0))
|
f.sections.append(AttributesSection("Attributes", atts))
|
||||||
f.write(ba)
|
f.sections.append(RelationshipsSection("Relationships", rels))
|
||||||
|
f.sections.append(StringTableSection("StringTable", strs_db))
|
||||||
|
f.sections.append(ResourcesSection("Resources", rsrc_db))
|
||||||
|
|
||||||
section_count = 6
|
f.save()
|
||||||
# section count
|
|
||||||
f.write(int.to_bytes(section_count, 4, 'little'))
|
|
||||||
|
|
||||||
# sections = [ (offset, length) ]
|
|
||||||
sections = [ ("GUIDTable", guids, 16), ("Instances", insts, 16), ("Attributes", atts, 12), ("Relationships", rels, 12), ("StringTable", strs_db, None), ("Resources", rsrc_db, None) ]
|
|
||||||
offset = 12 + (section_count * 32)
|
|
||||||
|
|
||||||
lastLength = 0
|
|
||||||
for (name, sect, item_len) in sections:
|
|
||||||
offset += lastLength
|
|
||||||
length = 0
|
|
||||||
|
|
||||||
if item_len is None:
|
|
||||||
if sect == strs_db:
|
|
||||||
for itm in sect:
|
|
||||||
# FIXME: hard code for z-strings
|
|
||||||
length += len(itm) + 1
|
|
||||||
elif sect == rsrc_db:
|
|
||||||
for itm in sect:
|
|
||||||
length += len(itm)
|
|
||||||
else:
|
|
||||||
length = item_len * len(sect)
|
|
||||||
|
|
||||||
f.write(str(name).ljust(16, '\0').encode("utf-8"))
|
|
||||||
f.write(int.to_bytes(offset, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(length, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(len(sect), 4, 'little'))
|
|
||||||
f.write(int.to_bytes(0, 4, 'little')) # reserved or padding
|
|
||||||
|
|
||||||
lastLength = length
|
|
||||||
|
|
||||||
# guids
|
|
||||||
for guid in guids:
|
|
||||||
f.write(guid.to_bytes())
|
|
||||||
|
|
||||||
# instances
|
|
||||||
for (gi, cgi, ckey, ikey) in insts:
|
|
||||||
f.write(int.to_bytes(cgi, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(gi, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(ckey, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(ikey, 4, 'little'))
|
|
||||||
|
|
||||||
# attributes
|
|
||||||
for (srci, atti, vali, edate) in atts:
|
|
||||||
f.write(int.to_bytes(srci, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(atti, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(vali, 4, 'little'))
|
|
||||||
|
|
||||||
# relationships
|
|
||||||
for (srci, reli, tgti, edate) in rels:
|
|
||||||
f.write(int.to_bytes(srci, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(reli, 4, 'little'))
|
|
||||||
f.write(int.to_bytes(tgti, 4, 'little'))
|
|
||||||
|
|
||||||
# string table
|
|
||||||
for strz in strs_db:
|
|
||||||
f.write(strz.encode("utf-8"))
|
|
||||||
f.write(int.to_bytes(0, 1, 'little'))
|
|
||||||
|
|
||||||
# resource table
|
|
||||||
for rsrc in rsrc_db:
|
|
||||||
f.write(rsrc)
|
|
||||||
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
print ("processed " + str(len(self.instance_ops)) + " instances, " + str(len(self.attribute_ops)) + " attributes, and " + str(len(self.relationship_ops)) + " relationships")
|
print ("processed " + str(len(self.instance_ops)) + " instances, " + str(len(self.attribute_ops)) + " attributes, and " + str(len(self.relationship_ops)) + " relationships")
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of yaml2mcl.
|
||||||
|
#
|
||||||
|
# yaml2mcl is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# yaml2mcl is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
class Section:
|
||||||
|
|
||||||
|
def __init__(self, name : str, data, count : int):
|
||||||
|
self.name = name
|
||||||
|
self.data = data
|
||||||
|
self.count = count
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
return self.count * len(self.data)
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class GuidSection (Section):
|
||||||
|
def __init__(self, name : str, data : list):
|
||||||
|
|
||||||
|
Section.__init__(self, name, data, 16)
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
for guid in self.data:
|
||||||
|
f.write(guid.to_bytes())
|
||||||
|
|
||||||
|
class InstancesSection (Section):
|
||||||
|
def __init__(self, name : str, data : list):
|
||||||
|
|
||||||
|
Section.__init__(self, name, data, 16)
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
|
||||||
|
for (gi, cgi, ckey, ikey) in self.data:
|
||||||
|
f.write(int.to_bytes(cgi, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(gi, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(ckey, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(ikey, 4, 'little'))
|
||||||
|
|
||||||
|
class AttributesSection (Section):
|
||||||
|
def __init__(self, name : str, data : list):
|
||||||
|
|
||||||
|
Section.__init__(self, name, data, 12)
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
|
||||||
|
for (srci, atti, vali, edate) in self.data:
|
||||||
|
f.write(int.to_bytes(srci, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(atti, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(vali, 4, 'little'))
|
||||||
|
|
||||||
|
class RelationshipsSection (Section):
|
||||||
|
def __init__(self, name : str, data : list):
|
||||||
|
|
||||||
|
Section.__init__(self, name, data, 12)
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
|
||||||
|
for (srci, reli, tgti, edate) in self.data:
|
||||||
|
f.write(int.to_bytes(srci, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(reli, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(tgti, 4, 'little'))
|
||||||
|
|
||||||
|
class StringTableSection (Section):
|
||||||
|
|
||||||
|
def __init__(self, name : str, data : list):
|
||||||
|
|
||||||
|
Section.__init__(self, name, data, 0)
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
length = 0
|
||||||
|
for item in self.data:
|
||||||
|
length += len(item) + 1
|
||||||
|
return length
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
for item in self.data:
|
||||||
|
f.write(item.encode("utf-8"))
|
||||||
|
f.write(int.to_bytes(0, 1, 'little'))
|
||||||
|
|
||||||
|
class ResourcesSection (Section):
|
||||||
|
|
||||||
|
def __init__(self, name : str, data : list):
|
||||||
|
|
||||||
|
Section.__init__(self, name, data, 0)
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
length = 0
|
||||||
|
for item in self.data:
|
||||||
|
length += len(item)
|
||||||
|
return length
|
||||||
|
|
||||||
|
def write_data(self, f):
|
||||||
|
for rsrc in self.data:
|
||||||
|
f.write(rsrc)
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of yaml2mcl.
|
||||||
|
#
|
||||||
|
# yaml2mcl is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# yaml2mcl is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .Section import Section
|
||||||
|
|
||||||
|
class SectionFile:
|
||||||
|
|
||||||
|
def __init__(self, signature : str = None, version : float = 1.0, flags : int = 0):
|
||||||
|
self.signature = signature
|
||||||
|
self.sections = [ ]
|
||||||
|
self.version = version
|
||||||
|
self.flags = flags
|
||||||
|
|
||||||
|
def add_section(self, section : Section):
|
||||||
|
self.sections.append(section)
|
||||||
|
|
||||||
|
def open(self, filename : str):
|
||||||
|
|
||||||
|
self.filename = filename
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
|
||||||
|
f = open(self.filename, 'wb')
|
||||||
|
|
||||||
|
if self.signature is not None:
|
||||||
|
f.write(self.signature.encode('utf-8'))
|
||||||
|
|
||||||
|
import struct
|
||||||
|
ba = bytearray(struct.pack("f", self.version))
|
||||||
|
f.write(ba)
|
||||||
|
f.write(int.to_bytes(self.flags, 4, 'little'))
|
||||||
|
|
||||||
|
section_count = len(self.sections)
|
||||||
|
f.write(int.to_bytes(section_count, 4, 'little'))
|
||||||
|
|
||||||
|
offset = 16 + (section_count * 32)
|
||||||
|
lastLength = 0
|
||||||
|
for sect in self.sections:
|
||||||
|
offset += lastLength
|
||||||
|
length = sect.get_length()
|
||||||
|
|
||||||
|
f.write(str(sect.name).ljust(16, '\0').encode("utf-8"))
|
||||||
|
f.write(int.to_bytes(offset, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(length, 4, 'little'))
|
||||||
|
f.write(int.to_bytes(len(sect.data), 4, 'little'))
|
||||||
|
f.write(int.to_bytes(0, 4, 'little')) # reserved or padding
|
||||||
|
|
||||||
|
lastLength = length
|
||||||
|
|
||||||
|
for sect in self.sections:
|
||||||
|
sect.write_data(f)
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
# Copyright 2024 Michael Becker <alcexhim@gmail.com>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from .SectionFile import SectionFile
|
||||||
|
from .Section import Section, GuidSection, InstancesSection, AttributesSection, RelationshipsSection, StringTableSection, ResourcesSection
|
||||||
Loading…
x
Reference in New Issue
Block a user