add arguments to refine the pointer type

This commit is contained in:
2014-10-16 19:51:24 +02:00
parent 1814c0b46c
commit 010798af5d

View File

@@ -167,6 +167,15 @@ class BlendFile:
handle.close() handle.close()
def ensure_subtype_smaller(self, sdna_index_curr, sdna_index_next):
# never refine to a smaller type
if (self.structs[sdna_index_curr].size >
self.structs[sdna_index_next].size):
raise RuntimeError("cant refine to smaller type (%s -> %s)" %
(self.file.structs[sdna_index_curr].dna_type_id.decode('ascii'),
self.file.structs[sdna_index_next].dna_type_id.decode('ascii')))
@staticmethod @staticmethod
def decode_structs(header, block, handle): def decode_structs(header, block, handle):
""" """
@@ -311,18 +320,11 @@ class BlendFileBlock:
self.count = 0 self.count = 0
self.file_offset = 0 self.file_offset = 0
def refine_type_from_index(self, sdna_index_next): def refine_type_from_index(self, sdna_index_next):
assert(type(sdna_index_next) is int) assert(type(sdna_index_next) is int)
sdna_index_curr = self.sdna_index sdna_index_curr = self.sdna_index
self.file.ensure_subtype_smaller(sdna_index_curr, sdna_index_next)
# never refine to a smaller type
if (self.file.structs[sdna_index_curr].size >
self.file.structs[sdna_index_next].size):
raise RuntimeError("cant refine to smaller type (%s -> %s)" %
(self.file.structs[sdna_index_curr].dna_type_id.decode('ascii'),
self.file.structs[sdna_index_next].dna_type_id.decode('ascii')))
self.sdna_index = sdna_index_next self.sdna_index = sdna_index_next
def refine_type(self, dna_type_id): def refine_type(self, dna_type_id):
@@ -330,14 +332,31 @@ class BlendFileBlock:
self.refine_type_from_index(self.file.sdna_index_from_id[dna_type_id]) self.refine_type_from_index(self.file.sdna_index_from_id[dna_type_id])
def get(self, path, def get(self, path,
use_nil=True, use_str=True): sdna_index_refine=None,
dna_struct = self.file.structs[self.sdna_index] use_nil=True, use_str=True,
):
if sdna_index_refine is None:
sdna_index_refine = self.sdna_index
else:
self.file.ensure_subtype_smaller(self.sdna_index, sdna_index_refine)
dna_struct = self.file.structs[sdna_index_refine]
self.file.handle.seek(self.file_offset, os.SEEK_SET) self.file.handle.seek(self.file_offset, os.SEEK_SET)
return dna_struct.field_get(self.file.header, self.file.handle, path, return dna_struct.field_get(
self.file.header, self.file.handle, path,
use_nil=use_nil, use_str=use_str) use_nil=use_nil, use_str=use_str)
def set(self, path, value): def set(self, path, value,
dna_struct = self.file.structs[self.sdna_index] sdna_index_refine=None,
):
if sdna_index_refine is None:
sdna_index_refine = self.sdna_index
else:
self.file.ensure_subtype_smaller(self.sdna_index, sdna_index_refine)
dna_struct = self.file.structs[sdna_index_refine]
self.file.handle.seek(self.file_offset, os.SEEK_SET) self.file.handle.seek(self.file_offset, os.SEEK_SET)
self.file.is_modified = True self.file.is_modified = True
return dna_struct.field_set( return dna_struct.field_set(
@@ -347,9 +366,11 @@ class BlendFileBlock:
# Utility get/set # Utility get/set
# #
# avoid inline pointer casting # avoid inline pointer casting
def get_pointer(self, path): def get_pointer(self, path, sdna_index_refine=None):
result = self.get(path) if sdna_index_refine is None:
assert(self.file.structs[self.sdna_index].field_from_path(self.file.handle, path).dna_name.is_pointer) sdna_index_refine = self.sdna_index
result = self.get(path, sdna_index_refine=sdna_index_refine)
assert(self.file.structs[sdna_index_refine].field_from_path(self.file.handle, path).dna_name.is_pointer)
if result != 0: if result != 0:
# possible (but unlikely) # possible (but unlikely)
# that this fails and returns None # that this fails and returns None