cbytesparse.py.Memory
- class cbytesparse.py.Memory(start=None, endex=None)[source]
Mutable virtual memory.
This class is a handy wrapper around blocks, so that it can behave mostly like a
bytearray
, but on sparse chunks of data.Being mutable, instances of this class can be updated dynamically. All the methods and attributes of an
ImmutableMemory
are available as well.Please look at examples of each method to get a glimpse of the features of this class.
See also
ImmutableMemory
- Parameters:
start (int) – Optional memory start address. Anything before will be deleted.
endex (int) – Optional memory exclusive end address. Anything at or after it will be deleted.
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> memory.to_blocks() []
>>> memory = Memory(start=3, endex=10) >>> memory.bound_span (3, 10) >>> memory.write(0, b'Hello, World!') >>> memory.to_blocks() [[3, b'lo, Wor']]
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> memory.to_blocks() [[5, b'Hello, World!']]
Methods
Appends a single item.
Backups an append() operation.
Restores an append() operation.
Span of block data.
Iterates over blocks.
Bounds addresses.
Clears an address range.
Backups a clear() operation.
Restores a clear() operation.
Collapses a generic sequence of blocks.
Iterates over blocks.
Iterates over content address and value pairs.
Iterates over content addresses.
Iterates over content values.
Creates a deep copy.
Counts items.
Keeps data within an address range.
Backups a crop() operation.
Restores a crop() operation.
Cuts a slice of memory.
Deletes an address range.
Backups a delete() operation.
Restores a delete() operation.
Span of homogeneous data.
Concatenates items.
Backups an extend() operation.
Restores an extend() operation.
Selects items from a range.
Overwrites a range with a pattern.
Backups a fill() operation.
Restores a fill() operation.
Index of an item.
Fills emptiness between non-touching blocks.
Backups a flood() operation.
Restores a flood() operation.
Creates a virtual memory from blocks.
Creates a virtual memory from a byte-like chunk.
Creates a virtual memory from a iterable address/byte mapping.
Creates a virtual memory from another one.
Creates a virtual memory from a byte-like sequence.
Creates a virtual memory from an hexadecimal string.
Iterates over block gaps.
Gets the item at an address.
Converts into an hexadecimal string.
Index of an item.
Inserts data.
Backups an insert() operation.
Restores an insert() operation.
Iterates over block intervals.
Iterates over address and value pairs.
Iterates over addresses.
Gets the item at an address.
Sets the item at an address.
Backups a poke() operation.
Restores a poke() operation.
Takes a value away.
Backups a pop() operation.
Restores a pop() operation.
Pops the last item.
Backups a popitem() operation.
Restores a popitem() operation.
Reads data.
Reads data into a pre-allocated buffer.
Removes an item.
Backups a remove() operation.
Restores a remove() operation.
Inserts emptiness.
Backups a reserve() operation.
Restores a reserve() operation.
Reverses the memory in-place.
Index of an item, reversed search.
Index of an item, reversed search.
Iterates over values, reversed order.
Defaults a value.
Backups a setdefault() operation.
Restores a setdefault() operation.
Shifts the items.
Backups a shift() operation.
Restores an shift() operation.
Exports into blocks.
Exports into bytes.
Updates data.
Backups an update() operation.
Restores an update() operation.
Validates internal structure.
Iterates over values.
Creates a view over a range.
Writes data.
Backups a write() operation.
Restores a write() operation.
Attributes
Bounds exclusive end address.
Bounds span addresses.
Bounds start address.
Exclusive content end address.
Inclusive content end address.
Number of blocks.
Actual content size.
Memory content address span.
Inclusive content start address.
Contains contiguous data.
Exclusive end address.
Inclusive end address.
Memory address span.
Inclusive start address.
- __add__(value)[source]
Concatenates items.
Equivalent to
self.copy() += items
of aMutableMemory
.See also
MutableMemory.__iadd__()
Examples
>>> from bytesparse import Memory
>>> memory1 = Memory.from_bytes(b'ABC') >>> memory2 = memory1 + b'xyz' >>> memory2.to_blocks() [[0, b'ABCxyz']]
>>> memory1 = Memory.from_blocks([[1, b'ABC']]) >>> memory2 = Memory.from_blocks([[5, b'xyz']]) >>> memory1.content_endex 4 >>> memory3 = memory1 + memory2 >>> memory3.to_blocks() [[1, b'ABC'], [9, b'xyz']]
- __bool__()[source]
Has any items.
- Returns:
bool – Has any items.
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> bool(memory) False
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> bool(memory) True
- __bytes__()[source]
Creates a bytes clone.
- Returns:
bytes
– Cloned data.- Raises:
ValueError – Data not contiguous (see
contiguous
).
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> bytes(memory) b''
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> bytes(memory) b'Hello, World!'
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5, start=1, endex=20) >>> bytes(memory) Traceback (most recent call last): ... ValueError: non-contiguous data within range
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> bytes(memory) Traceback (most recent call last): ... ValueError: non-contiguous data within range
- __class_getitem__ = <bound method GenericAlias of <class 'cbytesparse.py.Memory'>>
- __contains__(item)[source]
Checks if some items are contained.
- Parameters:
item (items) – Items to find. Can be either some byte string or an integer.
- Returns:
bool – Item is contained.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C]
[1
2
3]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'123'], [9, b'xyz']]) >>> b'23' in memory True >>> ord('y') in memory True >>> b'$' in memory False
- __delitem__(key)[source]
Deletes data.
- Parameters:
key (slice or int) – Deletion range or address.
Note
This method is typically not optimized for a
slice
where its step is an integer greater than 1.Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
[A
B
C
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> del memory[4:9] >>> memory.to_blocks() [[1, b'ABCyz']]
~~~
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
[A
B
C
D]
[$]
[x
z]
[A
B
D]
[$]
[x
z]
[A
D]
[x]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> del memory[9] >>> memory.to_blocks() [[1, b'ABCD'], [6, b'$'], [8, b'xz']] >>> del memory[3] >>> memory.to_blocks() [[1, b'ABD'], [5, b'$'], [7, b'xz']] >>> del memory[2:10:3] >>> memory.to_blocks() [[1, b'AD'], [5, b'x']]
- __eq__(other)[source]
Equality comparison.
- Parameters:
other (Memory) –
Data to compare with self.
If it is a
ImmutableMemory
, all of its blocks must match.If it is a
bytes
, abytearray
, or amemoryview
, it is expected to match the first and only stored block.Otherwise, it must match the first and only stored block, via iteration over the stored values.
- Returns:
bool – self is equal to other.
Examples
>>> from bytesparse import Memory
>>> data = b'Hello, World!' >>> memory = Memory.from_bytes(data) >>> memory == data True >>> memory.shift(1) >>> memory == data True
>>> data = b'Hello, World!' >>> memory = Memory.from_bytes(data) >>> memory == list(data) True >>> memory.shift(1) >>> memory == list(data) True
- __getitem__(key)[source]
Gets data.
- Parameters:
key (slice or int) – Selection range or address. If it is a
slice
with bytes-like step, the latter is interpreted as the filling pattern.- Returns:
items – Items from the requested range.
Note
This method is typically not optimized for a
slice
where its step is an integer greater than 1.Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B
C
D]
[$]
[x
y
z]
65
66
67
68
36
120
121
122
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory[9] # -> ord('y') = 121 121 >>> memory[:3]._blocks [[1, b'AB']] >>> memory[3:10]._blocks [[3, b'CD'], [6, b'$'], [8, b'xy']] >>> bytes(memory[3:10:b'.']) b'CD.$.xy' >>> memory[memory.endex] None >>> bytes(memory[3:10:3]) b'C$y' >>> memory[3:10:2]._blocks [[3, b'C'], [6, b'y']] >>> bytes(memory[3:10:2]) Traceback (most recent call last): ... ValueError: non-contiguous data within range
- __hash__ = None
- __iadd__(value)[source]
Concatenates items.
Equivalent to
self.extend(items)
.See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'ABC') >>> memory += b'xyz' >>> memory.to_blocks() [[0, b'ABCxyz']]
>>> memory1 = Memory.from_blocks([[1, b'ABC']]) >>> memory2 = Memory.from_blocks([[5, b'xyz']]) >>> memory1.content_endex 4 >>> memory1 += memory2 >>> memory1.to_blocks() [[1, b'ABC'], [9, b'xyz']]
- __imul__(times)[source]
Concatenates a repeated copy.
Equivalent to
self.extend(items)
repeated times times.See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'ABC') >>> memory *= 3 >>> memory.to_blocks() [[0, b'ABCABCABC']]
>>> memory = Memory.from_blocks([[1, b'ABC']]) >>> memory *= 3 >>> memory.to_blocks() [[1, b'ABCABCABC']]
- __iter__()[source]
Iterates over values.
Iterates over values between
start
andendex
.- Yields:
int – Value as byte integer, or
None
.
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> list(memory) [65, 66, 67, None, 120, 121, 122]
- __len__()[source]
Actual length.
Computes the actual length of the stored items, i.e. (
endex
-start
). This will consider any bounds being active.- Returns:
int – Memory length.
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> len(memory) 0
>>> memory = Memory(start=3, endex=10) >>> len(memory) 7
>>> memory = Memory.from_blocks([[1, b'ABC'], [9, b'xyz']]) >>> len(memory) 11
>>> memory = Memory.from_blocks([[3, b'ABC'], [9, b'xyz']], start=1, endex=15) >>> len(memory) 14
- __mul__(times)[source]
Concatenates a repeated copy.
Equivalent to
self.copy() *= items
of aMutableMemory
.See also
MutableMemory.__imul__()
Examples
>>> from bytesparse import Memory
>>> memory1 = Memory.from_bytes(b'ABC') >>> memory2 = memory1 * 3 >>> memory2.to_blocks() [[0, b'ABCABCABC']]
>>> memory1 = Memory.from_blocks([[1, b'ABC']]) >>> memory2 = memory1 * 3 >>> memory2.to_blocks() [[1, b'ABCABCABC']]
- __reversed__()[source]
Iterates over values, reversed order.
Iterates over values between
start
andendex
, in reversed order.- Yields:
int – Value as byte integer, or
None
.
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> list(memory) [65, 66, 67, None, 120, 121, 122] >>> list(reversed(memory)) [122, 121, 120, None, 67, 66, 65]
- __setitem__(key, value)[source]
Sets data.
- Parameters:
key (slice or int) – Selection range or address.
value (items) – Items to write at the selection address. If value is null, the range is cleared.
Examples
>>> from bytesparse import Memory
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
[A]
[y
z]
[A
B
C]
[x
y
z]
[A]
[C]
y
z]
[A
1
C]
[2
y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory[7:10] = None >>> memory.to_blocks() [[5, b'AB'], [10, b'yz']] >>> memory[7] = b'C' >>> memory[9] = b'x' >>> memory.to_blocks() == [[5, b'ABC'], [9, b'xyz']] True >>> memory[6:12:3] = None >>> memory.to_blocks() [[5, b'A'], [7, b'C'], [10, b'yz']] >>> memory[6:13:3] = b'123' >>> memory.to_blocks() [[5, b'A1C'], [9, b'2yz3']]
~~~
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C]
[x
y
z]
[$]
[A
B
C]
[x
y
z]
[$]
[A
B
4
5
6
7
8
y
z]
[$]
[A
B
4
5
<
>
8
y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory[0:4] = b'$' >>> memory.to_blocks() [[0, b'$'], [2, b'ABC'], [6, b'xyz']] >>> memory[4:7] = b'45678' >>> memory.to_blocks() [[0, b'$'], [2, b'AB45678yz']] >>> memory[6:8] = b'<>' >>> memory.to_blocks() [[0, b'$'], [2, b'AB45<>8yz']]
- __str__()[source]
String representation.
If
content_size
is lesser thanSTR_MAX_CONTENT_SIZE
, then the memory is represented as a list of blocks.If exceeding, it is equivalent to
__repr__()
.- Returns:
str – String representation.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [7, b'xyz']]) >>> str(memory) <[[1, b'ABC'], [7, b'xyz']]>
- classmethod __subclasshook__(C)
Abstract classes can override this to customize issubclass().
This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).
- __weakref__
list of weak references to the object (if defined)
- _block_index_at(address)[source]
Locates the block enclosing an address.
Returns the index of the block enclosing the given address.
- Parameters:
address (int) – Address of the target item.
- Returns:
int – Block index if found,
None
otherwise.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
0
0
0
0
1
2
2
2
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> [memory._block_index_at(i) for i in range(12)] [None, 0, 0, 0, 0, None, 1, None, 2, 2, 2, None]
- _block_index_endex(address)[source]
Locates the last block before an address range.
Returns the index of the last block whose end address is lesser than or equal to address.
Useful to find the termination block index in a ranged search.
- Parameters:
address (int) – Exclusive end address of the scanned range.
- Returns:
int – First block index before address.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
0
1
1
1
1
1
2
2
3
3
3
3
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> [memory._block_index_endex(i) for i in range(12)] [0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3]
- _block_index_start(address)[source]
Locates the first block inside an address range.
Returns the index of the first block whose start address is greater than or equal to address.
Useful to find the initial block index in a ranged search.
- Parameters:
address (int) – Inclusive start address of the scanned range.
- Returns:
int – First block index since address.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
0
0
0
0
0
1
1
2
2
2
2
3
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> [memory._block_index_start(i) for i in range(12)] [0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3]
- _prebound_endex(start_min, size)[source]
Bounds final data.
Low-level method to manage bounds of data starting from an address.
- Parameters:
start_min (int) – Starting address of the erasure range. If
None
,bound_endex
minus size is considered.size (int) – Size of the erasure range.
See also
- _prebound_endex_backup(start_min, size)[source]
Backups a _prebound_endex() operation.
- Parameters:
start_min (int) – Starting address of the erasure range. If
None
,bound_endex
minus size is considered.size (int) – Size of the erasure range.
- Returns:
ImmutableMemory
– Backup memory region.
See also
- _prebound_start(endex_max, size)[source]
Bounds initial data.
Low-level method to manage bounds of data starting from an address.
- Parameters:
endex_max (int) – Exclusive end address of the erasure range. If
None
,bound_start
plus size is considered.size (int) – Size of the erasure range.
See also
- _prebound_start_backup(endex_max, size)[source]
Backups a _prebound_start() operation.
- Parameters:
endex_max (int) – Exclusive end address of the erasure range. If
None
,bound_start
plus size is considered.size (int) – Size of the erasure range.
- Returns:
ImmutableMemory
– Backup memory region.
See also
- append(item)[source]
Appends a single item.
- Parameters:
item (int) – Value to append. Can be a single byte string or integer.
See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> memory.append(b'$') >>> memory.to_blocks() [[0, b'$']]
~~~
>>> memory = Memory() >>> memory.append(3) >>> memory.to_blocks() [[0, b'\x03']]
- block_span(address)[source]
Span of block data.
It searches for the biggest chunk of data adjacent to the given address.
If the address is within a gap, its bounds are returned, and its value is
None
.If the address is before or after any data, bounds are
None
.- Parameters:
address (int) – Reference address.
- Returns:
tuple – Start bound, exclusive end bound, and reference value.
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> memory.block_span(0) (None, None, None)
~~~
0
1
2
3
4
5
6
7
8
9
10
[A
B
B
B
C]
[C
C
D]
65
66
66
66
67
67
67
68
>>> memory = Memory.from_blocks([[0, b'ABBBC'], [7, b'CCD']]) >>> memory.block_span(2) (0, 5, 66) >>> memory.block_span(4) (0, 5, 67) >>> memory.block_span(5) (5, 7, None) >>> memory.block_span(10) (10, None, None)
- blocks(start=None, endex=None)[source]
Iterates over blocks.
Iterates over data blocks within an address range.
- Parameters:
- Yields:
(start, memoryview) – Start and data view of each block/slice.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> [[s, bytes(d)] for s, d in memory.blocks()] [[1, b'AB'], [5, b'x'], [7, b'123']] >>> [[s, bytes(d)] for s, d in memory.blocks(2, 9)] [[2, b'B'], [5, b'x'], [7, b'12']] >>> [[s, bytes(d)] for s, d in memory.blocks(3, 5)] []
- bound(start, endex)[source]
Bounds addresses.
It bounds the given addresses to stay within memory limits.
None
is used to ignore a limit for the start or endex directions.In case of stored data,
content_start
andcontent_endex
are used as bounds.In case of bounds limits,
bound_start
orbound_endex
are used as bounds, when notNone
.In case start and endex are in the wrong order, one clamps the other if present (see the Python implementation for details).
- Returns:
tuple of int – Bounded start and endex, closed interval.
Examples
>>> from bytesparse import Memory
>>> Memory().bound(None, None) (0, 0) >>> Memory().bound(None, 100) (0, 100)
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.bound(0, 30) (0, 30) >>> memory.bound(2, 6) (2, 6) >>> memory.bound(None, 6) (1, 6) >>> memory.bound(2, None) (2, 8)
~~~
0
1
2
3
4
5
6
7
8
[[[
[A
B
C]
)))
>>> memory = Memory.from_blocks([[3, b'ABC']], start=1, endex=8) >>> memory.bound(None, None) (1, 8) >>> memory.bound(0, 30) (1, 8) >>> memory.bound(2, 6) (2, 6) >>> memory.bound(2, None) (2, 8) >>> memory.bound(None, 6) (1, 6)
- property bound_endex: int | None
Bounds exclusive end address.
Any data at or after this address is automatically discarded. Disabled if
None
.Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> memory.bound_endex = 10 >>> memory.to_blocks() [[5, b'Hello']]
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5, endex=10) >>> memory.to_blocks() [[5, b'Hello']]
- Type:
int
- property bound_span: Tuple[int | None, int | None]
Bounds span addresses.
A
tuple
holdingbound_start
andbound_endex
.Notes
Assigning
None
toMutableMemory.bound_span
sets bothbound_start
andbound_endex
toNone
(equivalent to(None, None)
).Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> memory.bound_span = (7, 13) >>> memory.to_blocks() [[7, b'llo, W']] >>> memory.bound_span = None >>> memory.bound_span (None, None)
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5, start=7, endex=13) >>> memory.to_blocks() [[7, b'llo, W']]
- Type:
tuple of int
- property bound_start: int | None
Bounds start address.
Any data before this address is automatically discarded. Disabled if
None
.Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> memory.bound_start = 10 >>> memory.to_blocks() [[10, b', World!']]
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5, start=10) >>> memory.to_blocks() [[10, b', World!']]
- Type:
int
- clear(start=None, endex=None)[source]
Clears an address range.
- Parameters:
See also
Examples
>>> from bytesparse import Memory
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
[A]
[y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory.clear(6, 10) >>> memory.to_blocks() [[5, b'A'], [10, b'yz']]
- clear_backup(start=None, endex=None)[source]
Backups a clear() operation.
- Parameters:
- Returns:
ImmutableMemory
– Backup memory region.
See also
- clear_restore(backup)[source]
Restores a clear() operation.
- Parameters:
backup (
ImmutableMemory
) – Backup memory region to restore.
See also
- classmethod collapse_blocks(blocks)[source]
Collapses a generic sequence of blocks.
Given a generic sequence of blocks, writes them in the same order, generating a new sequence of non-contiguous blocks, sorted by address.
- Parameters:
blocks (sequence of blocks) – Sequence of blocks to collapse.
- Returns:
list of blocks – Collapsed block list.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
[0
1
2
3
4
5
6
7
8
9]
[A
B
C
D]
[E
F]
[$]
[x
y
z]
[$
B
C
E
F
5
x
y
z
9]
>>> blocks = [ ... [0, b'0123456789'], ... [0, b'ABCD'], ... [3, b'EF'], ... [0, b'$'], ... [6, b'xyz'], ... ] >>> Memory.collapse_blocks(blocks) [[0, b'$BCEF5xyz9']]
~~~
0
1
2
3
4
5
6
7
8
9
[0
1
2]
[A
B]
[x
y
z]
[$]
[0
$
2]
[A
B
x
y
z]
>>> blocks = [ ... [0, b'012'], ... [4, b'AB'], ... [6, b'xyz'], ... [1, b'$'], ... ] >>> Memory.collapse_blocks(blocks) [[0, b'0$2'], [4, b'ABxyz']]
- content_blocks(block_index_start=None, block_index_endex=None, block_index_step=None)[source]
Iterates over blocks.
Iterates over data blocks within a block index range.
- Parameters:
block_index_start (int) – Inclusive block start index. A negative index is referred to
content_parts
. IfNone
,0
is considered.block_index_endex (int) – Exclusive block end index. A negative index is referred to
content_parts
. IfNone
,content_parts
is considered.block_index_step (int) – Block index step, which can be negative. If
None
,1
is considered.
- Yields:
(start, memoryview) – Start and data view of each block/slice.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> [[s, bytes(d)] for s, d in memory.content_blocks()] [[1, b'AB'], [5, b'x'], [7, b'123']] >>> [[s, bytes(d)] for s, d in memory.content_blocks(1, 2)] [[5, b'x']] >>> [[s, bytes(d)] for s, d in memory.content_blocks(3, 5)] [] >>> [[s, bytes(d)] for s, d in memory.content_blocks(block_index_start=-2)] [[5, b'x'], [7, b'123']] >>> [[s, bytes(d)] for s, d in memory.content_blocks(block_index_endex=-1)] [[1, b'AB'], [5, b'x']] >>> [[s, bytes(d)] for s, d in memory.content_blocks(block_index_step=2)] [[1, b'AB'], [7, b'123']]
- property content_endex: int
Exclusive content end address.
This property holds the exclusive end address of the memory content. By default, it is the current maximmum exclusive end address of the last stored block.
If the memory has no data and no bounds,
start
is returned.Bounds considered only for an empty memory.
Examples
>>> from bytesparse import Memory
>>> Memory().content_endex 0 >>> Memory(endex=8).content_endex 0 >>> Memory(start=1, endex=8).content_endex 1
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.content_endex 8
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
)))
>>> memory = Memory.from_blocks([[1, b'ABC']], endex=8) >>> memory.content_endex 4
- Type:
int
- property content_endin: int
Inclusive content end address.
This property holds the inclusive end address of the memory content. By default, it is the current maximmum inclusive end address of the last stored block.
If the memory has no data and no bounds,
start
minus one is returned.Bounds considered only for an empty memory.
Examples
>>> from bytesparse import Memory
>>> Memory().content_endin -1 >>> Memory(endex=8).content_endin -1 >>> Memory(start=1, endex=8).content_endin 0
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.content_endin 7
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
)))
>>> memory = Memory.from_blocks([[1, b'ABC']], endex=8) >>> memory.content_endin 3
- Type:
int
- content_items(start=None, endex=None)[source]
Iterates over content address and value pairs.
- Parameters:
- Yields:
int – Content address and value pairs.
See also
meth:content_keys meth:content_values
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> dict(memory.content_items()) {1: 65, 2: 66, 5: 120, 7: 49, 8: 50, 9: 51} >>> dict(memory.content_items(2, 9)) {2: 66, 5: 120, 7: 49, 8: 50} >>> dict(memory.content_items(3, 5)) {}
- content_keys(start=None, endex=None)[source]
Iterates over content addresses.
- Parameters:
- Yields:
int – Content addresses.
See also
meth:content_items meth:content_values
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> list(memory.content_keys()) [1, 2, 5, 7, 8, 9] >>> list(memory.content_keys(2, 9)) [2, 5, 7, 8] >>> list(memory.content_keys(3, 5)) []
- property content_parts: int
Number of blocks.
- Returns:
int – The number of blocks.
Examples
>>> from bytesparse import Memory
>>> Memory().content_parts 0
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.content_parts 2
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
)))
>>> memory = Memory.from_blocks([[1, b'ABC']], endex=8) >>> memory.content_parts 1
- property content_size: int
Actual content size.
- Returns:
int – The sum of all block lengths.
Examples
>>> from bytesparse import Memory
>>> Memory().content_size 0 >>> Memory(start=1, endex=8).content_size 0
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.content_size 6
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
)))
>>> memory = Memory.from_blocks([[1, b'ABC']], endex=8) >>> memory.content_size 3
- property content_span: Tuple[int, int]
Memory content address span.
A
tuple
holding bothcontent_start
andcontent_endex
.Examples
>>> from bytesparse import Memory
>>> Memory().content_span (0, 0) >>> Memory(start=1).content_span (1, 1) >>> Memory(endex=8).content_span (0, 0) >>> Memory(start=1, endex=8).content_span (1, 1)
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.content_span (1, 8)
- Type:
tuple of int
- property content_start: int
Inclusive content start address.
This property holds the inclusive start address of the memory content. By default, it is the current minimum inclusive start address of the first stored block.
If the memory has no data and no bounds, 0 is returned.
Bounds considered only for an empty memory.
Examples
>>> from bytesparse import Memory
>>> Memory().content_start 0 >>> Memory(start=1).content_start 1 >>> Memory(start=1, endex=8).content_start 1
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.content_start 1
~~~
0
1
2
3
4
5
6
7
8
[[[
[x
y
z]
>>> memory = Memory.from_blocks([[5, b'xyz']], start=1) >>> memory.content_start 5
- Type:
int
- content_values(start=None, endex=None)[source]
Iterates over content values.
- Parameters:
- Yields:
int – Content values.
See also
meth:content_items meth:content_keys
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> list(memory.content_values()) [65, 66, 120, 49, 50, 51] >>> list(memory.content_values(2, 9)) [66, 120, 49, 50] >>> list(memory.content_values(3, 5)) []
- property contiguous: bool
Contains contiguous data.
The memory is considered to have contiguous data if there is no empty space between blocks.
If bounds are defined, there must be no empty space also towards them.
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> memory.contiguous True
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5) >>> memory.contiguous True
>>> memory = Memory.from_bytes(b'Hello, World!', offset=5, start=1, endex=20) >>> memory.contiguous False
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory.contiguous False
- Type:
bool
- copy()[source]
Creates a deep copy.
- Returns:
ImmutableMemory
– Deep copy.
Examples
>>> from bytesparse import Memory
>>> memory1 = Memory() >>> memory2 = memory1.copy() >>> memory2.bound_span (None, None) >>> memory2.to_blocks() []
>>> memory1 = Memory(start=1, endex=20) >>> memory2 = memory1.copy() >>> memory2.bound_span (1, 20) >>> memory2.to_blocks() []
>>> memory1 = Memory.from_bytes(b'Hello, World!', offset=5) >>> memory2 = memory1.copy() >>> memory2.to_blocks() [[5, b'Hello, World!']]
>>> memory1 = Memory.from_bytes(b'Hello, World!', offset=5, start=1, endex=20) >>> memory2 = memory1.copy() >>> memory2.bound_span (1, 20) >>> memory2.to_blocks() [[5, b'Hello, World!']] >>> memory2.bound_span = (2, 19) >>> memory1 == memory2 True
>>> memory1 = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory2 = memory1.copy() [[5, b'ABC'], [9, b'xyz']] >>> memory1 == memory2 True
- count(item, start=None, endex=None)[source]
Counts items.
- Parameters:
- Returns:
int – The number of items equal to value.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C]
[B
a
t]
[t
a
b]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'Bat'], [9, b'tab']]) >>> memory.count(b'a') 2
- crop(start=None, endex=None)[source]
Keeps data within an address range.
- Parameters:
See also
Examples
>>> from bytesparse import Memory
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
[B
C]
[x]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory.crop(6, 10) >>> memory.to_blocks() [[6, b'BC'], [9, b'x']]
- crop_backup(start=None, endex=None)[source]
Backups a crop() operation.
- Parameters:
- Returns:
ImmutableMemory
pair – Backup memory regions.
See also
- crop_restore(backup_start, backup_endex)[source]
Restores a crop() operation.
- Parameters:
backup_start (
ImmutableMemory
) – Backup memory region to restore at the beginning.backup_endex (
ImmutableMemory
) – Backup memory region to restore at the end.
See also
- cut(start=None, endex=None, bound=True)[source]
Cuts a slice of memory.
- Parameters:
start (int) – Inclusive start address for cutting. If
None
,start
is considered.endex (int) – Exclusive end address for cutting. If
None
,endex
is considered.bound (bool) – The selected address range is applied to the resulting memory as its bounds range. This retains information about any initial and final emptiness of that range, which would be lost otherwise.
- Returns:
Memory
– A copy of the memory from the selected range.
Examples
>>> from bytesparse import Memory
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
[B
C]
[x]
[A]
[y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> taken = memory.cut(6, 10) >>> taken.to_blocks() [[6, b'BC'], [9, b'x']] >>> memory.to_blocks() [[5, b'A'], [10, b'yz']]
- delete(start=None, endex=None)[source]
Deletes an address range.
- Parameters:
See also
Examples
>>> from bytesparse import Memory
4
5
6
7
8
9
10
11
12
13
[A
B
C]
[x
y
z]
[A
y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory.delete(6, 10) >>> memory.to_blocks() [[5, b'Ayz']]
- delete_backup(start=None, endex=None)[source]
Backups a delete() operation.
- Parameters:
- Returns:
ImmutableMemory
– Backup memory region.
See also
- delete_restore(backup)[source]
Restores a delete() operation.
- Parameters:
backup (
ImmutableMemory
) – Backup memory region
See also
- property endex: int
Exclusive end address.
This property holds the exclusive end address of the virtual space. By default, it is the current maximmum exclusive end address of the last stored block.
If
bound_endex
notNone
, that is returned.If the memory has no data and no bounds,
start
is returned.Examples
>>> from bytesparse import Memory
>>> Memory().endex 0
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.endex 8
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
)))
>>> memory = Memory.from_blocks([[1, b'ABC']], endex=8) >>> memory.endex 8
- Type:
int
- property endin: int
Inclusive end address.
This property holds the inclusive end address of the virtual space. By default, it is the current maximmum inclusive end address of the last stored block.
If
bound_endex
notNone
, that minus one is returned.If the memory has no data and no bounds,
start
is returned.Examples
>>> from bytesparse import Memory
>>> Memory().endin -1
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.endin 7
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
)))
>>> memory = Memory.from_blocks([[1, b'ABC']], endex=8) >>> memory.endin 7
- Type:
int
- equal_span(address)[source]
Span of homogeneous data.
It searches for the biggest chunk of data adjacent to the given address, with the same value at that address.
If the address is within a gap, its bounds are returned, and its value is
None
.If the address is before or after any data, bounds are
None
.- Parameters:
address (int) – Reference address.
- Returns:
tuple – Start bound, exclusive end bound, and reference value.
Examples
>>> from bytesparse import Memory
>>> memory = Memory() >>> memory.equal_span(0) (None, None, None)
~~~
0
1
2
3
4
5
6
7
8
9
10
[A
B
B
B
C]
[C
C
D]
65
66
66
66
67
67
67
68
>>> memory = Memory.from_blocks([[0, b'ABBBC'], [7, b'CCD']]) >>> memory.equal_span(2) (1, 4, 66) >>> memory.equal_span(4) (4, 5, 67) >>> memory.equal_span(5) (5, 7, None) >>> memory.equal_span(10) (10, None, None)
- extend(items, offset=0)[source]
Concatenates items.
Appends items after
content_endex
. Equivalent toself += items
.- Parameters:
items (items) – Items to append at the end of the current virtual space.
offset (int) – Optional offset w.r.t.
content_endex
.
See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.extend(b'123') >>> memory.to_blocks() [[1, b'ABC'], [5, b'xyz123']]
~~~
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.extend(range(49, 52), offset=4) >>> memory.to_blocks() [[1, b'ABC'], [5, b'xyz'], [12, b'123']]
~~~
>>> memory1 = Memory.from_blocks([[1, b'ABC']]) >>> memory2 = Memory.from_blocks([[5, b'xyz']]) >>> memory1.extend(memory2) >>> memory1.to_blocks() [[1, b'ABC'], [9, b'xyz']]
- extend_backup(offset=0)[source]
Backups an extend() operation.
- Parameters:
offset (int) – Optional offset w.r.t.
content_endex
.- Returns:
int – Content exclusive end address.
See also
- extend_restore(content_endex)[source]
Restores an extend() operation.
- Parameters:
content_endex (int) – Content exclusive end address to restore.
See also
- extract(start=None, endex=None, pattern=None, step=None, bound=True)[source]
Selects items from a range.
- Parameters:
start (int) – Inclusive start of the extracted range. If
None
,start
is considered.endex (int) – Exclusive end of the extracted range. If
None
,endex
is considered.pattern (items) – Optional pattern of items to fill the emptiness.
step (int) – Optional address stepping between bytes extracted from the range. It has the same meaning of Python’s
slice.step
, but negative steps are ignored. Please note that a step greater than 1 could take much more time to process than the default unitary step.bound (bool) – The selected address range is applied to the resulting memory as its bounds range. This retains information about any initial and final emptiness of that range, which would be lost otherwise.
- Returns:
ImmutableMemory
– A copy of the memory from the selected range.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.extract()._blocks [[1, b'ABCD'], [6, b'$'], [8, b'xyz']] >>> memory.extract(2, 9)._blocks [[2, b'BCD'], [6, b'$'], [8, b'x']] >>> memory.extract(start=2)._blocks [[2, b'BCD'], [6, b'$'], [8, b'xyz']] >>> memory.extract(endex=9)._blocks [[1, b'ABCD'], [6, b'$'], [8, b'x']] >>> memory.extract(5, 8).span (5, 8) >>> memory.extract(pattern=b'.')._blocks [[1, b'ABCD.$.xyz']] >>> memory.extract(pattern=b'.', step=3)._blocks [[1, b'AD.z']]
- fill(start=None, endex=None, pattern=0)[source]
Overwrites a range with a pattern.
- Parameters:
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
[1
2
3
1
2
3
1
2]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> memory.fill(pattern=b'123') >>> memory.to_blocks() [[1, b'12312312']]
~~~
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
[A
B
1
2
3
1
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> memory.fill(3, 7, b'123') >>> memory.to_blocks() [[1, b'AB1231yz']]
- fill_backup(start=None, endex=None)[source]
Backups a fill() operation.
- Parameters:
- Returns:
ImmutableMemory
– Backup memory region.
See also
- fill_restore(backup)[source]
Restores a fill() operation.
- Parameters:
backup (
ImmutableMemory
) – Backup memory region to restore.
See also
- find(item, start=None, endex=None)[source]
Index of an item.
- Parameters:
- Returns:
int – The index of the first item equal to value, or -1.
- flood(start=None, endex=None, pattern=0)[source]
Fills emptiness between non-touching blocks.
- Parameters:
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
[A
B
C
1
2
x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> memory.flood(pattern=b'123') >>> memory.to_blocks() [[1, b'ABC12xyz']]
~~~
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
[A
B
C
2
3
x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> memory.flood(3, 7, b'123') >>> memory.to_blocks() [[1, b'ABC23xyz']]
- flood_backup(start=None, endex=None)[source]
Backups a flood() operation.
- Parameters:
- Returns:
list of open intervals – Backup memory gaps.
See also
- flood_restore(gaps)[source]
Restores a flood() operation.
- Parameters:
gaps (list of open intervals) – Backup memory gaps to restore.
See also
- classmethod from_blocks(blocks, offset=0, start=None, endex=None, copy=True, validate=True)[source]
Creates a virtual memory from blocks.
- Parameters:
blocks (list of blocks) – A sequence of non-overlapping blocks, sorted by address.
offset (int) – Some address offset applied to all the blocks.
start (int) – Optional memory start address. Anything before will be deleted.
endex (int) – Optional memory exclusive end address. Anything at or after it will be deleted.
copy (bool) – Forces copy of provided input data.
validate (bool) – Validates the resulting
ImmutableMemory
object.
- Returns:
ImmutableMemory
– The resulting memory object.- Raises:
ValueError – Some requirements are not satisfied.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> blocks = [[1, b'ABC'], [5, b'xyz']] >>> memory = Memory.from_blocks(blocks) >>> memory.to_blocks() [[1, b'ABC'], [5, b'xyz']] >>> memory = Memory.from_blocks(blocks, offset=3) >>> memory.to_blocks() [[4, b'ABC'], [8, b'xyz']]
~~~
>>> # Loads data from an Intel HEX record file >>> # NOTE: Record files typically require collapsing! >>> import hexrec.records as hr # noqa >>> blocks = hr.load_blocks('records.hex') >>> memory = Memory.from_blocks(Memory.collapse_blocks(blocks)) >>> memory ...
- classmethod from_bytes(data, offset=0, start=None, endex=None, copy=True, validate=True)[source]
Creates a virtual memory from a byte-like chunk.
- Parameters:
data (byte-like data) – A byte-like chunk of data (e.g.
bytes
,bytearray
,memoryview
).offset (int) – Start address of the block of data.
start (int) – Optional memory start address. Anything before will be deleted.
endex (int) – Optional memory exclusive end address. Anything at or after it will be deleted.
copy (bool) – Forces copy of provided input data into the underlying data structure.
validate (bool) – Validates the resulting
ImmutableMemory
object.
- Returns:
ImmutableMemory
– The resulting memory object.- Raises:
ValueError – Some requirements are not satisfied.
See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'') >>> memory.to_blocks() []
~~~
0
1
2
3
4
5
6
7
8
[A
B
C
x
y
z]
>>> memory = Memory.from_bytes(b'ABCxyz', 2) >>> memory.to_blocks() [[2, b'ABCxyz']]
- classmethod from_items(items, offset=0, start=None, endex=None, validate=True)[source]
Creates a virtual memory from a iterable address/byte mapping.
- Parameters:
items (iterable address/byte mapping) – An iterable mapping of address to byte values. Values of
None
are translated as gaps. When an address is stated multiple times, the last is kept.offset (int) – An address offset applied to all the values.
start (int) – Optional memory start address. Anything before will be deleted.
endex (int) – Optional memory exclusive end address. Anything at or after it will be deleted.
validate (bool) – Validates the resulting
ImmutableMemory
object.
- Returns:
ImmutableMemory
– The resulting memory object.- Raises:
ValueError – Some requirements are not satisfied.
See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_values({}) >>> memory.to_blocks() []
~~~
0
1
2
3
4
5
6
7
8
[A
Z]
[x]
>>> items = [ ... (0, ord('A')), ... (1, ord('B')), ... (3, ord('x')), ... (1, ord('Z')), ... ] >>> memory = Memory.from_items(items, offset=2) >>> memory.to_blocks() [[2, b'AZ'], [5, b'x']]
- classmethod from_memory(memory, offset=0, start=None, endex=None, copy=True, validate=True)[source]
Creates a virtual memory from another one.
- Parameters:
memory (Memory) – A
ImmutableMemory
to copy data from.offset (int) – Some address offset applied to all the blocks.
start (int) – Optional memory start address. Anything before will be deleted.
endex (int) – Optional memory exclusive end address. Anything at or after it will be deleted.
copy (bool) – Forces copy of provided input data into the underlying data structure.
validate (bool) – Validates the resulting
MemorImmutableMemory
object.
- Returns:
ImmutableMemory
– The resulting memory object.- Raises:
ValueError – Some requirements are not satisfied.
Examples
>>> from bytesparse import Memory
>>> memory1 = Memory.from_bytes(b'ABC', 5) >>> memory2 = Memory.from_memory(memory1) >>> memory2._blocks [[5, b'ABC']] >>> memory1 == memory2 True >>> memory1 is memory2 False >>> memory1._blocks is memory2._blocks False
~~~
>>> memory1 = Memory.from_bytes(b'ABC', 10) >>> memory2 = Memory.from_memory(memory1, -3) >>> memory2._blocks [[7, b'ABC']] >>> memory1 == memory2 False
~~~
>>> memory1 = Memory.from_bytes(b'ABC', 10) >>> memory2 = Memory.from_memory(memory1, copy=False) >>> all((b1[1] is b2[1]) # compare block data ... for b1, b2 in zip(memory1._blocks, memory2._blocks)) True
- classmethod from_values(values, offset=0, start=None, endex=None, validate=True)[source]
Creates a virtual memory from a byte-like sequence.
- Parameters:
values (iterable byte-like sequence) – An iterable sequence of byte values. Values of
None
are translated as gaps.offset (int) – An address offset applied to all the values.
start (int) – Optional memory start address. Anything before will be deleted.
endex (int) – Optional memory exclusive end address. Anything at or after it will be deleted.
validate (bool) – Validates the resulting
ImmutableMemory
object.
- Returns:
ImmutableMemory
– The resulting memory object.- Raises:
ValueError – Some requirements are not satisfied.
See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_values(range(0)) >>> memory.to_blocks() []
~~~
0
1
2
3
4
5
6
7
8
[A
B
C
D
E]
>>> memory = Memory.from_values(range(ord('A'), ord('F')), offset=2) >>> memory.to_blocks() [[2, b'ABCDE']]
- classmethod fromhex(string)[source]
Creates a virtual memory from an hexadecimal string.
- Parameters:
string (str) – Hexadecimal string.
- Returns:
ImmutableMemory
– The resulting memory object.
Examples
>>> from bytesparse import Memory
>>> memory = Memory.fromhex('') >>> bytes(memory) b''
~~~
>>> memory = Memory.fromhex('48656C6C6F2C20576F726C6421') >>> bytes(memory) b'Hello, World!'
- gaps(start=None, endex=None)[source]
Iterates over block gaps.
Iterates over gaps emptiness bounds within an address range. If a yielded bound is
None
, that direction is infinitely empty (valid before or after global data bounds).- Parameters:
- Yields:
pair of addresses – Block data interval boundaries.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> list(memory.gaps()) [(None, 1), (3, 5), (6, 7), (10, None)] >>> list(memory.gaps(0, 11)) [(0, 1), (3, 5), (6, 7), (10, 11)] >>> list(memory.gaps(*memory.span)) [(3, 5), (6, 7)] >>> list(memory.gaps(2, 6)) [(3, 5)]
- get(address, default=None)[source]
Gets the item at an address.
- Returns:
int – The item at address, default if empty.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.get(3) # -> ord('C') = 67 67 >>> memory.get(6) # -> ord('$') = 36 36 >>> memory.get(10) # -> ord('z') = 122 122 >>> memory.get(0) # -> empty -> default = None None >>> memory.get(7) # -> empty -> default = None None >>> memory.get(11) # -> empty -> default = None None >>> memory.get(0, 123) # -> empty -> default = 123 123 >>> memory.get(7, 123) # -> empty -> default = 123 123 >>> memory.get(11, 123) # -> empty -> default = 123 123
- hex(*args)[source]
Converts into an hexadecimal string.
- Parameters:
sep (str) – Separator string between bytes. Defaults to an emoty string if not provided. Available since Python 3.8.
bytes_per_sep (int) – Number of bytes grouped between separators. Defaults to one byte per group. Available since Python 3.8.
- Returns:
str – Hexadecimal string representation.
- Raises:
ValueError – Data not contiguous (see
contiguous
).
Examples
>>> from bytesparse import Memory
>>> Memory().hex() == '' True
~~~
>>> memory = Memory.from_bytes(b'Hello, World!') >>> memory.hex() 48656c6c6f2c20576f726c6421 >>> memory.hex('.') 48.65.6c.6c.6f.2c.20.57.6f.72.6c.64.21 >>> memory.hex('.', 4) 48.656c6c6f.2c20576f.726c6421
- index(item, start=None, endex=None)[source]
Index of an item.
- Parameters:
- Returns:
int – The index of the first item equal to value.
- Raises:
ValueError – Item not found.
- insert(address, data)[source]
Inserts data.
Inserts data, moving existing items after the insertion address by the size of the inserted data.
- Arguments::
- address (int):
Address of the insertion point.
- data (bytes):
Data to insert.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C]
[x
y
z]
[A
B
C]
[x
y
z]
[$]
[A
B
C]
[x
y
1
z]
[$]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> memory.insert(10, b'$') >>> memory.to_blocks() [[1, b'ABC'], [6, b'xyz'], [10, b'$']] >>> memory.insert(8, b'1') >>> memory.to_blocks() [[1, b'ABC'], [6, b'xy1z'], [11, b'$']]
- insert_backup(address, data)[source]
Backups an insert() operation.
- Parameters:
address (int) – Address of the insertion point.
data (bytes) – Data to insert.
- Returns:
(int,
ImmutableMemory
) – Insertion address, backup memory region.
See also
- insert_restore(address, backup)[source]
Restores an insert() operation.
- Parameters:
address (int) – Address of the insertion point.
backup (
Memory
) – Backup memory region to restore.
See also
- intervals(start=None, endex=None)[source]
Iterates over block intervals.
Iterates over data boundaries within an address range.
- Parameters:
- Yields:
pair of addresses – Block data interval boundaries.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> list(memory.intervals()) [(1, 3), (5, 6), (7, 10)] >>> list(memory.intervals(2, 9)) [(2, 3), (5, 6), (7, 9)] >>> list(memory.intervals(3, 5)) []
- items(start=None, endex=None, pattern=None)[source]
Iterates over address and value pairs.
Iterates over address and value pairs, from start to endex. Implemets the interface of
dict
.- Parameters:
- Yields:
int – Range address and value pairs.
Examples
>>> from bytesparse import Memory
>>> from itertools import islice >>> memory = Memory() >>> list(memory.items(endex=8)) [(0, None), (1, None), (2, None), (3, None), (4, None), (5, None), (6, None), (7, None)] >>> list(memory.items(3, 8)) [(3, None), (4, None), (5, None), (6, None), (7, None)] >>> list(islice(memory.items(3, ...), 7)) [(3, None), (4, None), (5, None), (6, None), (7, None), (8, None), (9, None)]
~~~
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
65
66
67
120
121
122
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> list(memory.items()) [(1, 65), (2, 66), (3, 67), (4, None), (5, None), (6, 120), (7, 121), (8, 122)] >>> list(memory.items(3, 8)) [(3, 67), (4, None), (5, None), (6, 120), (7, 121)] >>> list(islice(memory.items(3, ...), 7)) [(3, 67), (4, None), (5, None), (6, 120), (7, 121), (8, 122), (9, None)]
- keys(start=None, endex=None)[source]
Iterates over addresses.
Iterates over addresses, from start to endex. Implemets the interface of
dict
.- Parameters:
- Yields:
int – Range address.
Examples
>>> from bytesparse import Memory
>>> from itertools import islice >>> memory = Memory() >>> list(memory.keys()) [] >>> list(memory.keys(endex=8)) [0, 1, 2, 3, 4, 5, 6, 7] >>> list(memory.keys(3, 8)) [3, 4, 5, 6, 7] >>> list(islice(memory.keys(3, ...), 7)) [3, 4, 5, 6, 7, 8, 9]
~~~
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> list(memory.keys()) [1, 2, 3, 4, 5, 6, 7, 8] >>> list(memory.keys(endex=8)) [1, 2, 3, 4, 5, 6, 7] >>> list(memory.keys(3, 8)) [3, 4, 5, 6, 7] >>> list(islice(memory.keys(3, ...), 7)) [3, 4, 5, 6, 7, 8, 9]
- peek(address)[source]
Gets the item at an address.
- Returns:
int – The item at address,
None
if empty.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.peek(3) # -> ord('C') = 67 67 >>> memory.peek(6) # -> ord('$') = 36 36 >>> memory.peek(10) # -> ord('z') = 122 122 >>> memory.peek(0) None >>> memory.peek(7) None >>> memory.peek(11) None
- poke(address, item)[source]
Sets the item at an address.
- Parameters:
address (int) – Address of the target item.
item (int or byte) – Item to set,
None
to clear the cell.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.poke(3, b'@') >>> memory.peek(3) # -> ord('@') = 64 64 >>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.poke(5, b'@') >>> memory.peek(5) # -> ord('@') = 64 64
- poke_backup(address)[source]
Backups a poke() operation.
- Parameters:
address (int) – Address of the target item.
- Returns:
(int, int) – address, item at address (
None
if empty).
See also
- poke_restore(address, item)[source]
Restores a poke() operation.
- Parameters:
address (int) – Address of the target item.
item (int or byte) – Item to restore.
See also
- pop(address=None, default=None)[source]
Takes a value away.
- Parameters:
address (int) – Address of the byte to pop. If
None
, the very last byte is popped.default (int) – Value to return if address is within emptiness.
- Returns:
int – Value at address; default within emptiness.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
[A
B
C
D]
[$]
[x
y]
[A
B
D]
[$]
[x
y]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.pop() # -> ord('z') = 122 122 >>> memory.pop(3) # -> ord('C') = 67 67 >>> memory.pop(6, 63) # -> ord('?') = 67 63
- pop_backup(address=None)[source]
Backups a pop() operation.
- Parameters:
address (int) – Address of the byte to pop. If
None
, the very last byte is popped.- Returns:
(int, int) – address, item at address (
None
if empty).
See also
- pop_restore(address, item)[source]
Restores a pop() operation.
- Parameters:
address (int) – Address of the target item.
item (int or byte) – Item to restore,
None
if empty.
See also
- popitem()[source]
Pops the last item.
- Returns:
(int, int) – Address and value of the last item.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A]
[y
z]
>>> memory = Memory.from_blocks([[1, b'A'], [9, b'yz']]) >>> memory.popitem() # -> ord('z') = 122 (10, 122) >>> memory.popitem() # -> ord('y') = 121 (9, 121) >>> memory.popitem() # -> ord('A') = 65 (1, 65) >>> memory.popitem() Traceback (most recent call last): ... KeyError: empty
- popitem_backup()[source]
Backups a popitem() operation.
- Returns:
(int, int) – Address and value of the last item.
See also
- popitem_restore(address, item)[source]
Restores a popitem() operation.
- Parameters:
address (int) – Address of the target item.
item (int or byte) – Item to restore.
See also
- read(address, size)[source]
Reads data.
Reads a chunk of data from an address, with a given size. Data within the range is required to be contiguous.
- Parameters:
address (int) – Start address of the chunk to read.
size (int) – Chunk size.
- Returns:
memoryview
– A view over the addressed chunk.- Raises:
ValueError – Data not contiguous (see
contiguous
).
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> bytes(memory.read(2, 3)) b'BCD' >>> bytes(memory.read(9, 1)) b'y' >>> memory.read(4, 3) Traceback (most recent call last): ... ValueError: non-contiguous data within range >>> memory.read(0, 6) Traceback (most recent call last): ... ValueError: non-contiguous data within range
- readinto(address, buffer)[source]
Reads data into a pre-allocated buffer.
Provided a pre-allocated writable buffer (e.g. a
bytearray
or amemoryview
slice of it), this method reads a chunk of data from an address, with the size of the target buffer. Data within the range is required to be contiguous.- Parameters:
address (int) – Start address of the chunk to read.
buffer (writable) – Pre-allocated buffer to fill with data.
- Returns:
int – Number of bytes read.
- Raises:
ValueError – Data not contiguous (see
contiguous
).
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> buffer = bytearray(3) >>> memory.readinto(2, buffer) 3 >>> buffer bytearray(b'BCD') >>> view = memoryview(buffer) >>> memory.readinto(9, view[1:2]) 1 >>> buffer bytearray(b'ByD') >>> memory.readinto(4, buffer) Traceback (most recent call last): ... ValueError: non-contiguous data within range >>> memory.readinto(0, bytearray(6)) Traceback (most recent call last): ... ValueError: non-contiguous data within range
- remove(item, start=None, endex=None)[source]
Removes an item.
Searches and deletes the first occurrence of an item.
- Parameters:
- Raises:
ValueError – Item not found.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
[A
D]
[$]
[x
y
z]
[A
D]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.remove(b'BC') >>> memory.to_blocks() [[1, b'AD'], [4, b'$'], [6, b'xyz']] >>> memory.remove(ord('$')) >>> memory.to_blocks() [[1, b'AD'], [5, b'xyz']] >>> memory.remove(b'?') Traceback (most recent call last): ... ValueError: subsection not found
- remove_backup(item, start=None, endex=None)[source]
Backups a remove() operation.
- Parameters:
- Returns:
Memory
– Backup memory region.
See also
- remove_restore(backup)[source]
Restores a remove() operation.
- Parameters:
backup (
Memory
) – Backup memory region.
See also
- reserve(address, size)[source]
Inserts emptiness.
Reserves emptiness at the provided address.
- Parameters:
address (int) – Start address of the emptiness to insert.
size (int) – Size of the emptiness to insert.
See also
Examples
>>> from bytesparse import Memory
2
3
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
[A]
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[3, b'ABC'], [7, b'xyz']]) >>> memory.reserve(4, 2) >>> memory.to_blocks() [[3, b'A'], [6, b'BC'], [9, b'xyz']]
~~~
2
3
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
)))
[A
B]
)))
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']], endex=12) >>> memory.reserve(5, 5) >>> memory.to_blocks() [[10, b'AB']]
- reserve_backup(address, size)[source]
Backups a reserve() operation.
- Parameters:
address (int) – Start address of the emptiness to insert.
size (int) – Size of the emptiness to insert.
- Returns:
(int,
ImmutableMemory
) – Reservation address, backup memory region.
See also
- reserve_restore(address, backup)[source]
Restores a reserve() operation.
- Parameters:
address (int) – Address of the reservation point.
backup (
ImmutableMemory
) – Backup memory region to restore.
See also
- reverse()[source]
Reverses the memory in-place.
Data is reversed within the memory
span
.Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
[z
y
x]
[$]
[D
C
B
A]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.reverse() >>> memory.to_blocks() [[1, b'zyx'], [5, b'$'], [7, b'DCBA']]
~~~
0
1
2
3
4
5
6
7
8
9
10
11
[[[
[A
B
C]
)))
[[[
[C
B
A]
)))
>>> memory = Memory.from_bytes(b'ABCD', 3, start=2, endex=10) >>> memory.reverse() >>> memory.to_blocks() [[5, b'CBA']]
- rfind(item, start=None, endex=None)[source]
Index of an item, reversed search.
- Parameters:
- Returns:
int – The index of the last item equal to value, or -1.
- rindex(item, start=None, endex=None)[source]
Index of an item, reversed search.
- Parameters:
- Returns:
int – The index of the last item equal to value.
- Raises:
ValueError – Item not found.
- rvalues(start=None, endex=None, pattern=None)[source]
Iterates over values, reversed order.
Iterates over values, from endex to start.
- Parameters:
- Yields:
int – Range values.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
A
B
C
D
A
65
66
67
68
65
>>> from itertools import islice >>> memory = Memory() >>> list(memory.rvalues(endex=8)) [None, None, None, None, None, None, None, None] >>> list(memory.rvalues(3, 8)) [None, None, None, None, None] >>> list(islice(memory.rvalues(..., 8), 7)) [None, None, None, None, None, None, None] >>> list(memory.rvalues(3, 8, b'ABCD')) [65, 68, 67, 66, 65]
~~~
0
1
2
3
4
5
6
7
8
9
[A
B
C]
<1
2>
[x
y
z]
65
66
67
120
121
122
65
66
67
49
50
120
121
122
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> list(memory.rvalues()) [122, 121, 120, None, None, 67, 66, 65] >>> list(memory.rvalues(3, 8)) [121, 120, None, None, 67] >>> list(islice(memory.rvalues(..., 8), 7)) [121, 120, None, None, 67, 66, 65] >>> list(memory.rvalues(3, 8, b'0123')) [121, 120, 50, 49, 67]
- setdefault(address, default=None)[source]
Defaults a value.
- Parameters:
address (int) – Address of the byte to set.
default (int) – Value to set if address is within emptiness.
- Returns:
int – Value at address; default within emptiness.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> memory.setdefault(3, b'@') # -> ord('C') = 67 67 >>> memory.peek(3) # -> ord('C') = 67 67 >>> memory.setdefault(5, 64) # -> ord('@') = 64 64 >>> memory.peek(5) # -> ord('@') = 64 64 >>> memory.setdefault(9) is None False >>> memory.peek(9) is None False >>> memory.setdefault(7) is None True >>> memory.peek(7) is None True
- setdefault_backup(address)[source]
Backups a setdefault() operation.
- Parameters:
address (int) – Address of the byte to set.
- Returns:
(int, int) – address, item at address (
None
if empty).
See also
- setdefault_restore(address, item)[source]
Restores a setdefault() operation.
- Parameters:
address (int) – Address of the target item.
item (int or byte) – Item to restore,
None
if empty.
See also
- shift(offset)[source]
Shifts the items.
- Parameters:
offset (int) – Signed amount of address shifting.
See also
Examples
>>> from bytesparse import Memory
2
3
4
5
6
7
8
9
10
11
12
[A
B
C]
[x
y
z]
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']]) >>> memory.shift(-2) >>> memory.to_blocks() [[3, b'ABC'], [7, b'xyz']]
~~~
2
3
4
5
6
7
8
9
10
11
12
[[[
[A
B
C]
[x
y
z]
[y
z]
>>> memory = Memory.from_blocks([[5, b'ABC'], [9, b'xyz']], start=3) >>> memory.shift(-8) >>> memory.to_blocks() [[2, b'yz']]
- shift_backup(offset)[source]
Backups a shift() operation.
- Parameters:
offset (int) – Signed amount of address shifting.
- Returns:
(int,
ImmutableMemory
) – Shifting, backup memory region.
See also
- shift_restore(offset, backup)[source]
Restores an shift() operation.
- Parameters:
offset (int) – Signed amount of address shifting.
backup (
ImmutableMemory
) – Backup memory region to restore.
See also
- property span: Tuple[int, int]
Memory address span.
A
tuple
holding bothstart
andendex
.Examples
>>> from bytesparse import Memory
>>> Memory().span (0, 0) >>> Memory(start=1, endex=8).span (1, 8)
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.span (1, 8)
- Type:
tuple of int
- property start: int
Inclusive start address.
This property holds the inclusive start address of the virtual space. By default, it is the current minimum inclusive start address of the first stored block.
If
bound_start
notNone
, that is returned.If the memory has no data and no bounds, 0 is returned.
Examples
>>> from bytesparse import Memory
>>> Memory().start 0
~~~
0
1
2
3
4
5
6
7
8
[A
B
C]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [5, b'xyz']]) >>> memory.start 1
~~~
0
1
2
3
4
5
6
7
8
[[[
[x
y
z]
>>> memory = Memory.from_blocks([[5, b'xyz']], start=1) >>> memory.start 1
- Type:
int
- to_blocks(start=None, endex=None)[source]
Exports into blocks.
Exports data blocks within an address range, converting them into standalone
bytes
objects.- Parameters:
- Returns:
list of blocks – Exported data blocks.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
[A
B]
[x]
[1
2
3]
>>> memory = Memory.from_blocks([[1, b'AB'], [5, b'x'], [7, b'123']]) >>> memory.to_blocks() [[1, b'AB'], [5, b'x'], [7, b'123']] >>> memory.to_blocks(2, 9) [[2, b'B'], [5, b'x'], [7, b'12']] >>> memory.to_blocks(3, 5)] []
- to_bytes(start=None, endex=None)[source]
Exports into bytes.
Exports data within an address range, converting into a standalone
bytes
object.- Parameters:
- Returns:
bytes – Exported data bytes.
See also
Examples
>>> from bytesparse import Memory
>>> memory = Memory.from_bytes(b'') >>> memory.to_bytes() b''
~~~
0
1
2
3
4
5
6
7
8
[A
B
C
x
y
z]
>>> memory = Memory.from_bytes(b'ABCxyz', 2) >>> memory.to_bytes() b'ABCxyz' >>> memory.to_bytes(start=4) b'Cxyz' >>> memory.to_bytes(endex=6) b'ABCx' >>> memory.to_bytes(4, 6) b'Cx'
- update(data, clear=False, **kwargs)[source]
Updates data.
- Parameters:
data (iterable) – Data to update with. Can be either another memory, an (address, value) mapping, or an iterable of (address, value) pairs.
clear (bool) – Clears the target range before writing data. Useful only if data is a
Memory
with empty spaces.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C]
[x
y]
[A
B
C]
[x
y
@]
[A
?
C]
>>> memory = Memory() >>> memory.update(Memory.from_bytes(b'ABC', 5)) >>> memory.to_blocks() [[5, b'ABC']] >>> memory.update({1: b'x', 2: ord('y')}) >>> memory.to_blocks() [[1, b'xy'], [5, b'ABC']] >>> memory.update([(6, b'?'), (3, ord('@'))]) >>> memory.to_blocks() [[1, b'xy@'], [5, b'A?C']]
- update_backup(data, clear=False, **kwargs)[source]
Backups an update() operation.
- Parameters:
data (iterable) – Data to update with. Can be either another memory, an (address, value) mapping, or an iterable of (address, value) pairs.
clear (bool) – Clears the target range before writing data. Useful only if data is a
Memory
with empty spaces.
- Returns:
list of
ImmutableMemory
– Backup memory regions.
See also
- update_restore(backups)[source]
Restores an update() operation.
- Parameters:
backups (list of
ImmutableMemory
) – Backup memory regions to restore.
See also
- validate()[source]
Validates internal structure.
It makes sure that all the allocated blocks are sorted by block start address, and that all the blocks are non-overlapping.
- Raises:
ValueError – Invalid data detected (see exception message).
- values(start=None, endex=None, pattern=None)[source]
Iterates over values.
Iterates over values, from start to endex. Implemets the interface of
dict
.- Parameters:
- Yields:
int – Range values.
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
A
B
C
D
A
65
66
67
68
65
>>> from itertools import islice >>> memory = Memory() >>> list(memory.values(endex=8)) [None, None, None, None, None, None, None, None] >>> list(memory.values(3, 8)) [None, None, None, None, None] >>> list(islice(memory.values(3, ...), 7)) [None, None, None, None, None, None, None] >>> list(memory.values(3, 8, b'ABCD')) [65, 66, 67, 68, 65]
~~~
0
1
2
3
4
5
6
7
8
9
[A
B
C]
<1
2>
[x
y
z]
65
66
67
120
121
122
65
66
67
49
50
120
121
122
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> list(memory.values()) [65, 66, 67, None, None, 120, 121, 122] >>> list(memory.values(3, 8)) [67, None, None, 120, 121] >>> list(islice(memory.values(3, ...), 7)) [67, None, None, 120, 121, 122, None] >>> list(memory.values(3, 8, b'0123')) [67, 49, 50, 120, 121]
- view(start=None, endex=None)[source]
Creates a view over a range.
Creates a memory view over the selected address range. Data within the range is required to be contiguous.
- Parameters:
- Returns:
memoryview
– A view of the selected address range.- Raises:
ValueError – Data not contiguous (see
contiguous
).
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
10
11
[A
B
C
D]
[$]
[x
y
z]
>>> memory = Memory.from_blocks([[1, b'ABCD'], [6, b'$'], [8, b'xyz']]) >>> bytes(memory.view(2, 5)) b'BCD' >>> bytes(memory.view(9, 10)) b'y' >>> memory.view() Traceback (most recent call last): ... ValueError: non-contiguous data within range >>> memory.view(0, 6) Traceback (most recent call last): ... ValueError: non-contiguous data within range
- write(address, data, clear=False)[source]
Writes data.
- Parameters:
address (int) – Address where to start writing data.
data (bytes) – Data to write.
clear (bool) – Clears the target range before writing data. Useful only if data is a
ImmutableMemory
with empty spaces.
See also
Examples
>>> from bytesparse import Memory
0
1
2
3
4
5
6
7
8
9
[A
B
C]
[x
y
z]
[A
B
C]
[1
2
3
z]
>>> memory = Memory.from_blocks([[1, b'ABC'], [6, b'xyz']]) >>> memory.write(5, b'123') >>> memory.to_blocks() [[1, b'ABC'], [5, b'123z']]
- write_backup(address, data, clear=False)[source]
Backups a write() operation.
- Parameters:
address (int) – Address where to start writing data.
data (bytes) – Data to write.
clear (bool) – Clears the target range before writing data. Useful only if data is a
Memory
with empty spaces.
- Returns:
list of
ImmutableMemory
– Backup memory regions.
See also