PyNerva 0.0.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nervapy/__init__.py +50 -0
- nervapy/abi.py +91 -0
- nervapy/arm/__init__.py +124 -0
- nervapy/arm/__main__.py +0 -0
- nervapy/arm/abi.py +138 -0
- nervapy/arm/formats.py +49 -0
- nervapy/arm/function.py +2465 -0
- nervapy/arm/generic.py +10796 -0
- nervapy/arm/instructions.py +519 -0
- nervapy/arm/isa.py +409 -0
- nervapy/arm/literal_pool.py +331 -0
- nervapy/arm/microarchitecture.py +211 -0
- nervapy/arm/pseudo.py +652 -0
- nervapy/arm/registers.py +1458 -0
- nervapy/arm/vfpneon.py +4092 -0
- nervapy/arm.py +13 -0
- nervapy/c/__init__.py +1 -0
- nervapy/c/types.py +436 -0
- nervapy/codegen.py +99 -0
- nervapy/common/__init__.py +4 -0
- nervapy/common/function.py +5 -0
- nervapy/common/regalloc.py +121 -0
- nervapy/constant_data.py +282 -0
- nervapy/encoder.py +246 -0
- nervapy/formats/__init__.py +2 -0
- nervapy/formats/elf/__init__.py +4 -0
- nervapy/formats/elf/file.py +178 -0
- nervapy/formats/elf/image.py +106 -0
- nervapy/formats/elf/section.py +422 -0
- nervapy/formats/elf/symbol.py +281 -0
- nervapy/formats/macho/__init__.py +2 -0
- nervapy/formats/macho/file.py +123 -0
- nervapy/formats/macho/image.py +143 -0
- nervapy/formats/macho/section.py +322 -0
- nervapy/formats/macho/symbol.py +158 -0
- nervapy/formats/mscoff/__init__.py +8 -0
- nervapy/formats/mscoff/image.py +132 -0
- nervapy/formats/mscoff/section.py +181 -0
- nervapy/formats/mscoff/symbol.py +148 -0
- nervapy/function.py +136 -0
- nervapy/literal.py +731 -0
- nervapy/loader.py +188 -0
- nervapy/name.py +159 -0
- nervapy/parse.py +52 -0
- nervapy/stream.py +58 -0
- nervapy/util.py +126 -0
- nervapy/writer.py +518 -0
- nervapy/x86_64/__init__.py +324 -0
- nervapy/x86_64/__main__.py +407 -0
- nervapy/x86_64/abi.py +517 -0
- nervapy/x86_64/amd.py +6464 -0
- nervapy/x86_64/avx.py +102029 -0
- nervapy/x86_64/crypto.py +1533 -0
- nervapy/x86_64/encoding.py +424 -0
- nervapy/x86_64/fma.py +19138 -0
- nervapy/x86_64/function.py +2707 -0
- nervapy/x86_64/generic.py +23384 -0
- nervapy/x86_64/instructions.py +500 -0
- nervapy/x86_64/isa.py +476 -0
- nervapy/x86_64/lower.py +126 -0
- nervapy/x86_64/mask.py +2593 -0
- nervapy/x86_64/meta.py +143 -0
- nervapy/x86_64/mmxsse.py +17265 -0
- nervapy/x86_64/nacl.py +327 -0
- nervapy/x86_64/operand.py +1204 -0
- nervapy/x86_64/options.py +21 -0
- nervapy/x86_64/pseudo.py +686 -0
- nervapy/x86_64/registers.py +1225 -0
- nervapy/x86_64/types.py +17 -0
- nervapy/x86_64/uarch.py +580 -0
- pynerva-0.0.7.dist-info/METADATA +310 -0
- pynerva-0.0.7.dist-info/RECORD +74 -0
- pynerva-0.0.7.dist-info/WHEEL +4 -0
- pynerva-0.0.7.dist-info/licenses/LICENSE.rst +15 -0
nervapy/constant_data.py
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ConstantData - Extended Constant class that generates .data sections
|
|
3
|
+
|
|
4
|
+
This module provides ConstantData class that automatically:
|
|
5
|
+
1. Creates a Constant with metadata
|
|
6
|
+
2. Registers itself with the active Function
|
|
7
|
+
3. Generates .data section entries
|
|
8
|
+
4. Provides a label/address for use with LDR instructions
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
from nervapy.constant_data import ConstantData
|
|
12
|
+
|
|
13
|
+
with Function("my_func", ...) as func:
|
|
14
|
+
# Create constant data - automatically added to function
|
|
15
|
+
magic = ConstantData.uint32(0x11111111, name="magic_number")
|
|
16
|
+
|
|
17
|
+
# Use with LDR (label will be generated)
|
|
18
|
+
# Note: You'll need to use raw assembly for LDR =label
|
|
19
|
+
# Or manually construct the address loading
|
|
20
|
+
|
|
21
|
+
# Assembly will include .data section automatically
|
|
22
|
+
print(func.assembly)
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from nervapy.literal import Constant
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConstantData(Constant):
|
|
29
|
+
"""Extended Constant that registers with Function for .data generation"""
|
|
30
|
+
|
|
31
|
+
# Class-level registry of constants per function
|
|
32
|
+
_function_constants: dict[int, list["ConstantData"]] = {}
|
|
33
|
+
|
|
34
|
+
def __init__(self, size, repeats, data, element_ctype, name):
|
|
35
|
+
super().__init__(size, repeats, data, element_ctype, name)
|
|
36
|
+
|
|
37
|
+
# Register with active function
|
|
38
|
+
self._register_with_function()
|
|
39
|
+
|
|
40
|
+
def _register_with_function(self):
|
|
41
|
+
"""Register this constant with the active function"""
|
|
42
|
+
from nervapy.arm.function import active_function
|
|
43
|
+
|
|
44
|
+
if active_function is not None:
|
|
45
|
+
func_id = id(active_function)
|
|
46
|
+
if func_id not in ConstantData._function_constants:
|
|
47
|
+
ConstantData._function_constants[func_id] = []
|
|
48
|
+
ConstantData._function_constants[func_id].append(self)
|
|
49
|
+
|
|
50
|
+
def get_label(self):
|
|
51
|
+
"""Return the label name for this constant"""
|
|
52
|
+
if self.name and len(self.name) > 0:
|
|
53
|
+
if hasattr(self.name[0], 'name'):
|
|
54
|
+
return self.name[0].name
|
|
55
|
+
return str(self.name[0])
|
|
56
|
+
return f"const_{id(self)}"
|
|
57
|
+
|
|
58
|
+
def generate_data_section(self):
|
|
59
|
+
"""Generate .data section assembly for this constant"""
|
|
60
|
+
lines = []
|
|
61
|
+
label = self.get_label()
|
|
62
|
+
lines.append(f"\t.global {label}")
|
|
63
|
+
lines.append(f"\t.type {label}, %object")
|
|
64
|
+
lines.append(f"{label}:")
|
|
65
|
+
|
|
66
|
+
# Determine word size based on element type
|
|
67
|
+
from nervapy.c.types import int64_t, uint64_t
|
|
68
|
+
|
|
69
|
+
if self.element_ctype in [uint64_t, int64_t]:
|
|
70
|
+
# 64-bit values - use .quad or two .word directives
|
|
71
|
+
if self.repeats == 1:
|
|
72
|
+
# Single 64-bit value - split into two 32-bit words (little-endian)
|
|
73
|
+
low = self.data[0] & 0xFFFFFFFF
|
|
74
|
+
high = (self.data[0] >> 32) & 0xFFFFFFFF
|
|
75
|
+
lines.append(f"\t.word 0x{low:08X}, 0x{high:08X}")
|
|
76
|
+
else:
|
|
77
|
+
# Multiple 64-bit values
|
|
78
|
+
words = []
|
|
79
|
+
for val in self.data:
|
|
80
|
+
low = val & 0xFFFFFFFF
|
|
81
|
+
high = (val >> 32) & 0xFFFFFFFF
|
|
82
|
+
words.extend([f"0x{low:08X}", f"0x{high:08X}"])
|
|
83
|
+
lines.append(f"\t.word {', '.join(words)}")
|
|
84
|
+
else:
|
|
85
|
+
# 32-bit or smaller values
|
|
86
|
+
if self.repeats == 1:
|
|
87
|
+
lines.append(f"\t.word 0x{self.data[0]:08X}")
|
|
88
|
+
else:
|
|
89
|
+
words = ", ".join(f"0x{v:08X}" for v in self.data)
|
|
90
|
+
lines.append(f"\t.word {words}")
|
|
91
|
+
|
|
92
|
+
return "\n".join(lines)
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def get_function_constants(function):
|
|
96
|
+
"""Get all constants registered with a function"""
|
|
97
|
+
func_id = id(function)
|
|
98
|
+
return ConstantData._function_constants.get(func_id, [])
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def clear_function_constants(function):
|
|
102
|
+
"""Clear constants for a function (called after generation)"""
|
|
103
|
+
func_id = id(function)
|
|
104
|
+
if func_id in ConstantData._function_constants:
|
|
105
|
+
del ConstantData._function_constants[func_id]
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def generate_all_data_sections(function):
|
|
109
|
+
"""Generate complete .data section for all constants in a function"""
|
|
110
|
+
constants = ConstantData.get_function_constants(function)
|
|
111
|
+
if not constants:
|
|
112
|
+
return ""
|
|
113
|
+
|
|
114
|
+
lines = ["\n\t.data", "\t.align 4"]
|
|
115
|
+
for const in constants:
|
|
116
|
+
lines.append(const.generate_data_section())
|
|
117
|
+
|
|
118
|
+
return "\n".join(lines) + "\n"
|
|
119
|
+
|
|
120
|
+
# Factory methods (same as Constant but return ConstantData)
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def uint32(number, name=None):
|
|
124
|
+
"""Create a 32-bit unsigned integer constant with .data section"""
|
|
125
|
+
from nervapy.name import Name
|
|
126
|
+
from nervapy.parse import parse_assigned_variable_name
|
|
127
|
+
from nervapy.util import is_int, is_int32
|
|
128
|
+
|
|
129
|
+
if not is_int(number):
|
|
130
|
+
raise TypeError(f"The value {number} is not an integer")
|
|
131
|
+
if not is_int32(number):
|
|
132
|
+
raise ValueError(f"The number {number} is not a 32-bit integer")
|
|
133
|
+
|
|
134
|
+
if number < 0:
|
|
135
|
+
number += 0x100000000
|
|
136
|
+
|
|
137
|
+
if name is not None:
|
|
138
|
+
Name.check_name(name)
|
|
139
|
+
name_obj = Name(name=name)
|
|
140
|
+
else:
|
|
141
|
+
import inspect
|
|
142
|
+
name_obj = Name(
|
|
143
|
+
prename=parse_assigned_variable_name(inspect.stack(), "ConstantData.uint32")
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
from nervapy.c.types import uint32_t
|
|
147
|
+
return ConstantData(4, 1, (number,), uint32_t, name_obj)
|
|
148
|
+
|
|
149
|
+
@staticmethod
|
|
150
|
+
def uint32x4(number1, number2=None, number3=None, number4=None, name=None):
|
|
151
|
+
"""Create a 4-element 32-bit unsigned integer array constant"""
|
|
152
|
+
from nervapy.c.types import uint32_t
|
|
153
|
+
from nervapy.name import Name
|
|
154
|
+
from nervapy.parse import parse_assigned_variable_name
|
|
155
|
+
from nervapy.util import is_int, is_int32
|
|
156
|
+
|
|
157
|
+
args = [arg for arg in [number1, number2, number3, number4] if arg is not None]
|
|
158
|
+
if len(args) == 0:
|
|
159
|
+
raise ValueError("At least one constant value must be specified")
|
|
160
|
+
if len(args) != 1 and len(args) != 4:
|
|
161
|
+
raise ValueError("Either 1 or 4 values must be specified")
|
|
162
|
+
|
|
163
|
+
for i, num in enumerate(args):
|
|
164
|
+
if not is_int(num):
|
|
165
|
+
raise TypeError(f"The value {num} is not an integer")
|
|
166
|
+
if not is_int32(num):
|
|
167
|
+
raise ValueError(f"The number {num} is not a 32-bit integer")
|
|
168
|
+
if num < 0:
|
|
169
|
+
args[i] += 0x100000000
|
|
170
|
+
|
|
171
|
+
if len(args) == 1:
|
|
172
|
+
args = [args[0]] * 4
|
|
173
|
+
|
|
174
|
+
if name is not None:
|
|
175
|
+
Name.check_name(name)
|
|
176
|
+
name_obj = Name(name=name)
|
|
177
|
+
else:
|
|
178
|
+
import inspect
|
|
179
|
+
name_obj = Name(
|
|
180
|
+
prename=parse_assigned_variable_name(inspect.stack(), "ConstantData.uint32x4")
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
return ConstantData(16, 4, tuple(args), uint32_t, name_obj)
|
|
184
|
+
|
|
185
|
+
@staticmethod
|
|
186
|
+
def uint64(number, name=None):
|
|
187
|
+
"""Create a 64-bit unsigned integer constant with .data section"""
|
|
188
|
+
from nervapy.c.types import uint64_t
|
|
189
|
+
from nervapy.name import Name
|
|
190
|
+
from nervapy.parse import parse_assigned_variable_name
|
|
191
|
+
from nervapy.util import is_int, is_int64
|
|
192
|
+
|
|
193
|
+
if not is_int(number):
|
|
194
|
+
raise TypeError(f"The value {number} is not an integer")
|
|
195
|
+
if not is_int64(number):
|
|
196
|
+
raise ValueError(f"The number {number} is not a 64-bit integer")
|
|
197
|
+
|
|
198
|
+
if number < 0:
|
|
199
|
+
number += 0x10000000000000000
|
|
200
|
+
|
|
201
|
+
if name is not None:
|
|
202
|
+
Name.check_name(name)
|
|
203
|
+
name_obj = Name(name=name)
|
|
204
|
+
else:
|
|
205
|
+
import inspect
|
|
206
|
+
name_obj = Name(
|
|
207
|
+
prename=parse_assigned_variable_name(inspect.stack(), "ConstantData.uint64")
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return ConstantData(8, 1, (number,), uint64_t, name_obj)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# Note: Auto-patching is done when Function is imported via __init__.py
|
|
214
|
+
# For manual usage, call install_constant_data_support() after importing Function
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def install_constant_data_support():
|
|
218
|
+
"""Install ConstantData support by patching the Function class
|
|
219
|
+
|
|
220
|
+
This enables automatic .data section generation for ConstantData objects.
|
|
221
|
+
Call this after importing Function but before creating any functions.
|
|
222
|
+
|
|
223
|
+
Example:
|
|
224
|
+
from nervapy import *
|
|
225
|
+
from nervapy.arm import *
|
|
226
|
+
from nervapy.constant_data import ConstantData, install_constant_data_support
|
|
227
|
+
|
|
228
|
+
install_constant_data_support() # Enable automatic .data sections
|
|
229
|
+
|
|
230
|
+
with Function(...) as func:
|
|
231
|
+
const = ConstantData.uint32(111, name="my_const")
|
|
232
|
+
...
|
|
233
|
+
"""
|
|
234
|
+
from nervapy.arm.function import Function
|
|
235
|
+
|
|
236
|
+
# Check if already patched
|
|
237
|
+
if hasattr(Function, '_constant_data_patched'):
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
# Save original methods
|
|
241
|
+
original_assembly = Function.assembly.fget
|
|
242
|
+
original_exit = Function.__exit__
|
|
243
|
+
|
|
244
|
+
def patched_assembly(self):
|
|
245
|
+
"""Patched assembly property that appends .data sections"""
|
|
246
|
+
# Get original assembly
|
|
247
|
+
asm = original_assembly(self)
|
|
248
|
+
|
|
249
|
+
# Append .data section if there are constants
|
|
250
|
+
# Note: We check for constants stored on the function instance
|
|
251
|
+
# because they may have been cleared from the global registry
|
|
252
|
+
if hasattr(self, '_constant_data_list'):
|
|
253
|
+
constants = self._constant_data_list
|
|
254
|
+
else:
|
|
255
|
+
constants = ConstantData.get_function_constants(self)
|
|
256
|
+
|
|
257
|
+
if constants:
|
|
258
|
+
lines = ["\n\t.data", "\t.align 4"]
|
|
259
|
+
for const in constants:
|
|
260
|
+
lines.append(const.generate_data_section())
|
|
261
|
+
asm += "\n".join(lines) + "\n"
|
|
262
|
+
|
|
263
|
+
return asm
|
|
264
|
+
|
|
265
|
+
def patched_exit(self, exc_type, exc_value, traceback):
|
|
266
|
+
"""Patched __exit__ that saves constants before cleanup"""
|
|
267
|
+
# Save constants to function instance before clearing global registry
|
|
268
|
+
self._constant_data_list = list(ConstantData.get_function_constants(self))
|
|
269
|
+
|
|
270
|
+
# Call original __exit__
|
|
271
|
+
result = original_exit(self, exc_type, exc_value, traceback)
|
|
272
|
+
|
|
273
|
+
# Clear from global registry (but kept in _constant_data_list)
|
|
274
|
+
ConstantData.clear_function_constants(self)
|
|
275
|
+
|
|
276
|
+
return result
|
|
277
|
+
|
|
278
|
+
# Apply patches
|
|
279
|
+
Function.assembly = property(patched_assembly)
|
|
280
|
+
Function.__exit__ = patched_exit
|
|
281
|
+
Function._constant_data_patched = True
|
|
282
|
+
|
nervapy/encoder.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# This file is part of PeachPy package and is licensed under the Simplified BSD license.
|
|
2
|
+
# See license.rst for the full text of the license.
|
|
3
|
+
|
|
4
|
+
import six
|
|
5
|
+
|
|
6
|
+
from nervapy.abi import Endianness
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Encoder:
|
|
10
|
+
def __init__(self, endianness, bitness=None):
|
|
11
|
+
assert endianness in {Endianness.Little, Endianness.Big}
|
|
12
|
+
if endianness == Endianness.Little:
|
|
13
|
+
self.int16 = Encoder.int16le
|
|
14
|
+
self.uint16 = Encoder.uint16le
|
|
15
|
+
self.int32 = Encoder.int32le
|
|
16
|
+
self.uint32 = Encoder.uint32le
|
|
17
|
+
self.int64 = Encoder.int64le
|
|
18
|
+
self.uint64 = Encoder.uint64le
|
|
19
|
+
else:
|
|
20
|
+
self.int16 = Encoder.int16be
|
|
21
|
+
self.uint16 = Encoder.uint16be
|
|
22
|
+
self.int32 = Encoder.int32be
|
|
23
|
+
self.uint32 = Encoder.uint32be
|
|
24
|
+
self.int64 = Encoder.int64be
|
|
25
|
+
self.uint64 = Encoder.uint64be
|
|
26
|
+
self.bitness = bitness
|
|
27
|
+
if bitness is not None:
|
|
28
|
+
assert bitness in {32, 64}, "Only 32-bit and 64-bit encoders are supported"
|
|
29
|
+
if bitness == 32:
|
|
30
|
+
self.signed_offset = self.int32
|
|
31
|
+
self.unsigned_offset = self.uint32
|
|
32
|
+
else:
|
|
33
|
+
self.signed_offset = self.int64
|
|
34
|
+
self.unsigned_offset = self.uint64
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def int8(n):
|
|
38
|
+
"""Converts signed 8-bit integer to bytearray representation"""
|
|
39
|
+
assert -128 <= n <= 127, (
|
|
40
|
+
"%u can not be represented as an 8-bit signed integer" % n
|
|
41
|
+
)
|
|
42
|
+
return bytearray([n & 0xFF])
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def uint8(n):
|
|
46
|
+
"""Converts unsigned 8-bit integer to bytearray representation"""
|
|
47
|
+
assert 0 <= n <= 255, (
|
|
48
|
+
"%u can not be represented as an 8-bit unsigned integer" % n
|
|
49
|
+
)
|
|
50
|
+
return bytearray([n])
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def int16le(n):
|
|
54
|
+
"""Converts signed 16-bit integer to little-endian bytearray representation"""
|
|
55
|
+
assert -32768 <= n <= 32767, (
|
|
56
|
+
"%u can not be represented as a 16-bit signed integer" % n
|
|
57
|
+
)
|
|
58
|
+
return bytearray([n & 0xFF, (n >> 8) & 0xFF])
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def int16be(n):
|
|
62
|
+
"""Converts signed 16-bit integer to big-endian bytearray representation"""
|
|
63
|
+
assert -32768 <= n <= 32767, (
|
|
64
|
+
"%u can not be represented as a 16-bit signed integer" % n
|
|
65
|
+
)
|
|
66
|
+
return bytearray([n >> 8, (n & 0xFF) & 0xFF])
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def uint16le(n):
|
|
70
|
+
"""Converts unsigned 16-bit integer to little-endian bytearray representation"""
|
|
71
|
+
assert 0 <= n <= 65535, (
|
|
72
|
+
"%u can not be represented as a 16-bit unsigned integer" % n
|
|
73
|
+
)
|
|
74
|
+
return bytearray([n & 0xFF, n >> 8])
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def uint16be(n):
|
|
78
|
+
"""Converts unsigned 16-bit integer to big-endian bytearray representation"""
|
|
79
|
+
assert 0 <= n <= 65535, (
|
|
80
|
+
"%u can not be represented as a 16-bit unsigned integer" % n
|
|
81
|
+
)
|
|
82
|
+
return bytearray([n >> 8, n & 0xFF])
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def int32le(n):
|
|
86
|
+
"""Converts signed 32-bit integer to little-endian bytearray representation"""
|
|
87
|
+
assert -2147483648 <= n <= 2147483647, (
|
|
88
|
+
"%u can not be represented as a 32-bit signed integer" % n
|
|
89
|
+
)
|
|
90
|
+
return bytearray(
|
|
91
|
+
[n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF, (n >> 24) & 0xFF]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def int32be(n):
|
|
96
|
+
"""Converts signed 32-bit integer to big-endian bytearray representation"""
|
|
97
|
+
assert -2147483648 <= n <= 2147483647, (
|
|
98
|
+
"%u can not be represented as a 32-bit signed integer" % n
|
|
99
|
+
)
|
|
100
|
+
return bytearray(
|
|
101
|
+
[(n >> 24) & 0xFF, (n >> 16) & 0xFF, (n >> 8) & 0xFF, n & 0xFF]
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def uint32le(n):
|
|
106
|
+
"""Converts unsigned 32-bit integer to little-endian bytearray representation"""
|
|
107
|
+
assert 0 <= n <= 4294967295, (
|
|
108
|
+
"%u can not be represented as a 32-bit unsigned integer" % n
|
|
109
|
+
)
|
|
110
|
+
return bytearray([n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF, n >> 24])
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def uint32be(n):
|
|
114
|
+
"""Converts unsigned 32-bit integer to big-endian bytearray representation"""
|
|
115
|
+
assert 0 <= n <= 4294967295, (
|
|
116
|
+
"%u can not be represented as a 32-bit unsigned integer" % n
|
|
117
|
+
)
|
|
118
|
+
return bytearray([n >> 24, (n >> 16) & 0xFF, (n >> 8) & 0xFF, n & 0xFF])
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def int64le(n):
|
|
122
|
+
"""Converts signed 64-bit integer to little-endian bytearray representation"""
|
|
123
|
+
assert -9223372036854775808 <= n <= 9223372036854775807, (
|
|
124
|
+
"%u can not be represented as a 64-bit signed integer" % n
|
|
125
|
+
)
|
|
126
|
+
return bytearray(
|
|
127
|
+
[
|
|
128
|
+
n & 0xFF,
|
|
129
|
+
(n >> 8) & 0xFF,
|
|
130
|
+
(n >> 16) & 0xFF,
|
|
131
|
+
(n >> 24) & 0xFF,
|
|
132
|
+
(n >> 32) & 0xFF,
|
|
133
|
+
(n >> 40) & 0xFF,
|
|
134
|
+
(n >> 48) & 0xFF,
|
|
135
|
+
(n >> 56) & 0xFF,
|
|
136
|
+
]
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
@staticmethod
|
|
140
|
+
def int64be(n):
|
|
141
|
+
"""Converts signed 64-bit integer to big-endian bytearray representation"""
|
|
142
|
+
assert -9223372036854775808 <= n <= 9223372036854775807, (
|
|
143
|
+
"%u can not be represented as a 64-bit signed integer" % n
|
|
144
|
+
)
|
|
145
|
+
return bytearray(
|
|
146
|
+
[
|
|
147
|
+
(n >> 56) & 0xFF,
|
|
148
|
+
(n >> 48) & 0xFF,
|
|
149
|
+
(n >> 40) & 0xFF,
|
|
150
|
+
(n >> 32) & 0xFF,
|
|
151
|
+
(n >> 24) & 0xFF,
|
|
152
|
+
(n >> 16) & 0xFF,
|
|
153
|
+
(n >> 8) & 0xFF,
|
|
154
|
+
n & 0xFF,
|
|
155
|
+
]
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def uint64le(n):
|
|
160
|
+
"""Converts unsigned 64-bit integer to little-endian bytearray representation"""
|
|
161
|
+
assert 0 <= n <= 18446744073709551615, (
|
|
162
|
+
"%u can not be represented as a 64-bit unsigned integer" % n
|
|
163
|
+
)
|
|
164
|
+
return bytearray(
|
|
165
|
+
[
|
|
166
|
+
n & 0xFF,
|
|
167
|
+
(n >> 8) & 0xFF,
|
|
168
|
+
(n >> 16) & 0xFF,
|
|
169
|
+
(n >> 24) & 0xFF,
|
|
170
|
+
(n >> 32) & 0xFF,
|
|
171
|
+
(n >> 40) & 0xFF,
|
|
172
|
+
(n >> 48) & 0xFF,
|
|
173
|
+
(n >> 56) & 0xFF,
|
|
174
|
+
]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
@staticmethod
|
|
178
|
+
def uint64be(n):
|
|
179
|
+
"""Converts unsigned 64-bit integer to big-endian bytearray representation"""
|
|
180
|
+
assert 0 <= n <= 18446744073709551615, (
|
|
181
|
+
"%u can not be represented as a 64-bit unsigned integer" % n
|
|
182
|
+
)
|
|
183
|
+
return bytearray(
|
|
184
|
+
[
|
|
185
|
+
(n >> 56) & 0xFF,
|
|
186
|
+
(n >> 48) & 0xFF,
|
|
187
|
+
(n >> 40) & 0xFF,
|
|
188
|
+
(n >> 32) & 0xFF,
|
|
189
|
+
(n >> 24) & 0xFF,
|
|
190
|
+
(n >> 16) & 0xFF,
|
|
191
|
+
(n >> 8) & 0xFF,
|
|
192
|
+
n & 0xFF,
|
|
193
|
+
]
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
def int16(self, n):
|
|
197
|
+
"""Converts signed 16-bit integer to bytearray representation according to encoder endianness"""
|
|
198
|
+
pass
|
|
199
|
+
|
|
200
|
+
def uint16(self, n):
|
|
201
|
+
"""Converts unsigned 16-bit integer to bytearray representation according to encoder endianness"""
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
def int32(self, n):
|
|
205
|
+
"""Converts signed 32-bit integer to bytearray representation according to encoder endianness"""
|
|
206
|
+
pass
|
|
207
|
+
|
|
208
|
+
def uint32(self, n):
|
|
209
|
+
"""Converts unsigned 32-bit integer to bytearray representation according to encoder endianness"""
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
def int64(self, n):
|
|
213
|
+
"""Converts signed 64-bit integer to bytearray representation according to encoder endianness"""
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
def uint64(self, n):
|
|
217
|
+
"""Converts unsigned 64-bit integer to bytearray representation according to encoder endianness"""
|
|
218
|
+
pass
|
|
219
|
+
|
|
220
|
+
@staticmethod
|
|
221
|
+
def fixed_string(string, size):
|
|
222
|
+
"""Converts string to fixed-length bytearray representation"""
|
|
223
|
+
assert isinstance(size, six.integer_types) and size > 0, (
|
|
224
|
+
"size %u is not a positive integer" % size
|
|
225
|
+
)
|
|
226
|
+
if string is None:
|
|
227
|
+
return bytearray(size)
|
|
228
|
+
import codecs
|
|
229
|
+
|
|
230
|
+
byte_string = codecs.encode(string, "utf8")
|
|
231
|
+
if len(byte_string) > size:
|
|
232
|
+
raise ValueError("The length of %s exceeds the target %d" % (string, size))
|
|
233
|
+
elif len(byte_string) == size:
|
|
234
|
+
return byte_string
|
|
235
|
+
else:
|
|
236
|
+
return byte_string + bytearray(size - len(byte_string))
|
|
237
|
+
|
|
238
|
+
def signed_offset(self, n):
|
|
239
|
+
"""Converts signed integer offset to bytearray representation according to encoder bitness and endianness"""
|
|
240
|
+
raise ValueError("Can not encode signed offset: encoder bitness not specified")
|
|
241
|
+
|
|
242
|
+
def unsigned_offset(self, n):
|
|
243
|
+
"""Converts unsigned integer offset to bytearray representation according to encoder bitness and endianness"""
|
|
244
|
+
raise ValueError(
|
|
245
|
+
"Can not encode unsigned offset: encoder bitness not specified"
|
|
246
|
+
)
|