mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2024-05-31 18:41:29 +00:00
f1b0f5ebac
* added functions to copy a segment & its base so comments can be marked on the copy of the base and show up in the copy of the segment
278 lines
9.3 KiB
Python
278 lines
9.3 KiB
Python
import os
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
from atrcopy import DefaultSegment, SegmentData, get_xex, interleave_segments, user_bit_mask
|
|
|
|
|
|
def get_indexed(segment, num, scale):
|
|
indexes = np.arange(num) * scale
|
|
raw = segment.rawdata.get_indexed(indexes)
|
|
s = DefaultSegment(raw, segment.start_addr + indexes[0])
|
|
return s, indexes
|
|
|
|
class TestSegment1(object):
|
|
def setup(self):
|
|
self.segments = []
|
|
for i in range(8):
|
|
data = np.arange(1024, dtype=np.uint8) * i
|
|
r = SegmentData(data)
|
|
self.segments.append(DefaultSegment(r, i * 1024))
|
|
|
|
def test_xex(self):
|
|
items = [
|
|
[(0, 1, 2), 0],
|
|
]
|
|
|
|
for indexes, stuff in items:
|
|
s = [self.segments[i] for i in indexes]
|
|
bytes = get_xex(s, 0xbeef)
|
|
assert tuple(bytes[0:2]) == (0xff, 0xff)
|
|
# 2 bytes for the ffff
|
|
# 4 bytes per segment for start, end address
|
|
# An extra segment has been inserted for the run address!
|
|
size = reduce(lambda a, b:a + 4 + len(b), s, 0)
|
|
print size, len(bytes)
|
|
assert len(bytes) == 2 + size
|
|
|
|
def test_copy(self):
|
|
for s in self.segments:
|
|
d = s.rawdata
|
|
print "orig:", d.data.shape, d.is_indexed, d.data, id(d.data)
|
|
c = d.copy()
|
|
print "copy", c.data.shape, c.is_indexed, c.data, id(c.data)
|
|
assert c.data.shape == s.data.shape
|
|
assert id(c) != id(s)
|
|
assert np.all((c.data[:] - s.data[:]) == 0)
|
|
c.data[0:100] = 1
|
|
print d.data
|
|
print c.data
|
|
assert not np.all((c.data[:] - s.data[:]) == 0)
|
|
|
|
|
|
class TestIndexed(object):
|
|
def setup(self):
|
|
data = np.arange(4096, dtype=np.uint8)
|
|
data[1::2] = np.repeat(np.arange(16, dtype=np.uint8), 128)
|
|
r = SegmentData(data)
|
|
self.segment = DefaultSegment(r, 0)
|
|
|
|
def test_indexed(self):
|
|
assert not self.segment.rawdata.is_indexed
|
|
s, indexes = get_indexed(self.segment, 1024, 3)
|
|
assert s.rawdata.is_indexed
|
|
for i in range(len(indexes)):
|
|
assert s.get_raw_index(i) == indexes[i]
|
|
|
|
# get indexed into indexed, will result in every 9th byte
|
|
s2, indexes2 = get_indexed(s, 256, 3)
|
|
assert s2.rawdata.is_indexed
|
|
for i in range(len(indexes2)):
|
|
assert s2.get_raw_index(i) == indexes2[i] * 3
|
|
|
|
def test_indexed_sub(self):
|
|
base = self.segment
|
|
assert not base.rawdata.is_indexed
|
|
raw = base.rawdata[512:1536] # 1024 byte segment
|
|
sub = DefaultSegment(raw, 512)
|
|
|
|
assert not sub.rawdata.is_indexed
|
|
for i in range(len(sub)):
|
|
ri = sub.get_raw_index(i)
|
|
assert ri == sub.start_addr + i
|
|
assert sub[i] == base[ri]
|
|
start, end = sub.byte_bounds_offset()
|
|
assert start == 512
|
|
assert end == 1536
|
|
|
|
with pytest.raises(IndexError) as e:
|
|
# attempt to get indexes to 1024 * 3... Index to big => fail!
|
|
s, indexes = get_indexed(sub, 1024, 3)
|
|
|
|
# try with elements up to 256 * 3
|
|
s, indexes = get_indexed(sub, 256, 3)
|
|
print sub.data
|
|
print indexes
|
|
print s.data[:]
|
|
assert s.rawdata.is_indexed
|
|
for i in range(len(indexes)):
|
|
ri = s.get_raw_index(i)
|
|
print ri, "base[ri]=%d" % base[ri], i, indexes[i], "s[i]=%d" % s[i]
|
|
assert ri == sub.start_addr + indexes[i]
|
|
assert s[i] == base[ri]
|
|
start, end = s.byte_bounds_offset()
|
|
assert start == 0
|
|
assert end == len(base)
|
|
|
|
# get indexed into indexed, will result in every 9th byte
|
|
s2, indexes2 = get_indexed(s, 64, 3)
|
|
assert s2.rawdata.is_indexed
|
|
for i in range(len(indexes2)):
|
|
assert s2.get_raw_index(i) == sub.start_addr + indexes2[i] * 3
|
|
start, end = s.byte_bounds_offset()
|
|
assert start == 0
|
|
assert end == len(base)
|
|
|
|
def test_interleave(self):
|
|
base = self.segment
|
|
r1 = base.rawdata[512:1024] # 512 byte segment
|
|
s1 = DefaultSegment(r1, 512)
|
|
r2 = base.rawdata[1024:1536] # 512 byte segment
|
|
s2 = DefaultSegment(r2, 1024)
|
|
|
|
indexes1 = r1.get_indexes_from_base()
|
|
verify1 = np.arange(512, 1024, dtype=np.uint32)
|
|
assert np.array_equal(indexes1, verify1)
|
|
|
|
indexes2 = r2.get_indexes_from_base()
|
|
verify2 = np.arange(1024, 1536, dtype=np.uint32)
|
|
assert np.array_equal(indexes2, verify2)
|
|
|
|
s = interleave_segments([s1, s2], 2)
|
|
a = np.empty(len(s1) + len(s2), dtype=np.uint8)
|
|
a[0::4] = s1[0::2]
|
|
a[1::4] = s1[1::2]
|
|
a[2::4] = s2[0::2]
|
|
a[3::4] = s2[1::2]
|
|
print list(s[:])
|
|
print list(a[:])
|
|
print s.rawdata.order
|
|
assert np.array_equal(s[:], a)
|
|
|
|
s = interleave_segments([s1, s2], 4)
|
|
a = np.empty(len(s1) + len(s2), dtype=np.uint8)
|
|
a[0::8] = s1[0::4]
|
|
a[1::8] = s1[1::4]
|
|
a[2::8] = s1[2::4]
|
|
a[3::8] = s1[3::4]
|
|
a[4::8] = s2[0::4]
|
|
a[5::8] = s2[1::4]
|
|
a[6::8] = s2[2::4]
|
|
a[7::8] = s2[3::4]
|
|
assert np.array_equal(s[:], a)
|
|
|
|
with pytest.raises(ValueError) as e:
|
|
s = interleave_segments([s1, s2], 3)
|
|
|
|
r1 = base.rawdata[512:1025] # 513 byte segment
|
|
s1 = DefaultSegment(r1, 512)
|
|
r2 = base.rawdata[1024:1537] # 513 byte segment
|
|
s2 = DefaultSegment(r2, 1024)
|
|
s = interleave_segments([s1, s2], 3)
|
|
a = np.empty(len(s1) + len(s2), dtype=np.uint8)
|
|
a[0::6] = s1[0::3]
|
|
a[1::6] = s1[1::3]
|
|
a[2::6] = s1[2::3]
|
|
a[3::6] = s2[0::3]
|
|
a[4::6] = s2[1::3]
|
|
a[5::6] = s2[2::3]
|
|
assert np.array_equal(s[:], a)
|
|
|
|
def test_copy(self):
|
|
s, indexes = get_indexed(self.segment, 1024, 3)
|
|
c = s.rawdata.copy()
|
|
print c.data.shape, c.is_indexed
|
|
print id(c.data.np_data), id(s.data.np_data)
|
|
assert c.data.shape == s.data.shape
|
|
assert id(c) != id(s)
|
|
assert np.all((c.data[:] - s.data[:]) == 0)
|
|
c.data[0:100] = 1
|
|
assert not np.all((c.data[:] - s.data[:]) == 0)
|
|
|
|
|
|
class TestComments(object):
|
|
def setup(self):
|
|
data = np.ones([4000], dtype=np.uint8)
|
|
r = SegmentData(data)
|
|
self.segment = DefaultSegment(r, 0)
|
|
self.sub_segment = DefaultSegment(r[2:202], 2)
|
|
|
|
def test_locations(self):
|
|
s = self.segment
|
|
s.set_comment([[4,5]], "test1")
|
|
s.set_comment([[40,50]], "test2")
|
|
s.set_style_ranges([[2,100]], comment=True)
|
|
s.set_style_ranges([[200, 299]], data=True)
|
|
for i in range(1,4):
|
|
for j in range(1, 4):
|
|
# create some with overlapping regions, some without
|
|
r = [500*j, 500*j + 200*i + 200]
|
|
s.set_style_ranges([r], user=i)
|
|
s.set_user_data([r], i, i*10 + j)
|
|
r = [100, 200]
|
|
s.set_style_ranges([r], user=4)
|
|
s.set_user_data([r], 4, 99)
|
|
r = [3100, 3200]
|
|
s.set_style_ranges([r], user=4)
|
|
s.set_user_data([r], 4, 99)
|
|
|
|
s2 = self.sub_segment
|
|
print len(s2)
|
|
copy = s2.get_comment_locations()
|
|
print copy
|
|
# comments at 4 and 40 in the original means 2 and 38 in the copy
|
|
orig = s.get_comment_locations()
|
|
assert copy[2] == orig[4]
|
|
assert copy[28] == orig[38]
|
|
|
|
def test_split_data_at_comment(self):
|
|
s = self.segment
|
|
s.set_style_ranges([[0,1000]], data=True)
|
|
for i in range(0, len(s), 25):
|
|
s.set_comment([[i,i+1]], "comment at %d" % i)
|
|
|
|
s2 = self.sub_segment
|
|
print len(s2)
|
|
copy = s2.get_comment_locations()
|
|
print copy
|
|
# comments at 4 and 40 in the original means 2 and 38 in the copy
|
|
orig = s.get_comment_locations()
|
|
print orig[0:200]
|
|
assert copy[2] == orig[4]
|
|
assert copy[28] == orig[38]
|
|
|
|
r = s2.get_entire_style_ranges([1], user=True)
|
|
print r
|
|
assert r == [((0, 23), 1), ((23, 48), 1), ((48, 73), 1), ((73, 98), 1), ((98, 123), 1), ((123, 148), 1), ((148, 173), 1), ((173, 198), 1), ((198, 200), 1)]
|
|
|
|
def test_split_data_at_comment2(self):
|
|
s = self.segment
|
|
start = 0
|
|
i = 0
|
|
for end in range(40, 1000, 40):
|
|
s.set_style_ranges([[start, end]], user=i)
|
|
start = end
|
|
i = (i + 1) % 8
|
|
for i in range(0, len(s), 25):
|
|
s.set_comment([[i,i+1]], "comment at %d" % i)
|
|
|
|
s2 = self.sub_segment
|
|
print len(s2)
|
|
copy = s2.get_comment_locations()
|
|
print copy
|
|
# comments at 4 and 40 in the original means 2 and 38 in the copy
|
|
orig = s.get_comment_locations()
|
|
print orig[0:200]
|
|
assert copy[2] == orig[4]
|
|
assert copy[28] == orig[38]
|
|
|
|
r = s2.get_entire_style_ranges([1], user=user_bit_mask)
|
|
print r
|
|
assert r == [((0, 38), 0), ((38, 48), 1), ((48, 73), 1), ((73, 78), 1), ((78, 118), 2), ((118, 158), 3), ((158, 198), 4), ((198, 200), 5)]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
t = TestIndexed()
|
|
t.setup()
|
|
t.test_indexed()
|
|
t.test_indexed_sub()
|
|
t.test_interleave()
|
|
t = TestSegment1()
|
|
t.setup()
|
|
t.test_xex()
|
|
t.test_copy()
|
|
t = TestComments()
|
|
t.setup()
|
|
t.test_split_data_at_comment()
|