1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://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,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/common/buffer_writer.h"
16 :
17 : #include "gtest/gtest.h"
18 :
19 : namespace common {
20 :
21 : namespace {
22 :
23 : struct {
24 : uint32 i;
25 : uint16 iarray[2];
26 : char string[2];
27 : char unused1;
28 : char unused2;
29 : wchar_t wstring[2];
30 : } const kExpectedData = { 0x12345678, { 0xDEAD, 0xBEEF }, "f", 0, 0, L"b" };
31 : static_assert(sizeof(kExpectedData) == 16,
32 : "Alignment issues with expected data.");
33 :
34 : class BufferWriterTest : public ::testing::Test {
35 : public:
36 E : virtual void SetUp() {
37 E : ::memset(buffer_, 0, sizeof(buffer_));
38 E : }
39 :
40 E : void WriteData(BufferWriter* writer) {
41 E : ASSERT_TRUE(writer != NULL);
42 :
43 E : uint32 i = 0x12345678; // 4 bytes.
44 E : uint16 iarray[2] = { 0xDEAD, 0xBEEF }; // 4 bytes
45 E : char string[] = "f"; // 2 bytes.
46 E : wchar_t wstring[] = L"b"; // 4 bytes.
47 :
48 E : ASSERT_EQ(0u, writer->pos());
49 E : ASSERT_TRUE(writer->Write(sizeof(i), (void*)(&i))); // 4 bytes.
50 E : ASSERT_EQ(4u, writer->pos());
51 E : ASSERT_TRUE(writer->Write(arraysize(iarray), iarray)); // 4 bytes.
52 E : ASSERT_EQ(8u, writer->pos());
53 E : ASSERT_TRUE(writer->WriteString(string)); // 2 bytes.
54 E : ASSERT_EQ(10u, writer->pos());
55 E : ASSERT_FALSE(writer->IsAligned(4));
56 E : ASSERT_TRUE(writer->Align(4)); // 2 bytes.
57 E : ASSERT_EQ(12u, writer->pos());
58 E : ASSERT_TRUE(writer->WriteString(wstring)); // 4 bytes.
59 E : ASSERT_EQ(16u, writer->pos());
60 E : }
61 :
62 : std::vector<uint8> vector_;
63 : uint8 buffer_[16];
64 : };
65 :
66 : } // namespace
67 :
68 E : TEST_F(BufferWriterTest, SimpleAccessorsAndMutators) {
69 E : BufferWriter writer(buffer_, sizeof(buffer_));
70 E : EXPECT_EQ(0u, writer.pos());
71 E : EXPECT_EQ(sizeof(buffer_), writer.length());
72 E : EXPECT_EQ(sizeof(buffer_), writer.RemainingBytes());
73 :
74 E : writer.set_pos(10);
75 E : EXPECT_EQ(10u, writer.pos());
76 E : EXPECT_EQ(sizeof(buffer_) - 10, writer.RemainingBytes());
77 :
78 : // We should be able to set positions past the end of the buffer without
79 : // harm.
80 E : writer.set_pos(sizeof(buffer_) + 10);
81 E : EXPECT_EQ(sizeof(buffer_) + 10, writer.pos());
82 E : EXPECT_EQ(0u, writer.RemainingBytes());
83 E : }
84 :
85 E : TEST_F(BufferWriterTest, WriteBehaviour) {
86 E : BufferWriter writer(buffer_, sizeof(buffer_));
87 :
88 E : EXPECT_TRUE(writer.Consume(1));
89 E : EXPECT_EQ(1u, writer.pos());
90 E : EXPECT_FALSE(writer.Consume(sizeof(buffer_))); // Write past the end.
91 E : EXPECT_FALSE(writer.Consume(0xFFFFFFFF)); // Overflow of pos_.
92 :
93 E : uint8 data8[sizeof(buffer_)] = {};
94 :
95 E : EXPECT_TRUE(writer.Write(1, data8));
96 E : EXPECT_EQ(2u, writer.pos());
97 E : EXPECT_FALSE(writer.Write(arraysize(data8), (void*)data8));
98 :
99 E : uint16 data16[sizeof(buffer_) / 2] = {};
100 E : EXPECT_TRUE(writer.Write(1, data16));
101 E : EXPECT_EQ(4u, writer.pos());
102 E : EXPECT_FALSE(writer.Write(arraysize(data16), data16));
103 :
104 E : uint16 small_datum = 42;
105 : struct {
106 : uint8 buffer[sizeof(buffer_)];
107 E : } big_datum = {};
108 :
109 E : EXPECT_TRUE(writer.Write(small_datum));
110 E : EXPECT_EQ(6u, writer.pos());
111 E : EXPECT_FALSE(writer.Write(big_datum));
112 :
113 E : char small_string[] = "h";
114 E : char big_string[] = "the quick brown fox SAY WHAT?";
115 : static_assert(sizeof(big_string) >= sizeof(buffer_),
116 : "Big string is too small.");
117 :
118 E : EXPECT_TRUE(writer.WriteString(small_string));
119 E : EXPECT_EQ(8u, writer.pos());
120 E : EXPECT_FALSE(writer.WriteString(big_string));
121 :
122 E : wchar_t small_wstring[] = L"z";
123 E : wchar_t big_wstring[] = L"sally sells seashells";
124 : static_assert(sizeof(big_wstring) >= sizeof(buffer_),
125 : "Big wstring is too small.");
126 :
127 E : EXPECT_TRUE(writer.WriteString(small_wstring));
128 E : EXPECT_EQ(12u, writer.pos());
129 E : EXPECT_FALSE(writer.WriteString(big_wstring));
130 E : }
131 :
132 E : TEST_F(BufferWriterTest, AlignAndIsAligned) {
133 E : BufferWriter writer(buffer_, sizeof(buffer_));
134 :
135 E : EXPECT_TRUE(writer.IsAligned(1));
136 E : EXPECT_TRUE(writer.IsAligned(2));
137 E : EXPECT_TRUE(writer.IsAligned(4));
138 E : EXPECT_TRUE(writer.IsAligned(8));
139 :
140 E : writer.set_pos(3);
141 E : EXPECT_TRUE(writer.IsAligned(1));
142 E : EXPECT_FALSE(writer.IsAligned(2));
143 E : EXPECT_FALSE(writer.IsAligned(4));
144 E : EXPECT_FALSE(writer.IsAligned(8));
145 :
146 E : EXPECT_TRUE(writer.Align(4));
147 E : EXPECT_EQ(4u, writer.pos());
148 E : EXPECT_TRUE(writer.IsAligned(1));
149 E : EXPECT_TRUE(writer.IsAligned(2));
150 E : EXPECT_TRUE(writer.IsAligned(4));
151 E : EXPECT_FALSE(writer.IsAligned(8));
152 :
153 E : EXPECT_TRUE(writer.Align(8));
154 E : EXPECT_EQ(8u, writer.pos());
155 E : EXPECT_TRUE(writer.IsAligned(1));
156 E : EXPECT_TRUE(writer.IsAligned(2));
157 E : EXPECT_TRUE(writer.IsAligned(4));
158 E : EXPECT_TRUE(writer.IsAligned(8));
159 :
160 : // We don't have room for this alignment.
161 : static_assert(32 > sizeof(buffer_), "Need a bigger failing alignment.");
162 E : EXPECT_FALSE(writer.Align(32));
163 E : }
164 :
165 E : TEST_F(BufferWriterTest, WriteToBuffer) {
166 E : BufferWriter writer(buffer_, sizeof(buffer_));
167 :
168 E : ASSERT_NO_FATAL_FAILURE(WriteData(&writer));
169 E : EXPECT_EQ(sizeof(kExpectedData), writer.pos());
170 E : EXPECT_EQ(0, ::memcmp(&kExpectedData, buffer_, sizeof(kExpectedData)));
171 E : }
172 :
173 E : TEST_F(BufferWriterTest, WriteToVector) {
174 E : VectorBufferWriter writer(&vector_);
175 E : vector_.resize(8);
176 :
177 E : ASSERT_NO_FATAL_FAILURE(WriteData(&writer));
178 E : EXPECT_EQ(sizeof(kExpectedData), writer.pos());
179 E : EXPECT_EQ(0, ::memcmp(&kExpectedData, &vector_[0], sizeof(kExpectedData)));
180 E : }
181 :
182 : } // namespace common
|