cleanup string handling

This commit is contained in:
2014-10-14 11:42:54 +02:00
parent 28c28578cf
commit 092430476d

View File

@@ -55,13 +55,13 @@ FILE_BUFFER_SIZE = 1024 * 1024
# open a filename
# determine if the file is compressed
# and returns a handle
def openBlendFile(filename, access="rb"):
def open_blend(filename, access="rb"):
"""Opens a blend file for reading or writing pending on the access
supports 2 kind of blend files. Uncompressed and compressed.
Known issue: does not support packaged blend files
"""
handle = open(filename, access)
magic = ReadString(handle, 7)
magic = read_string(handle, 7)
if magic == "BLENDER":
log.debug("normal blendfile detected")
handle.seek(0, os.SEEK_SET)
@@ -89,29 +89,10 @@ def openBlendFile(filename, access="rb"):
return res
def closeBlendFile(afile):
"""close the blend file
writes the blend file to disk if changes has happened"""
handle = afile.handle
if afile.is_compressed:
log.debug("close compressed blend file")
handle.seek(os.SEEK_SET, 0)
log.debug("compressing started")
fs = gzip.open(afile.filepath_orig, "wb")
data = handle.read(FILE_BUFFER_SIZE)
while data:
fs.write(data)
data = handle.read(FILE_BUFFER_SIZE)
fs.close()
log.debug("compressing finished")
handle.close()
######################################################
# Write a string to the file.
######################################################
def WriteString(handle, astring, fieldlen):
def write_string(handle, astring, fieldlen):
assert(isinstance(astring, str))
stringw = ""
if len(astring) >= fieldlen:
@@ -121,7 +102,7 @@ def WriteString(handle, astring, fieldlen):
handle.write(stringw.encode('utf-8'))
def WriteBytes(handle, astring, fieldlen):
def write_bytes(handle, astring, fieldlen):
assert(isinstance(astring, (bytes, bytearray)))
stringw = b''
if len(astring) >= fieldlen:
@@ -133,37 +114,37 @@ def WriteBytes(handle, astring, fieldlen):
handle.write(stringw)
######################################################
# ReadString reads a String of given length from a file handle
######################################################
STRING = []
for i in range(0, 2048):
STRING.append(struct.Struct(str(i) + "s"))
def _string_struct(length):
if length < len(_string_struct.STRING):
st = _string_struct.STRING[length]
else:
st = struct.Struct("%ds" % length)
return st
_string_struct.STRING = [struct.Struct("%ds" % i) for i in range(0, 2048)]
def ReadString(handle, length):
st = STRING[length]
return st.unpack(handle.read(st.size))[0].decode("iso-8859-1")
######################################################
# ReadString0 reads a zero terminating String from a file handle
######################################################
ZEROTESTER = 0
if sys.version_info < (3, 0):
ZEROTESTER = "\0"
def read_string(handle, length):
"""
read_string reads a String of given length from a file handle
"""
st = _string_struct(length)
return st.unpack(handle.read(st.size))[0].decode('utf-8')
def ReadString0(data, offset):
def read_string0(data, offset):
"""
read_string0 reads a zero terminating String from a file handle
"""
add = 0
while data[offset+add] != ZEROTESTER:
# TODO, faster method!
while data[offset + add] != 0:
add += 1
if add < len(STRING):
st = STRING[add]
S = st.unpack_from(data, offset)[0].decode("iso-8859-1")
else:
S = struct.Struct(str(add) + "s").unpack_from(data, offset)[0].decode("iso-8859-1")
return S
st = _string_struct(add)
result = st.unpack_from(data, offset)[0].decode('utf-8')
return result
######################################################
# ReadUShort reads an unsigned short from a file handle
@@ -290,10 +271,27 @@ class BlendFile:
return None
def close(self):
"""
Close the blend file
writes the blend file to disk if changes has happened
"""
if not self.is_modified:
self.handle.close()
else:
closeBlendFile(self)
handle = self.handle
if self.is_compressed:
log.debug("close compressed blend file")
handle.seek(os.SEEK_SET, 0)
log.debug("compressing started")
fs = gzip.open(self.filepath_orig, "wb")
data = handle.read(FILE_BUFFER_SIZE)
while data:
fs.write(data)
data = handle.read(FILE_BUFFER_SIZE)
fs.close()
log.debug("compressing finished")
handle.close()
class BlendFileBlock:
@@ -449,7 +447,7 @@ class DNACatalog:
log.debug("building #%d names" % names_len)
for i in range(names_len):
tName = ReadString0(data, offset)
tName = read_string0(data, offset)
offset = offset + len(tName) + 1
self.names.append(DNAName(tName))
del names_len
@@ -460,7 +458,7 @@ class DNACatalog:
offset += 4
log.debug("building #"+str(types_len)+" types")
for i in range(types_len):
tType = ReadString0(data, offset)
tType = read_string0(data, offset)
self.types.append([tType, 0, None])
offset += len(tType) + 1
@@ -598,7 +596,7 @@ class DNAStructure:
elif ftype[0] == "float":
return ReadFloat(handle, header)
elif ftype[0] == "char":
return ReadString(handle, fname.array_size)
return read_string(handle, fname.array_size)
else:
return ftype[2].field_get(header, handle, rest)
@@ -620,9 +618,9 @@ class DNAStructure:
if len(rest) == 0:
if ftype[0] == "char":
if type(value) is str:
return WriteString(handle, value, fname.array_size)
return write_string(handle, value, fname.array_size)
else:
return WriteBytes(handle, value, fname.array_size)
return write_bytes(handle, value, fname.array_size)
else:
return ftype[2].field_set(header, handle, rest, value)
else: