hexrec.records.Record#
- class hexrec.records.Record(address, tag, data, checksum=Ellipsis)[source]#
Abstract record type.
A record is the basic structure of a record file.
This is an abstract class, so it provides basic generic methods shared by most of the
Record
implementations. Please refer to the actual subclass for more details.- Variables:
address (int) – Tells where its data starts in the memory addressing space, or an address with a special meaning.
tag (int) – Defines the logical meaning of the address and data fields.
data (bytes) – Byte data as required by the tag.
count (int) – Counts its fields as required by the
Record
subclass implementation.checksum (int) – Computes the checksum as required by most
Record
implementations.
- Parameters:
address (int) – Record address field.
tag (int) – Record tag field.
data (bytes) – Record data field.
checksum (int) – Record checksum field.
Ellipsis
makes the constructor compute its actual value automatically.None
assignsNone
.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> BinaryRecord(0x1234, None, b'Hello, World!') ... Record(address=0x00001234, tag=None, count=13, data=b'Hello, World!', checksum=0x69)
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> MotorolaRecord(0x1234, MotorolaTag.DATA_16, b'Hello, World!') ... Record(address=0x00001234, tag=<MotorolaTag.DATA_16: 1>, count=16, data=b'Hello, World!', checksum=0x40)
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> IntelRecord(0x1234, IntelTag.DATA, b'Hello, World!') ... Record(address=0x00001234, tag=<IntelTag.DATA: 0>, count=13, data=b'Hello, World!', checksum=0x44)
Methods
Makes a sequence of data records standalone.
Performs consistency checks.
Consistency check of a sequence of records.
Computes the checksum.
Computes the count.
Fix record tags.
Retrieves metadata from records.
Tells if it is a data record.
Loads blocks from a file.
Loads a virtual memory from a file.
Loads records from a file.
Marshals a record for output.
Checks if overlapping occurs.
Parses a record from a text line.
Reads blocks from a stream.
Reads a virtual memory from a stream.
Reads records from a stream.
Converts to flat addressing.
Saves blocks to a file.
Saves a virtual memory to a file.
Saves records to a file.
Splits a chunk of data into records.
Unmarshals a record from input.
Updates the checksum field via
compute_count()
.Updates the count field via
compute_count()
.Writes blocks to a stream.
Writes a virtual memory to a stream.
Saves records to a stream.
Attributes
tag
count
address
data
checksum
File extensions typically mapped to this record type.
Separator between record lines.
-
EXTENSIONS:
Sequence
[str
] = ()# File extensions typically mapped to this record type.
-
LINE_SEP:
Union
[bytes
,str
] = '\n'# Separator between record lines.
If subclass of
bytes
, it is considered as a binary file.
- __eq__(other)[source]#
Equality comparison.
- Returns:
bool – The address, tag, and data fields are equal.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord.build_data(0, b'Hello, World!') >>> record2 = BinaryRecord.build_data(0, b'Hello, World!') >>> record1 == record2 True
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord.build_data(0, b'Hello, World!') >>> record2 = BinaryRecord.build_data(1, b'Hello, World!') >>> record1 == record2 False
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord.build_data(0, b'Hello, World!') >>> record2 = BinaryRecord.build_data(0, b'hello, world!') >>> record1 == record2 False
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> record1 = MotorolaRecord.build_header(b'Hello, World!') >>> record2 = MotorolaRecord.build_data(0, b'hello, world!') >>> record1 == record2 False
- __hash__()[source]#
Computes the hash value.
Computes the hash of the
Record
fields. Useful to make the record hashable although it is a mutable class.- Returns:
int – Hash of the
Record
fields.
Warning
Be careful with hashable mutable objects!
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> hash(BinaryRecord(0x1234, None, b'Hello, World!')) ... 7668968047460943252
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> hash(MotorolaRecord(0x1234, MotorolaTag.DATA_16, ... b'Hello, World!')) ... 7668968047460943265
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> hash(IntelRecord(0x1234, IntelTag.DATA, b'Hello, World!')) ... 7668968047460943289
- __lt__(other)[source]#
Less-than comparison.
- Returns:
bool – address less than other’s.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord(0x1234, None, b'') >>> record2 = BinaryRecord(0x4321, None, b'') >>> record1 < record2 True
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord(0x4321, None, b'') >>> record2 = BinaryRecord(0x1234, None, b'') >>> record1 < record2 False
- __str__()[source]#
Converts to text string.
Builds a printable text representation of the record, usually the same found in the saved record file as per its
Record
subclass requirements.- Returns:
str – A printable text representation of the record.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> str(BinaryRecord(0x1234, None, b'Hello, World!')) '48656C6C6F2C20576F726C6421'
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> str(MotorolaRecord(0x1234, MotorolaTag.DATA_16, ... b'Hello, World!')) 'S110123448656C6C6F2C20576F726C642140'
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> str(IntelRecord(0x1234, IntelTag.DATA, b'Hello, World!')) ':0D12340048656C6C6F2C20576F726C642144'
- _get_checksum()[source]#
int: The checksum field itself if not
None
, the value computed bycompute_count()
otherwise.
- classmethod _open_input(path)[source]#
Opens a file for input.
- Parameters:
path (str) – File path.
- Returns:
stream – An input stream handle.
- classmethod _open_output(path)[source]#
Opens a file for output.
- Parameters:
path (str) – File path.
- Returns:
stream – An output stream handle.
- classmethod build_standalone(data_records, *args, **kwargs)[source]#
Makes a sequence of data records standalone.
- Parameters:
data_records (list of records) – Sequence of data records.
args (tuple) – Further positional arguments for overriding.
kwargs (dict) – Further keyword arguments for overriding.
- Yields:
record – Records for a standalone record file.
- classmethod check_sequence(records)[source]#
Consistency check of a sequence of records.
- Parameters:
records (list of records) – Sequence of records.
- Raises:
ValueError – A field is inconsistent.
- compute_checksum()[source]#
Computes the checksum.
- Returns:
int – checksum field value based on the current fields.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record = BinaryRecord(0, None, b'Hello, World!') >>> str(record) '48656C6C6F2C20576F726C6421' >>> hex(record.compute_checksum()) '0x69'
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> record = MotorolaRecord(0, MotorolaTag.DATA_16, ... b'Hello, World!') >>> str(record) 'S110000048656C6C6F2C20576F726C642186' >>> hex(record.compute_checksum()) '0x86'
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> record = IntelRecord(0, IntelTag.DATA, b'Hello, World!') >>> str(record) ':0D00000048656C6C6F2C20576F726C64218A' >>> hex(record.compute_checksum()) '0x8a'
- compute_count()[source]#
Computes the count.
- Returns:
bool – count field value based on the current fields.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record = BinaryRecord(0, None, b'Hello, World!') >>> str(record) '48656C6C6F2C20576F726C6421' >>> record.compute_count() 13
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> record = MotorolaRecord(0, MotorolaTag.DATA_16, ... b'Hello, World!') >>> str(record) 'S110000048656C6C6F2C20576F726C642186' >>> record.compute_count() 16
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> record = IntelRecord(0, IntelTag.DATA, b'Hello, World!') >>> str(record) ':0D00000048656C6C6F2C20576F726C64218A' >>> record.compute_count() 13
- classmethod fix_tags(records)[source]#
Fix record tags.
Updates record tags to reflect modified size and count. All the checksums are updated too. Operates in-place.
- Parameters:
records (list of records) – A sequence of records. Must be in-line mutable.
- classmethod get_metadata(records)[source]#
Retrieves metadata from records.
Metadata is specific of each record type. The most common metadata are:
columns: maximum data columns per line.
start: program execution start address.
count: some count of record lines.
header: some header data.
When no such information is found, its keyword is either skipped or its value is
None
.- Parameters:
records (list of records) – Records to scan for metadata.
- Returns:
dict – Collected metadata.
- is_data()[source]#
Tells if it is a data record.
Tells whether the record contains plain binary data, i.e. it is not a special record.
- Returns:
bool – The record contains plain binary data.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> BinaryRecord(0, None, b'Hello, World!').is_data() True
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> MotorolaRecord(0, MotorolaTag.DATA_16, ... b'Hello, World!').is_data() True
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.formats.motorola import Tag as MotorolaTag >>> MotorolaRecord(0, MotorolaTag.HEADER, ... b'Hello, World!').is_data() False
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> IntelRecord(0, IntelTag.DATA, b'Hello, World!').is_data() True
>>> from hexrec.formats.intel import Record as IntelRecord >>> from hexrec.formats.intel import Tag as IntelTag >>> IntelRecord(0, IntelTag.END_OF_FILE, b'').is_data() False
- classmethod load_blocks(path)[source]#
Loads blocks from a file.
Each line of the input file is parsed via
parse_block()
, and collected into the returned sequence.- Parameters:
path (str) – Path of the record file to load.
- Returns:
list of records – Sequence of parsed records.
Example
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> with open('load_blocks.mot', 'wt') as f: ... f.write('S0030000FC\n') ... f.write('S1060000616263D3\n') ... f.write('S1060010646566BA\n') ... f.write('S5030002FA\n') ... f.write('S9030000FC\n') >>> MotorolaRecord.load_blocks('load_blocks.mot') [[0, b'abc'], [16, b'def']]
- classmethod load_memory(path)[source]#
Loads a virtual memory from a file.
- Parameters:
path (str) – Path of the record file to load.
- Returns:
Memory
– Loaded virtual memory.
Example
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> with open('load_blocks.mot', 'wt') as f: ... f.write('S0030000FC\n') ... f.write('S1060000616263D3\n') ... f.write('S1060010646566BA\n') ... f.write('S5030002FA\n') ... f.write('S9030000FC\n') >>> memory = MotorolaRecord.load_memory('load_blocks.mot') >>> memory.to_blocks() [[0, b'abc'], [16, b'def']]
- classmethod load_records(path)[source]#
Loads records from a file.
Each line of the input file is parsed via
parse()
, and collected into the returned sequence.- Parameters:
path (str) – Path of the record file to load.
- Returns:
list of records – Sequence of parsed records.
Example
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> with open('load_records.mot', 'wt') as f: ... f.write('S0030000FC\n') ... f.write('S1060000616263D3\n') ... f.write('S1060010646566BA\n') ... f.write('S5030002FA\n') ... f.write('S9030000FC\n') >>> records = MotorolaRecord.load_records('load_records.mot') >>> records [Record(address=0x00000000, tag=<Tag.HEADER: 0>, count=3, data=b'', checksum=0xFC), Record(address=0x00000000, tag=<Tag.DATA_16: 1>, count=6, data=b'abc', checksum=0xD3), Record(address=0x00000010, tag=<Tag.DATA_16: 1>, count=6, data=b'def', checksum=0xBA), Record(address=0x00000000, tag=<Tag.COUNT_16: 5>, count=3, data=b'\x00\x02', checksum=0xFA), Record(address=0x00000000, tag=<Tag.START_16: 9>, count=3, data=b'', checksum=0xFC)]
- marshal(*args, **kwargs)[source]#
Marshals a record for output.
- Parameters:
args (tuple) – Further positional arguments for overriding.
kwargs (dict) – Further keyword arguments for overriding.
- Returns:
bytes or str – Data for output, according to the file type.
- overlaps(other)[source]#
Checks if overlapping occurs.
This record and another have overlapping data, when both address fields are not
None
.- Parameters:
other (record) – Record to compare with self.
- Returns:
bool – Overlapping.
Examples
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord(0, None, b'abc') >>> record2 = BinaryRecord(1, None, b'def') >>> record1.overlaps(record2) True
>>> from hexrec.formats.binary import Record as BinaryRecord >>> record1 = BinaryRecord(0, None, b'abc') >>> record2 = BinaryRecord(3, None, b'def') >>> record1.overlaps(record2) False
- classmethod parse_record(line, *args, **kwargs)[source]#
Parses a record from a text line.
- Parameters:
line (str) – Record line to parse.
args (tuple) – Further positional arguments for overriding.
kwargs (dict) – Further keyword arguments for overriding.
- Returns:
record – Parsed record.
Note
This method must be overridden.
- classmethod read_blocks(stream)[source]#
Reads blocks from a stream.
Read blocks from the input stream into the returned sequence.
- Parameters:
stream (stream) – Input stream of the blocks to read.
- Returns:
list of blocks – Sequence of parsed blocks.
Example
>>> import io >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> blocks = [[0, b'abc'], [16, b'def']] >>> stream = io.StringIO() >>> MotorolaRecord.write_blocks(stream, blocks) >>> _ = stream.seek(0, io.SEEK_SET) >>> MotorolaRecord.read_blocks(stream) [[0, b'abc'], [16, b'def']]
- classmethod read_memory(stream)[source]#
Reads a virtual memory from a stream.
Read blocks from the input stream into the returned sequence.
- Parameters:
stream (stream) – Input stream of the blocks to read.
- Returns:
Memory
– Loaded virtual memory.
Example
>>> import io >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> blocks = [[0, b'abc'], [16, b'def']] >>> stream = io.StringIO() >>> MotorolaRecord.write_blocks(stream, blocks) >>> _ = stream.seek(0, io.SEEK_SET) >>> memory = MotorolaRecord.read_memory(stream) >>> memory.to_blocks() [[0, b'abc'], [16, b'def']]
- classmethod read_records(stream)[source]#
Reads records from a stream.
For text files, each line of the input file is parsed via
parse()
, and collected into the returned sequence.For binary files, everything to the end of the stream is parsed as a single record.
- Parameters:
stream (stream) – Input stream of the records to read.
- Returns:
list of records – Sequence of parsed records.
Example
>>> import io >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> blocks = [[0, b'abc'], [16, b'def']] >>> stream = io.StringIO() >>> MotorolaRecord.write_blocks(stream, blocks) >>> _ = stream.seek(0, io.SEEK_SET) >>> records = MotorolaRecord.read_records(stream) >>> records [Record(address=0x00000000, tag=<Tag.HEADER: 0>, count=3, data=b'', checksum=0xFC), Record(address=0x00000000, tag=<Tag.DATA_16: 1>, count=6, data=b'abc', checksum=0xD3), Record(address=0x00000010, tag=<Tag.DATA_16: 1>, count=6, data=b'def', checksum=0xBA), Record(address=0x00000000, tag=<Tag.COUNT_16: 5>, count=3, data=b'\x00\x02', checksum=0xFA), Record(address=0x00000000, tag=<Tag.START_16: 9>, count=3, data=b'', checksum=0xFC)]
- classmethod readdress(records)[source]#
Converts to flat addressing.
Some record types, notably the Intel HEX, store records by some segment/offset addressing flavor. As this library adopts flat addressing instead, all the record addresses should be converted to flat addressing after loading. This procedure readdresses a sequence of records in-place.
Warning
Only the address field is modified. All the other fields hold their previous value.
- Parameters:
records (list) – Sequence of records to be converted to flat addressing, in-place.
- classmethod save_blocks(path, blocks, split_args=None, split_kwargs=None, build_args=None, build_kwargs=None)[source]#
Saves blocks to a file.
Each block of the blocks sequence is converted into a record via
build_data()
and written to the output file.- Parameters:
path (str) – Path of the record file to save.
blocks (list of blocks) – Sequence of blocks to store.
split_args (list) – Positional arguments for
Record.split()
.split_kwargs (dict) – Keyword arguments for
Record.split()
.build_args (list) – Positional arguments for
Record.build_standalone()
.build_kwargs (dict) – Keyword arguments for
Record.build_standalone()
.
Example
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> blocks = [[0, b'abc'], [16, b'def']] >>> MotorolaRecord.save_blocks('save_blocks.mot', blocks) >>> with open('save_blocks.mot', 'rt') as f: text = f.read() >>> text 'S0030000FC\nS1060000616263D3\nS1060010646566BA\nS5030002FA\nS9030000FC\n'
- classmethod save_memory(path, memory, split_args=None, split_kwargs=None, build_args=None, build_kwargs=None)[source]#
Saves a virtual memory to a file.
- Parameters:
path (str) – Path of the record file to save.
memory (
Memory
) – Virtual memory to store.split_args (list) – Positional arguments for
Record.split()
.split_kwargs (dict) – Keyword arguments for
Record.split()
.build_args (list) – Positional arguments for
Record.build_standalone()
.build_kwargs (dict) – Keyword arguments for
Record.build_standalone()
.
Example
>>> from hexrec.records import Memory >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> memory = Memory(blocks=[[0, b'abc'], [16, b'def']]) >>> MotorolaRecord.save_memory('save_memory.mot', memory) >>> with open('save_memory.mot', 'rt') as f: text = f.read() >>> text 'S0030000FC\nS1060000616263D3\nS1060010646566BA\nS5030002FA\nS9030000FC\n'
- classmethod save_records(path, records)[source]#
Saves records to a file.
Each record of the records sequence is converted into text via
str()
, and stored into the output text file.- Parameters:
path (str) – Path of the record file to save.
records (list) – Sequence of records to store.
Example
>>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.records import blocks_to_records >>> blocks = [[0, b'abc'], [16, b'def']] >>> records = blocks_to_records(blocks, MotorolaRecord) >>> MotorolaRecord.save_records('save_records.mot', records) >>> with open('save_records.mot', 'rt') as f: text = f.read() >>> text 'S0030000FC\nS1060000616263D3\nS1060010646566BA\nS5030002FA\nS9030000FC\n'
- classmethod split(data, *args, **kwargs)[source]#
Splits a chunk of data into records.
- Parameters:
data (bytes) – Byte data to split.
args (tuple) – Further positional arguments for overriding.
kwargs (dict) – Further keyword arguments for overriding.
- Returns:
list – List of records.
Note
This method must be overridden.
- classmethod unmarshal(data, *args, **kwargs)[source]#
Unmarshals a record from input.
- Parameters:
data (bytes or str) – Input data, according to the file type.
args (tuple) – Further positional arguments for overriding.
kwargs (dict) – Further keyword arguments for overriding.
- Returns:
record – Unmarshaled record.
- update_checksum()[source]#
Updates the checksum field via
compute_count()
.
- update_count()[source]#
Updates the count field via
compute_count()
.
- classmethod write_blocks(stream, blocks, split_args=None, split_kwargs=None, build_args=None, build_kwargs=None)[source]#
Writes blocks to a stream.
Each block of the blocks sequence is converted into a record via
build_data()
and written to the output stream.- Parameters:
stream (stream) – Output stream of the records to write.
blocks (list of blocks) – Sequence of records to store.
split_args (list) – Positional arguments for
Record.split()
.split_kwargs (dict) – Keyword arguments for
Record.split()
.build_args (list) – Positional arguments for
Record.build_standalone()
.build_kwargs (dict) – Keyword arguments for
Record.build_standalone()
.
Example
>>> import io >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> blocks = [[0, b'abc'], [16, b'def']] >>> stream = io.StringIO() >>> MotorolaRecord.write_blocks(stream, blocks) >>> stream.getvalue() 'S0030000FC\nS1060000616263D3\nS1060010646566BA\nS5030002FA\nS9030000FC\n'
- classmethod write_memory(stream, memory, split_args=None, split_kwargs=None, build_args=None, build_kwargs=None)[source]#
Writes a virtual memory to a stream.
- Parameters:
stream (stream) – Output stream of the records to write.
memory (
Memory
) – Virtual memory to save.split_args (list) – Positional arguments for
Record.split()
.split_kwargs (dict) – Keyword arguments for
Record.split()
.build_args (list) – Positional arguments for
Record.build_standalone()
.build_kwargs (dict) – Keyword arguments for
Record.build_standalone()
.
Example
>>> import io >>> from hexrec.records import Memory >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> memory = Memory.from_blocks([[0, b'abc'], [16, b'def']]) >>> stream = io.StringIO() >>> MotorolaRecord.write_memory(stream, memory) >>> stream.getvalue() 'S0030000FC\nS1060000616263D3\nS1060010646566BA\nS5030002FA\nS9030000FC\n'
- classmethod write_records(stream, records)[source]#
Saves records to a stream.
Each record of the records sequence is stored into the output file.
- Parameters:
stream (stream) – Output stream of the records to write.
records (list of records) – Sequence of records to store.
Example
>>> import io >>> from hexrec.formats.motorola import Record as MotorolaRecord >>> from hexrec.records import blocks_to_records >>> blocks = [[0, b'abc'], [16, b'def']] >>> records = blocks_to_records(blocks, MotorolaRecord) >>> stream = io.StringIO() >>> MotorolaRecord.write_records(stream, records) >>> stream.getvalue() 'S0030000FC\nS1060000616263D3\nS1060010646566BA\nS5030002FA\nS9030000FC\n'