blob: 3b1d64e56bf43f900bd9cbf18a481bf69f8825c2 [file] [log] [blame]
shaneajge6d3a612020-07-23 18:40:28 -04001// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#include "pw_hdlc_lite/encoder.h"
16
17#include <algorithm>
18#include <array>
19#include <cstddef>
20
21#include "gtest/gtest.h"
22#include "pw_stream/memory_stream.h"
23
24using std::byte;
25
26template <typename... Args>
27constexpr std::array<byte, sizeof...(Args)> MakeBytes(Args... args) noexcept {
28 return {static_cast<byte>(args)...};
29}
30
31namespace pw::hdlc_lite {
32namespace {
33// Size of the in-memory buffer to use for this test.
34constexpr size_t kSinkBufferSize = 15;
35
36TEST(Encoder, FrameFormatTest_1BytePayload) {
37 std::array<byte, kSinkBufferSize> memory_buffer;
38 stream::MemoryWriter memory_writer(memory_buffer);
39
40 constexpr std::array<byte, 1> test_array = MakeBytes(0x41);
41 constexpr std::array<byte, 5> expected_array =
42 MakeBytes(0x7E, 0x41, 0x15, 0xB9, 0x7E);
43
44 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
45 EXPECT_EQ(memory_writer.bytes_written(), 5u);
46 EXPECT_EQ(std::memcmp(memory_writer.data(),
47 expected_array.data(),
48 memory_writer.bytes_written()),
49 0);
50}
51
52TEST(Encoder, FrameFormatTest_EmptyPayload) {
53 std::array<byte, kSinkBufferSize> memory_buffer;
54 stream::MemoryWriter memory_writer(memory_buffer);
55
56 constexpr std::array<byte, 4> expected_array =
57 MakeBytes(0x7E, 0xFF, 0xFF, 0x7E);
58
59 EXPECT_TRUE(EncodeAndWritePayload(std::span<byte>(), memory_writer).ok());
60 EXPECT_EQ(memory_writer.bytes_written(), 4u);
61 EXPECT_EQ(std::memcmp(memory_writer.data(),
62 expected_array.data(),
63 memory_writer.bytes_written()),
64 0);
65}
66
67TEST(Encoder, FrameFormatTest_9BytePayload) {
68 std::array<byte, kSinkBufferSize> memory_buffer;
69 stream::MemoryWriter memory_writer(memory_buffer);
70
71 constexpr std::array<byte, 9> test_array =
72 MakeBytes(0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39);
73 constexpr std::array<byte, 13> expected_array = MakeBytes(0x7E,
74 0x31,
75 0x32,
76 0x33,
77 0x34,
78 0x35,
79 0x36,
80 0x37,
81 0x38,
82 0x39,
83 0xB1,
84 0x29,
85 0x7E);
86
87 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
88 EXPECT_EQ(memory_writer.bytes_written(), 13u);
89 EXPECT_EQ(std::memcmp(memory_writer.data(),
90 expected_array.data(),
91 memory_writer.bytes_written()),
92 0);
93}
94
95TEST(Encoder, EncodingMultiplePayloads) {
96 std::array<byte, kSinkBufferSize> memory_buffer;
97 stream::MemoryWriter memory_writer(memory_buffer);
98
99 constexpr std::array<byte, 1> test_array = MakeBytes(0x41);
100 constexpr std::array<byte, 5> expected_array_1 =
101 MakeBytes(0x7E, 0x41, 0x15, 0xB9, 0x7E);
102 constexpr std::array<byte, 10> expected_array_2 =
103 MakeBytes(0x7E, 0x41, 0x15, 0xB9, 0x7E, 0x7E, 0x41, 0x15, 0xB9, 0x7E);
104
105 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
106 EXPECT_EQ(memory_writer.bytes_written(), 5u);
107 EXPECT_EQ(std::memcmp(memory_writer.data(),
108 expected_array_1.data(),
109 memory_writer.bytes_written()),
110 0);
111
112 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
113 EXPECT_EQ(memory_writer.bytes_written(), 10u);
114 EXPECT_EQ(std::memcmp(memory_writer.data(),
115 expected_array_2.data(),
116 memory_writer.bytes_written()),
117 0);
118}
119
120TEST(Encoder, EscapingTest_0x7D) {
121 std::array<byte, kSinkBufferSize> memory_buffer;
122 stream::MemoryWriter memory_writer(memory_buffer);
123
124 constexpr std::array<byte, 1> test_array = MakeBytes(0x7D);
125 constexpr std::array<byte, 6> expected_array =
126 MakeBytes(0x7E, 0x7D, 0x5D, 0xCA, 0x4E, 0x7E);
127
128 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
129 EXPECT_EQ(memory_writer.bytes_written(), 6u);
130 EXPECT_EQ(std::memcmp(memory_writer.data(),
131 expected_array.data(),
132 memory_writer.bytes_written()),
133 0);
134}
135
136TEST(Encoder, EscapingTest_0x7E) {
137 std::array<byte, kSinkBufferSize> memory_buffer;
138 stream::MemoryWriter memory_writer(memory_buffer);
139
140 constexpr std::array<byte, 1> test_array = MakeBytes(0x7E);
141 constexpr std::array<byte, 7> expected_array =
142 MakeBytes(0x7E, 0x7D, 0x5E, 0xA9, 0x7D, 0x5E, 0x7E);
143
144 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
145 EXPECT_EQ(memory_writer.bytes_written(), 7u);
146 EXPECT_EQ(std::memcmp(memory_writer.data(),
147 expected_array.data(),
148 memory_writer.bytes_written()),
149 0);
150}
151
152TEST(Encoder, EscapingTest_Mix) {
153 std::array<byte, kSinkBufferSize> memory_buffer;
154 stream::MemoryWriter memory_writer(memory_buffer);
155
156 constexpr std::array<byte, 7> test_array =
157 MakeBytes(0x7E, 0x7B, 0x61, 0x62, 0x63, 0x7D, 0x7E);
158 constexpr std::array<byte, 14> expected_array = MakeBytes(0x7E,
159 0x7D,
160 0x5E,
161 0x7B,
162 0x61,
163 0x62,
164 0x63,
165 0x7D,
166 0x5D,
167 0x7D,
168 0x5E,
169 0x49,
170 0xE5,
171 0x7E);
172
173 EXPECT_TRUE(EncodeAndWritePayload(test_array, memory_writer).ok());
174 EXPECT_EQ(memory_writer.bytes_written(), 14u);
175 EXPECT_EQ(std::memcmp(memory_writer.data(),
176 expected_array.data(),
177 memory_writer.bytes_written()),
178 0);
179}
180
181TEST(Encoder, WriterErrorTest) {
182 std::array<byte, kSinkBufferSize> memory_buffer;
183 stream::MemoryWriter memory_writer(memory_buffer);
184
185 constexpr std::array<byte, 12> test_array = MakeBytes(
186 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41);
187
188 EXPECT_FALSE(EncodeAndWritePayload(test_array, memory_writer).ok());
189}
190
191} // namespace
192} // namespace pw::hdlc_lite