RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
reader.cc
1
2#include <cppunit/extensions/HelperMacros.h>
3#include <cppunit/TestFixture.h>
4#include <string>
5#include <sstream>
6
7#include "../../src/linker/reader.h"
8
9using namespace Linker;
10
11// TODO: also check for windowed reads
12
13namespace UnitTests
14{
15
16class TestReader : public CppUnit::TestFixture
17{
18 CPPUNIT_TEST_SUITE(TestReader);
19 CPPUNIT_TEST(testReadData);
20 CPPUNIT_TEST(testReadBinaryData);
21 CPPUNIT_TEST(testReadInteger);
22 CPPUNIT_TEST(testSeekSkip);
23 CPPUNIT_TEST_SUITE_END();
24private:
25 void testReadData();
26 void testReadBinaryData();
27 void testReadInteger();
28 void testSeekSkip();
29
30 std::string readData(std::string payload);
31 uint64_t readInteger(std::string payload, ::EndianType endiantype, bool isSigned = false);
32 uint64_t parseInteger(std::string buffer, ::EndianType endiantype, bool isSigned = false);
33public:
34 void setUp() override;
35 void tearDown() override;
36};
37
38std::string TestReader::readData(std::string payload)
39{
40 char buffer[payload.size()];
41 std::istringstream * iss = new std::istringstream(payload);
42
43 Reader * reader = new Reader(::LittleEndian, iss);
44 reader->ReadData(sizeof buffer, buffer);
45 std::string result = std::string(buffer, sizeof buffer);
46 CPPUNIT_ASSERT_EQUAL(payload, result);
47 delete reader;
48 delete iss;
49 return result;
50}
51
52void TestReader::testReadData()
53{
54 char payload[] = "Test data loaded successfully";
55 std::string payload_string(payload, sizeof payload - 1);
56 readData(payload_string);
57}
58
59void TestReader::testReadBinaryData()
60{
61 char payload[256];
62 for(int i = 0; i < 256; i++)
63 {
64 payload[i] = 0xD5 ^ i;
65 }
66 std::string payload_string(payload, sizeof payload - 1);
67 readData(payload_string);
68}
69
70uint64_t TestReader::readInteger(std::string payload, ::EndianType endiantype, bool isSigned)
71{
72 std::istringstream * iss = new std::istringstream(payload);
73 Reader * reader = new Reader(endiantype, iss);
74
75 uint64_t result =
76 isSigned
77 ? reader->ReadSigned(payload.size(), endiantype)
78 : reader->ReadUnsigned(payload.size(), endiantype);
79 delete reader;
80 delete iss;
81
82 return result;
83}
84
85uint64_t TestReader::parseInteger(std::string buffer, ::EndianType endiantype, bool isSigned)
86{
87 return readInteger(buffer, endiantype, isSigned);
88}
89
90void TestReader::testReadInteger()
91{
92 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12), parseInteger(std::string("\x12", 1), ::LittleEndian));
93 CPPUNIT_ASSERT_EQUAL(uint64_t(0x89), parseInteger(std::string("\x89", 1), ::LittleEndian));
94 CPPUNIT_ASSERT_EQUAL(uint64_t(0x3412), parseInteger(std::string("\x12\x34", 2), ::LittleEndian));
95 CPPUNIT_ASSERT_EQUAL(uint64_t(0x8912), parseInteger(std::string("\x12\x89", 2), ::LittleEndian));
96 CPPUNIT_ASSERT_EQUAL(uint64_t(0x563412), parseInteger(std::string("\x12\x34\x56", 3), ::LittleEndian));
97 CPPUNIT_ASSERT_EQUAL(uint64_t(0x893412), parseInteger(std::string("\x12\x34\x89", 3), ::LittleEndian));
98 CPPUNIT_ASSERT_EQUAL(uint64_t(0x78563412), parseInteger(std::string("\x12\x34\x56\x78", 4), ::LittleEndian));
99 CPPUNIT_ASSERT_EQUAL(uint64_t(0x89563412), parseInteger(std::string("\x12\x34\x56\x89", 4), ::LittleEndian));
100 CPPUNIT_ASSERT_EQUAL(uint64_t(0xF1DEBC9A78563412), parseInteger(std::string("\x12\x34\x56\x78\x9A\xBC\xDE\xF1", 8), ::LittleEndian));
101
102 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12), parseInteger(std::string("\x12", 1), ::BigEndian));
103 CPPUNIT_ASSERT_EQUAL(uint64_t(0x89), parseInteger(std::string("\x89", 1), ::BigEndian));
104 CPPUNIT_ASSERT_EQUAL(uint64_t(0x1234), parseInteger(std::string("\x12\x34", 2), ::BigEndian));
105 CPPUNIT_ASSERT_EQUAL(uint64_t(0x8934), parseInteger(std::string("\x89\x34", 2), ::BigEndian));
106 CPPUNIT_ASSERT_EQUAL(uint64_t(0x123456), parseInteger(std::string("\x12\x34\x56", 3), ::BigEndian));
107 CPPUNIT_ASSERT_EQUAL(uint64_t(0x893456), parseInteger(std::string("\x89\x34\x56", 3), ::BigEndian));
108 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12345678), parseInteger(std::string("\x12\x34\x56\x78", 4), ::BigEndian));
109 CPPUNIT_ASSERT_EQUAL(uint64_t(0x89345678), parseInteger(std::string("\x89\x34\x56\x78", 4), ::BigEndian));
110 CPPUNIT_ASSERT_EQUAL(uint64_t(0x123456789ABCDEF1), parseInteger(std::string("\x12\x34\x56\x78\x9A\xBC\xDE\xF1", 8), ::BigEndian));
111
112 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12), parseInteger(std::string("\x12", 1), ::PDP11Endian));
113 CPPUNIT_ASSERT_EQUAL(uint64_t(0x89), parseInteger(std::string("\x89", 1), ::PDP11Endian));
114 CPPUNIT_ASSERT_EQUAL(uint64_t(0x3412), parseInteger(std::string("\x12\x34", 2), ::PDP11Endian));
115 CPPUNIT_ASSERT_EQUAL(uint64_t(0x8912), parseInteger(std::string("\x12\x89", 2), ::PDP11Endian));
116 CPPUNIT_ASSERT_EQUAL(uint64_t(0x34127856), parseInteger(std::string("\x12\x34\x56\x78", 4), ::PDP11Endian));
117 CPPUNIT_ASSERT_EQUAL(uint64_t(0x89127856), parseInteger(std::string("\x12\x89\x56\x78", 4), ::PDP11Endian));
118
119 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12), parseInteger(std::string("\x12", 1), ::LittleEndian, true));
120 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x100 | 0x89), parseInteger(std::string("\x89", 1), ::LittleEndian, true));
121 CPPUNIT_ASSERT_EQUAL(uint64_t(0x3412), parseInteger(std::string("\x12\x34", 2), ::LittleEndian, true));
122 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x10000 | 0x8912), parseInteger(std::string("\x12\x89", 2), ::LittleEndian, true));
123 CPPUNIT_ASSERT_EQUAL(uint64_t(0x563412), parseInteger(std::string("\x12\x34\x56", 3), ::LittleEndian, true));
124 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x1000000 | 0x893412), parseInteger(std::string("\x12\x34\x89", 3), ::LittleEndian, true));
125 CPPUNIT_ASSERT_EQUAL(uint64_t(0x78563412), parseInteger(std::string("\x12\x34\x56\x78", 4), ::LittleEndian, true));
126 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x100000000 | 0x89563412), parseInteger(std::string("\x12\x34\x56\x89", 4), ::LittleEndian, true));
127 CPPUNIT_ASSERT_EQUAL(uint64_t(0xF1DEBC9A78563412), parseInteger(std::string("\x12\x34\x56\x78\x9A\xBC\xDE\xF1", 8), ::LittleEndian, true));
128
129 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12), parseInteger(std::string("\x12", 1), ::BigEndian, true));
130 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x100 | 0x89), parseInteger(std::string("\x89", 1), ::BigEndian, true));
131 CPPUNIT_ASSERT_EQUAL(uint64_t(0x1234), parseInteger(std::string("\x12\x34", 2), ::BigEndian, true));
132 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x10000 | 0x8934), parseInteger(std::string("\x89\x34", 2), ::BigEndian, true));
133 CPPUNIT_ASSERT_EQUAL(uint64_t(0x123456), parseInteger(std::string("\x12\x34\x56", 3), ::BigEndian, true));
134 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x1000000 |0x893456), parseInteger(std::string("\x89\x34\x56", 3), ::BigEndian, true));
135 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12345678), parseInteger(std::string("\x12\x34\x56\x78", 4), ::BigEndian, true));
136 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x100000000 | 0x89345678), parseInteger(std::string("\x89\x34\x56\x78", 4), ::BigEndian, true));
137 CPPUNIT_ASSERT_EQUAL(uint64_t(0x123456789ABCDEF1), parseInteger(std::string("\x12\x34\x56\x78\x9A\xBC\xDE\xF1", 8), ::BigEndian, true));
138
139 CPPUNIT_ASSERT_EQUAL(uint64_t(0x12), parseInteger(std::string("\x12", 1), ::PDP11Endian, true));
140 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x100 | 0x89), parseInteger(std::string("\x89", 1), ::PDP11Endian, true));
141 CPPUNIT_ASSERT_EQUAL(uint64_t(0x3412), parseInteger(std::string("\x12\x34", 2), ::PDP11Endian, true));
142 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x10000 | 0x8912), parseInteger(std::string("\x12\x89", 2), ::PDP11Endian, true));
143 CPPUNIT_ASSERT_EQUAL(uint64_t(0x34127856), parseInteger(std::string("\x12\x34\x56\x78", 4), ::PDP11Endian, true));
144 CPPUNIT_ASSERT_EQUAL(uint64_t(-0x100000000 | 0x89127856), parseInteger(std::string("\x12\x89\x56\x78", 4), ::PDP11Endian, true));
145}
146
147void TestReader::testSeekSkip()
148{
149 char payload[256];
150 char buffer[1];
151 for(int i = 0; i < 256; i++)
152 {
153 payload[i] = i;
154 }
155
156 std::string payload_string(payload, sizeof payload);
157 std::istringstream * iss = new std::istringstream(payload_string);
158 Reader * reader = new Reader(::LittleEndian, iss);
159
160 reader->Seek(123);
161 reader->ReadData(1, buffer);
162 CPPUNIT_ASSERT_EQUAL(123, int(static_cast<unsigned char>(buffer[0])));
163
164 reader->Skip(45);
165 reader->ReadData(1, buffer);
166 CPPUNIT_ASSERT_EQUAL(123 + 1 + 45, int(static_cast<unsigned char>(buffer[0])));
167
168 delete reader;
169 delete iss;
170}
171
172void TestReader::setUp()
173{
174}
175
176void TestReader::tearDown()
177{
178}
179
180}
181
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
void Skip(offset_t offset)
Jump to a distance in the input stream.
Definition reader.cc:120
void Seek(offset_t offset)
Jump to a specific location in the input stream.
Definition reader.cc:110
uint64_t ReadSigned(size_t bytes, EndianType endiantype)
Read a signed word.
Definition reader.cc:98
void ReadData(size_t count, void *data)
Read in a sequence of bytes.
Definition reader.cc:30
uint64_t ReadUnsigned(size_t bytes, EndianType endiantype)
Read an unsigned word.
Definition reader.cc:86
Definition reader.cc:17