-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPyByteArray.py
More file actions
99 lines (82 loc) · 3.49 KB
/
Copy pathPyByteArray.py
File metadata and controls
99 lines (82 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@namespace("Promethium")
from Promethium import List
# CPython's `bytearray` — a mutable, growable byte sequence, unlike
# Promethium's own `bytes` (a fixed-size native `Byte[]`, no `+`
# operator, no `bytes(n)` zero-fill constructor — see `struct.py`'s
# notes). Named `PyByteArray` rather than `ByteArray` on the established
# precedent of Cocoa/Toffee short-name collisions (`Queue`→`PyQueue`,
# `Date`→`PyDate`) — not confirmed to collide, but not worth a wasted
# rebuild to find out.
#
# Indexed access/mutation is backed by a plain `List[int]` (each element
# 0-255) — Promethium's own array-backed list, the same substrate
# `Deque`/`Counter`/etc. already use. `to_bytes()` is the part that used
# to be impossible: converting a *runtime-determined-length* `List[int]`
# into a real `bytes` value needs allocating a `bytes` buffer of that
# exact size, and the only previously-confirmed way to build a `bytes`
# value was a compile-time-sized literal. `RemObjects.Elements.RTL.Binary`
# — a genuine cross-platform growable byte buffer (backed per-target by
# `MemoryStream`/`NSMutableData`/`ByteArrayOutputStream`, found while
# looking for a `bytearray` substrate) turns out to solve exactly this:
# `Binary()` starts empty, `.Write(someBytes)` appends, and `.ToArray()`
# hands back a `bytes`-compatible native array of the exact accumulated
# length. Confirmed with a standalone probe before writing this file:
# `Binary().Write(...)` three times then `.ToArray()` round-tripped
# correctly and `.Length` matched the real accumulated count, both on
# Echoes. This corrects `struct.py`'s/`hashlib.py`'s "no dynamically-
# sized `bytes` allocation exists" note — it exists, it just isn't a
# `bytes`-literal-shaped API.
#
# `to_bytes()` writes one byte at a time (O(n) native calls) rather than
# batching runs into single `Write` calls — correct, not fast, matching
# `Deque`'s own documented "O(n) appendleft, real ring-buffer is future
# work" trade-off.
class PyByteArray:
_entries: List[int]
def __init__(self):
self._entries = List[int]()
def __init__(self, data: bytes):
self._entries = List[int]()
i: int = 0
while i < data.Length:
self._entries.append(data[i])
i += 1
def __init__(self, size: int):
self._entries = List[int]()
i: int = 0
while i < size:
self._entries.append(0)
i += 1
def __len__(self) -> int:
return self._entries.__len__()
def __getitem__(self, index: int) -> int:
return self._entries[index]
def __setitem__(self, index: int, value: int):
self._entries[index] = value
def append(self, value: int):
self._entries.append(value)
def extend(self, data: bytes):
i: int = 0
while i < data.Length:
self._entries.append(data[i])
i += 1
def pop(self) -> int:
return self._entries.pop()
def clear(self):
self._entries.clear()
def copy(self) -> PyByteArray:
result: PyByteArray = PyByteArray()
i: int = 0
while i < self._entries.__len__():
result.append(self._entries[i])
i += 1
return result
def to_bytes(self) -> bytes:
buf: RemObjects.Elements.RTL.Binary = RemObjects.Elements.RTL.Binary()
i: int = 0
while i < self._entries.__len__():
one: bytes = b"\x00"
one[0] = self._entries[i]
buf.Write(one)
i += 1
return buf.ToArray()