32 lines
1.0 KiB
Python
32 lines
1.0 KiB
Python
"""Order-preserving, reversible storage for SQLite text containing NUL.
|
|
|
|
PostgreSQL text forbids U+0000. Encode it as SOH/SOH, and encode a literal
|
|
SOH as SOH/STX. All other characters stay unchanged. The mapping preserves
|
|
binary lexicographic order, including string prefixes and composite keys.
|
|
"""
|
|
|
|
CODEC = 'nul-soh-v1'
|
|
ESCAPE = '\x01'
|
|
|
|
|
|
def encode(value):
|
|
if isinstance(value, str):
|
|
return value.replace(ESCAPE, ESCAPE + '\x02').replace('\x00', ESCAPE + ESCAPE)
|
|
return value
|
|
|
|
|
|
def decode(value):
|
|
if not isinstance(value, str) or ESCAPE not in value:
|
|
return value
|
|
result = []
|
|
start = 0
|
|
while (position := value.find(ESCAPE, start)) >= 0:
|
|
result.append(value[start:position])
|
|
following = value[position + 1:position + 2]
|
|
if following not in (ESCAPE, '\x02'):
|
|
raise ValueError('Invalid nul-soh-v1 text escape')
|
|
result.append('\x00' if following == ESCAPE else ESCAPE)
|
|
start = position + 2
|
|
result.append(value[start:])
|
|
return ''.join(result)
|