diff options
Diffstat (limited to 'plugins/python/liveconv/converters.py')
-rw-r--r-- | plugins/python/liveconv/converters.py | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/plugins/python/liveconv/converters.py b/plugins/python/liveconv/converters.py new file mode 100644 index 0000000..ef35f59 --- /dev/null +++ b/plugins/python/liveconv/converters.py @@ -0,0 +1,160 @@ + +from datetime import datetime, timedelta +from pychrysalide.arch import vmpa +import string +import struct + + +def data_to_number(content, addr, order, fmt): + """Convert to a number, if possible.""" + + size = struct.calcsize(order + fmt) + + data = content.read_raw(addr, size) + + value = struct.unpack(order + fmt, data)[0] + + return str(value) + + +def data_to_time(content, addr, order, fmt): + """Convert to a number, if possible.""" + + size = struct.calcsize(order + fmt) + + data = content.read_raw(addr, size) + + value = struct.unpack(order + fmt, data)[0] + + return str(datetime(1970, 1, 1) + timedelta(seconds=value)) + + +# Cf. FILETIME structure +# https://docs.microsoft.com/fr-fr/windows/win32/api/minwinbase/ns-minwinbase-filetime + +def data_to_filetime(content, addr, order): + """Convert to a Windows FILETIME, if possible.""" + + data = content.read_raw(addr, 8) + + value = struct.unpack(order + 'Q', data)[0] + + us = value / 10. + + return str(datetime(1601, 1, 1) + timedelta(microseconds=us)) + + +# Cf. DosDateTimeToFileTime() +# https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime + +def data_to_dos_time(content, addr, order): + """Convert to a MS-DOS time, if possible.""" + + data = content.read_raw(addr, 2) + + value = struct.unpack(order + 'H', data)[0] + + seconds = (value & 0x1f) * 2 + minutes = (value & 0x7e0) >> 5 + hours = (value & 0xf800) >> 11 + + return '%02u:%02u:%02u' % (hours, minutes, seconds) + +def data_to_dos_date(content, addr, order): + """Convert to a MS-DOS date, if possible.""" + + data = content.read_raw(addr, 2) + + value = struct.unpack(order + 'H', data)[0] + + day = (value & 0x1f) + month = (value & 0x1e0) >> 5 + year = ((value & 0xfe00) >> 9) + 1980 + + return '%u/%u/%u' % (month, day, year) + + +def data_to_char(content, addr, order): + """Convert to a character, if possible.""" + + data = content.read_raw(addr, 1) + + value = struct.unpack(order + 'c', data)[0] + + ch = chr(value[0]) + + return ch if ch in string.printable else '-' + + +def data_to_ansi(content, addr, order): + """Convert to an ANSI string, if possible.""" + + result = None + + while True: + + try: + + data = content.read_raw(addr, 1) + + value = struct.unpack(order + 'c', data)[0] + + ch = chr(value[0]) + + if not(ch in string.printable): + break + + if result: + result += ch + else: + result = ch + + except: + pass + + return result if result else '-' + + +def _data_to_utf(content, addr, utf): + """Convert to an UTF-X string, if possible.""" + + result = None + + length = 0 + + while True: + + try: + + start = vmpa(addr.phys, 0) + data = content.read_raw(start, length + 1) + + result = data.decode(utf) + + length += 1 + + except Exception as e: + break + + if length > 0: + + data = content.read_raw(addr, length) + + result = data.decode('utf-8') + + else: + result = '-' + + return result + + +def data_to_utf8(content, addr, order): + """Convert to an UTF-8 string, if possible.""" + + return _data_to_utf(content, addr, 'utf-8') + + +def data_to_utf16(content, addr, order): + """Convert to an UTF-16 string, if possible.""" + + return _data_to_utf(content, addr, 'utf-16') |