Skip to content

Commit

Permalink
small optimizations and code reduction
Browse files Browse the repository at this point in the history
  • Loading branch information
MosesofEgypt committed Jan 24, 2025
1 parent d9c7967 commit 0bd59bd
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 244 deletions.
15 changes: 7 additions & 8 deletions supyr_struct/blocks/array_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from sys import getsizeof

from supyr_struct.blocks.block import Block
from supyr_struct.blocks.list_block import ListBlock
from supyr_struct.blocks.list_block import ListBlock, repeat
from supyr_struct.defs.constants import NAME, UNNAMED, NAME_MAP
from supyr_struct.exceptions import DescEditError, DescKeyError
from supyr_struct.buffer import get_rawdata_context
Expand Down Expand Up @@ -37,7 +37,7 @@ def __init__(self, desc, parent=None, init_attrs=None, **kwargs):
self.parse(init_attrs=init_attrs, **kwargs)
else:
# populate the listblock with the right number of fields
list.__init__(self, [None]*self.get_size())
list.__init__(self, repeat(None, self.get_size()))

def __sizeof__(self, seenset=None):
'''
Expand Down Expand Up @@ -150,10 +150,9 @@ def __delitem__(self, index):
# the descriptor since its list indexes
# aren't attributes, but instanced objects
start, stop, step = index.indices(len(self))
step = -step if step < 0 else step
if start < stop:
start, stop = stop, start
if step > 0:
step = -step

list.__delitem__(self, index)
self.set_size()
Expand Down Expand Up @@ -239,7 +238,7 @@ def extend(self, new_attrs, **kwargs):
index = len(self)

# create new, empty indices
list.extend(self, [None]*new_attrs)
list.extend(self, repeat(None, new_attrs))
# read new sub_structs into the empty indices
for i in range(index, index + new_attrs):
attr_f_type.parser(attr_desc, parent=self,
Expand Down Expand Up @@ -705,10 +704,10 @@ def parse(self, **kwargs):
# parsing/initializing all array elements, so clear and resize
list.__delitem__(self, slice(None, None, None))
if initdata is not None:
list.extend(self, [None]*len(initdata))
list.extend(self, repeat(None, len(initdata)))
self.set_size() # update the size to the initdata length
else:
list.extend(self, [None]*self.get_size())
list.extend(self, repeat(None, self.get_size()))

if rawdata is not None:
# parse the ArrayBlock from raw data
Expand Down Expand Up @@ -798,7 +797,7 @@ def __init__(self, desc, parent=None, steptree=None,
self.parse(init_attrs=init_attrs, **kwargs)
else:
# populate the listblock with the right number of fields
list.__init__(self, [None]*self.get_size())
list.__init__(self, repeat(None, self.get_size()))

def __sizeof__(self, seenset=None):
'''
Expand Down
22 changes: 10 additions & 12 deletions supyr_struct/blocks/list_block.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'''
'''
from copy import deepcopy
from itertools import takewhile
from itertools import repeat, takewhile
from sys import getsizeof

from supyr_struct.blocks.block import Block
Expand Down Expand Up @@ -47,7 +47,7 @@ def __init__(self, desc, parent=None, init_attrs=None, **kwargs):
self.parse(init_attrs=init_attrs, **kwargs)
else:
# populate the listblock with the right number of fields
list.__init__(self, [None]*desc['ENTRIES'])
list.__init__(self, repeat(None, desc['ENTRIES']))

def __str__(self, **kwargs):
'''
Expand Down Expand Up @@ -215,7 +215,7 @@ def __deepcopy__(self, memo):

# clear the Block so it can be populated
list.__delitem__(dup_block, slice(None, None, None))
list.extend(dup_block, [None]*len(self))
list.extend(dup_block, repeat(None, len(self)))

# populate the duplicate
for i in range(len(self)):
Expand Down Expand Up @@ -269,9 +269,9 @@ def __getitem__(self, index):
If index is a string, returns self.__getattr__(index)
'''
if isinstance(index, str):
return self.__getattr__(index)
return list.__getitem__(self, index)
return (self.__getattr__(index) if isinstance(index, str) else
list.__getitem__(self, index)
)

def __setitem__(self, index, new_value):
'''
Expand Down Expand Up @@ -300,8 +300,7 @@ def __setitem__(self, index, new_value):
'''
if isinstance(index, int):
# handle accessing negative indexes
if index < 0:
index += len(self)
index = index + len(self) if index < 0 else index

assert not self.assert_is_valid_field_value(index, new_value)
list.__setitem__(self, index, new_value)
Expand Down Expand Up @@ -332,10 +331,9 @@ def __setitem__(self, index, new_value):

elif isinstance(index, slice):
start, stop, step = index.indices(len(self))
step = -step if step < 0 else step
if start > stop:
start, stop = stop, start
if step < 0:
step = -step

assert hasattr(new_value, '__iter__'), (
"must assign iterable to extended slice")
Expand Down Expand Up @@ -810,7 +808,7 @@ def parse(self, **kwargs):
if kwargs.get("clear", True):
# parsing/initializing all attributes, so clear the block
# and create as many elements as it needs to hold
list.__init__(self, [None]*desc['ENTRIES'])
list.__init__(self, repeat(None, desc['ENTRIES']))

if rawdata is not None:
# parse the ListBlock from raw data
Expand Down Expand Up @@ -899,7 +897,7 @@ def __init__(self, desc, parent=None, steptree=None,
self.parse(init_attrs=init_attrs, **kwargs)
else:
# populate the listblock with the right number of fields
list.__init__(self, [None]*desc['ENTRIES'])
list.__init__(self, repeat(None, desc['ENTRIES']))

def __sizeof__(self, seenset=None):
'''
Expand Down
10 changes: 4 additions & 6 deletions supyr_struct/blocks/while_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
stored anywhere and must be parsed until some function says to stop.
'''
from supyr_struct.blocks.block import Block
from supyr_struct.blocks.list_block import ListBlock
from supyr_struct.blocks.list_block import ListBlock, repeat
from supyr_struct.blocks.array_block import ArrayBlock, PArrayBlock
from supyr_struct.defs.constants import SUB_STRUCT, NAME, UNNAMED
from supyr_struct.exceptions import DescEditError, DescKeyError
Expand Down Expand Up @@ -36,8 +36,7 @@ def __setitem__(self, index, new_value):
'''
if isinstance(index, int):
# handle accessing negative indexes
if index < 0:
index += len(self)
index = index + len(self) if index < 0 else index

assert not self.assert_is_valid_field_value(index, new_value)
list.__setitem__(self, index, new_value)
Expand All @@ -48,10 +47,9 @@ def __setitem__(self, index, new_value):

elif isinstance(index, slice):
start, stop, step = index.indices(len(self))
step = -step if step < 0 else step
if start > stop:
start, stop = stop, start
if step < 0:
step = -step

assert hasattr(new_value, '__iter__'), (
"must assign iterable to extended slice")
Expand Down Expand Up @@ -428,7 +426,7 @@ def parse(self, **kwargs):
raise TypeError("Could not locate the sub-struct descriptor." +
"\nCould not initialize array")

list.extend(self, [None]*init_len)
list.extend(self, repeat(None, init_len))

if kwargs.get('init_attrs', True) or issubclass(attr_f_type.node_cls, Block):
# loop through each element in the array and initialize it
Expand Down
36 changes: 13 additions & 23 deletions supyr_struct/field_type_methods/decoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,9 @@ def decode_decimal(self, rawdata, desc=None, parent=None, attr_index=None):
Returns a Decimal represention of the "rawdata" argument.
'''
if self.endian == '<':
endian = 'little'
else:
endian = 'big'
d_exp = parent.get_meta('DECIMAL_EXP', attr_index)
bigint = str(int.from_bytes(
endian = 'little' if self.endian == '<' else 'big'
d_exp = parent.get_meta('DECIMAL_EXP', attr_index)
bigint = str(int.from_bytes(
rawdata, endian, signed=self.enc.endswith('S')))

return Decimal(bigint[:len(bigint)-d_exp] + '.' +
Expand All @@ -87,11 +84,10 @@ def decode_24bit_numeric(self, rawdata, desc=None,
Returns an int decoded represention of the "rawdata" argument.
'''
if self.endian == '<':
rawint = unpack('<I', rawdata + b'\x00')[0]
else:
rawint = unpack('>I', b'\x00' + rawdata)[0]

rawint = (
unpack('<I', rawdata + b'\x00') if self.endian == '<' else
unpack('>I', b'\x00' + rawdata)
)[0]
# if the int can be signed and IS signed then take care of that
if rawint & 0x800000 and self.enc[1] == 't':
return rawint - 0x1000000 # 0x1000000 == 0x800000 * 2
Expand Down Expand Up @@ -148,20 +144,14 @@ def decode_big_int(self, rawdata, desc=None, parent=None, attr_index=None):
if not len(rawdata):
return 0

if self.endian == '<':
endian = 'little'
else:
endian = 'big'

if self.enc[-1] == 's':
# ones compliment
bigint = int.from_bytes(rawdata, endian, signed=True)
if bigint < 0:
return bigint + 1
return bigint
elif self.enc[-1] == 'S':
endian = 'little' if self.endian == '<' else 'big'
if self.enc[-1] == 'S':
# twos compliment
return int.from_bytes(rawdata, endian, signed=True)
elif self.enc[-1] == 's':
# ones compliment
bigint = int.from_bytes(rawdata, endian, signed=True)
return bigint + (bigint < 0)

return int.from_bytes(rawdata, endian)

Expand Down
22 changes: 8 additions & 14 deletions supyr_struct/field_type_methods/encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ def encode_24bit_numeric(self, node, parent=None, attr_index=None):
# int can be signed
assert node >= -0x800000 and node <= 0x7fffff, (
'%s is too large to pack as a 24bit signed int.' % node)
if node < 0:
# int IS signed
node += 0x1000000
# int IS signed
node += 0x1000000 if node < 0 else 0
else:
assert node >= 0 and node <= 0xffffff, (
'%s is too large to pack as a 24bit unsigned int.' % node)

# pack and return the int
if self.endian == '<':
return pack('<I', node)[0:3]
return pack('>I', node)[1:4]
return (
pack('<I', node)[0:3] if self.endian == '<' else
pack('>I', node)[1:4]
)


def encode_int_timestamp(self, node, parent=None, attr_index=None):
Expand Down Expand Up @@ -148,19 +148,13 @@ def encode_big_int(self, node, parent=None, attr_index=None):
if not bytecount:
return b''

if self.endian == '<':
endian = 'little'
else:
endian = 'big'

endian = 'little' if self.endian == '<' else 'big'
if self.enc[-1] == 'S':
# twos compliment
return node.to_bytes(bytecount, endian, signed=True)
elif self.enc[-1] == 's':
# ones compliment
if node < 0:
return (node-1).to_bytes(bytecount, endian, signed=True)
return node.to_bytes(bytecount, endian, signed=False)
return (node - (node < 0)).to_bytes(bytecount, endian, signed=True)

return node.to_bytes(bytecount, endian)

Expand Down
Loading

0 comments on commit 0bd59bd

Please sign in to comment.