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/msf/msf_byte_stream.h"
16 :
17 : #include <algorithm>
18 :
19 : #include "gtest/gtest.h"
20 :
21 : namespace msf {
22 :
23 : namespace {
24 :
25 : class TestMsfByteStream : public MsfByteStream {
26 : public:
27 E : TestMsfByteStream() : MsfByteStream() {}
28 :
29 : using MsfByteStream::ReadBytes;
30 : };
31 :
32 : class TestMsfStream : public MsfStream {
33 : public:
34 E : explicit TestMsfStream(size_t length) : MsfStream(length) {}
35 :
36 E : virtual ~TestMsfStream() {}
37 :
38 E : bool ReadBytes(void* dest, size_t count, size_t* bytes_read) {
39 E : DCHECK(dest != NULL);
40 E : DCHECK(bytes_read != NULL);
41 :
42 E : if (pos() == length()) {
43 i : *bytes_read = 0;
44 i : return true;
45 : }
46 :
47 E : count = std::min(count, length() - pos());
48 E : ::memset(dest, 0xFF, count);
49 E : Seek(pos() + count);
50 E : *bytes_read = count;
51 :
52 E : return true;
53 E : }
54 : };
55 :
56 : } // namespace
57 :
58 E : TEST(MsfByteStreamTest, InitFromByteArray) {
59 E : uint8 data[] = {1, 2, 3, 4, 5, 6, 7, 8};
60 :
61 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
62 E : EXPECT_TRUE(stream->Init(data, arraysize(data)));
63 E : EXPECT_EQ(arraysize(data), stream->length());
64 E : EXPECT_TRUE(stream->data() != NULL);
65 :
66 E : for (size_t i = 0; i < stream->length(); ++i) {
67 E : uint8 num = 0;
68 E : EXPECT_TRUE(stream->Read(&num, 1));
69 E : EXPECT_EQ(data[i], num);
70 E : }
71 E : }
72 :
73 E : TEST(MsfByteStreamTest, InitFromMsfStream) {
74 E : scoped_refptr<TestMsfStream> test_stream(new TestMsfStream(64));
75 :
76 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
77 E : EXPECT_TRUE(stream->Init(test_stream.get()));
78 E : EXPECT_EQ(test_stream->length(), stream->length());
79 E : EXPECT_TRUE(stream->data() != NULL);
80 :
81 E : for (size_t i = 0; i < stream->length(); ++i) {
82 E : uint8 num = 0;
83 E : EXPECT_TRUE(stream->Read(&num, 1));
84 E : EXPECT_EQ(0xFF, num);
85 E : }
86 E : }
87 :
88 E : TEST(MsfByteStreamTest, InitFromMsfStreamPart) {
89 E : uint8 data[] = {0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
90 E : scoped_refptr<MsfByteStream> test_stream(new MsfByteStream());
91 E : EXPECT_TRUE(test_stream->Init(data, arraysize(data)));
92 :
93 E : scoped_refptr<MsfByteStream> stream(new MsfByteStream());
94 E : EXPECT_TRUE(test_stream->Seek(2));
95 E : EXPECT_TRUE(stream->Init(test_stream.get(), 7));
96 E : EXPECT_EQ(7, stream->length());
97 E : EXPECT_TRUE(stream->data() != NULL);
98 :
99 E : for (size_t i = 0; i < stream->length(); ++i) {
100 E : uint8 num = 0;
101 E : EXPECT_TRUE(stream->Read(&num, 1));
102 E : EXPECT_EQ(data[i + 2], num);
103 E : }
104 E : }
105 :
106 E : TEST(MsfByteStreamTest, ReadBytes) {
107 E : size_t len = 17;
108 E : scoped_refptr<TestMsfStream> test_stream(new TestMsfStream(len));
109 :
110 E : scoped_refptr<TestMsfByteStream> stream(new TestMsfByteStream());
111 E : EXPECT_TRUE(stream->Init(test_stream.get()));
112 :
113 E : int total_bytes = 0;
114 E : while (true) {
115 : uint8 buffer[4];
116 E : size_t bytes_read = 0;
117 E : EXPECT_TRUE(stream->ReadBytes(buffer, sizeof(buffer), &bytes_read));
118 E : if (bytes_read == 0)
119 E : break;
120 E : total_bytes += bytes_read;
121 E : }
122 :
123 E : EXPECT_EQ(len, total_bytes);
124 E : }
125 :
126 E : TEST(MsfByteStreamTest, GetWritableStream) {
127 E : scoped_refptr<MsfStream> stream(new MsfByteStream());
128 E : scoped_refptr<WritableMsfStream> writer1 = stream->GetWritableStream();
129 E : EXPECT_TRUE(writer1.get() != NULL);
130 :
131 : // NOTE: This is a condition that only needs to be true currently because
132 : // of limitations in the WritableMsfByteStream implementation. When we
133 : // move to a proper interface implementation with shared storage state,
134 : // this limitation will be removed.
135 E : scoped_refptr<WritableMsfStream> writer2 = stream->GetWritableStream();
136 E : EXPECT_EQ(writer1.get(), writer2.get());
137 E : }
138 :
139 E : TEST(WritableMsfByteStreamTest, WriterChangesReaderLengthButNotCursor) {
140 E : scoped_refptr<MsfStream> reader(new MsfByteStream());
141 E : scoped_refptr<WritableMsfStream> writer = reader->GetWritableStream();
142 E : ASSERT_TRUE(writer.get() != NULL);
143 :
144 E : EXPECT_EQ(reader->length(), 0u);
145 E : EXPECT_EQ(reader->pos(), 0u);
146 E : EXPECT_EQ(writer->length(), 0u);
147 E : EXPECT_EQ(writer->pos(), 0u);
148 E : writer->Consume(10);
149 E : EXPECT_EQ(reader->length(), 10u);
150 E : EXPECT_EQ(reader->pos(), 0u);
151 E : EXPECT_EQ(writer->length(), 10u);
152 E : EXPECT_EQ(writer->pos(), 10u);
153 E : }
154 :
155 : } // namespace msf
|