Files
maple/maple-py/src/maple/pdb/strings.py
T
2026-05-26 16:27:47 +10:00

36 lines
1.3 KiB
Python

"""DeviceSQL variable-length string encoding.
Three on-disk forms (see rekordbox-pdb.ksy `device_sql_string`):
- odd length_and_kind byte -> short ASCII (< 127 chars)
- 0x40 -> long ASCII (any length, ASCII bytes)
- 0x90 -> long UTF-16LE (for non-ASCII content)
We pick the cheapest form that fits the content. Long-but-ASCII paths
must use 0x40, NOT 0x90 -- some player firmwares decode 0x90 strings
as UTF-16 and then fail the case-sensitive filesystem lookup, so any
track whose `file_path` lands in the wrong form silently goes missing.
"""
EMPTY = b"\x03"
def encode_devicesql(s: str) -> bytes:
if not s:
return EMPTY
try:
ascii_bytes = s.encode("ascii")
except UnicodeEncodeError:
ascii_bytes = None
if ascii_bytes is not None:
if len(ascii_bytes) < 127:
length = len(ascii_bytes) + 1
length_and_kind = ((length << 1) | 1) & 0xFF
return bytes([length_and_kind]) + ascii_bytes
total_length = len(ascii_bytes) + 4 # marker + u2 length + u1 pad
return bytes([0x40]) + total_length.to_bytes(2, "little") + b"\x00" + ascii_bytes
payload = s.encode("utf-16-le")
total_length = len(payload) + 4
return bytes([0x90]) + total_length.to_bytes(2, "little") + b"\x00" + payload