summaryrefslogtreecommitdiff
path: root/plugins/python/liveconv/converters.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/python/liveconv/converters.py')
-rw-r--r--plugins/python/liveconv/converters.py160
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')