From 7639368f18430c38aef18ce6af5c33e06a22ae82 Mon Sep 17 00:00:00 2001 From: Alexander N <alpha-beta-release@gmx.net> Date: Sun, 10 Feb 2013 16:46:54 +0000 Subject: [PATCH] fix/workaround for character encoding ('ascii' is used for now, it should be 'cp1252' finally, but there are issues with printing on system console and struct.pack or io.FileIO.write) --- io_scene_ms3d/__init__.py | 2 +- io_scene_ms3d/ms3d_spec.py | 84 ++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/io_scene_ms3d/__init__.py b/io_scene_ms3d/__init__.py index c73b0a8d2..7dc24ed5f 100644 --- a/io_scene_ms3d/__init__.py +++ b/io_scene_ms3d/__init__.py @@ -23,7 +23,7 @@ bl_info = { 'description': "Import / Export MilkShape3D MS3D files"\ " (conform with MilkShape3D v1.8.4)", 'author': "Alexander Nussbaumer", - 'version': (0, 95, 1), + 'version': (0, 95, 2), 'blender': (2, 65, 3), 'location': "File > Import & File > Export", 'warning': "", diff --git a/io_scene_ms3d/ms3d_spec.py b/io_scene_ms3d/ms3d_spec.py index 1138a01eb..3afdbb769 100644 --- a/io_scene_ms3d/ms3d_spec.py +++ b/io_scene_ms3d/ms3d_spec.py @@ -37,6 +37,9 @@ from struct import ( from sys import ( exc_info, ) +from codecs import ( + register_error, + ) ############################################################################### # @@ -97,6 +100,22 @@ class Ms3dSpec: HEADER = "MS3D000000" + ## TEST_STR = 'START@€@µ@²@³@©@®@¶@ÿ@A@END.bmp' + ## TEST_RAW = b'START@\x80@\xb5@\xb2@\xb3@\xa9@\xae@\xb6@\xff@A@END.bmp\x00' + ## + STRING_MS3D_REPLACE = 'use_ms3d_replace' + STRING_ENCODING = "ascii" # wrong encoding (too limited), but there is an UnicodeEncodeError issue, that prevent using the correct one for the moment + ##STRING_ENCODING = "cp437" # US, wrong encoding and shows UnicodeEncodeError + ##STRING_ENCODING = "cp858" # Europe + €, wrong encoding and shows UnicodeEncodeError + ##STRING_ENCODING = "cp1252" # WIN EU, this would be the better codepage, but shows UnicodeEncodeError, on print on system console and writing to file + STRING_ERROR = STRING_MS3D_REPLACE + ##STRING_ERROR = 'replace' + ##STRING_ERROR = 'ignore' + ##STRING_ERROR = 'surrogateescape' + STRING_TERMINATION = b'\x00' + STRING_REPLACE = u'_' + + ########################################################################### # # min, max, default values @@ -251,52 +270,39 @@ class Ms3dIo: itemValue = value[i] Ms3dIo.write_array(raw_io, itemWriter, count2, itemValue) + + @staticmethod + def ms3d_replace(exc): + """ http://www.python.org/dev/peps/pep-0293/ """ + if isinstance(exc, UnicodeEncodeError): + return ((exc.end-exc.start)*Ms3dSpec.STRING_REPLACE, exc.end) + elif isinstance(exc, UnicodeDecodeError): + return (Ms3dSpec.STRING_REPLACE, exc.end) + elif isinstance(exc, UnicodeTranslateError): + return ((exc.end-exc.start)*Ms3dSpec.STRING_REPLACE, exc.end) + else: + raise TypeError("can't handle %s" % exc.__name__) + @staticmethod def read_string(raw_io, length): """ read a string of a specific length from raw_io """ - value = [] - skip = False - for i in range(length): - buffer = raw_io.read(Ms3dIo.SIZE_SBYTE) - if not buffer: - raise EOFError() - raw = (int)(unpack('<b', buffer)[0]) - if (raw >= 32) & (raw <= 255): - pass - else: - if (raw == 0): - raw = 0 - skip = True - else: - raw = 32 - - c = chr(raw) - - if (not skip): - value.append(c) - - finalValue = "".join(value) - return finalValue + buffer = raw_io.read(length) + if not buffer: + raise EOFError() + eol = buffer.find(Ms3dSpec.STRING_TERMINATION) + register_error(Ms3dSpec.STRING_MS3D_REPLACE, Ms3dIo.ms3d_replace) + s = buffer[:eol].decode(encoding=Ms3dSpec.STRING_ENCODING, errors=Ms3dSpec.STRING_ERROR) + return s @staticmethod def write_string(raw_io, length, value): """ write a string of a specific length to raw_io """ - l = len(value) - for i in range(length): - if(i < l): - c = value[i] - - if (isinstance(c, str)): - c = c[0] - raw = ord(c) - elif (isinstance(c, int)): - raw = c - else: - pass - else: - raw = 0 - - raw_io.write(pack('<b', (int)(raw % 256))) + register_error(Ms3dSpec.STRING_MS3D_REPLACE, Ms3dIo.ms3d_replace) + buffer = value.encode(encoding=Ms3dSpec.STRING_ENCODING, errors=Ms3dSpec.STRING_ERROR) + if not buffer: + buffer = bytes() + raw_io.write(pack('<{}s'.format(length), buffer)) + return ############################################################################### -- GitLab