1 // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "webm/istream_reader.h"
9
10 #include <algorithm>
11 #include <array>
12 #include <cstdint>
13 #include <sstream>
14 #include <type_traits>
15
16 #include "gtest/gtest.h"
17
18 using webm::IstreamReader;
19 using webm::Status;
20
21 namespace {
22
23 // Creates a std::array from a string literal (and omits the trailing
24 // NUL-character).
25 template <std::size_t N>
ArrayFromString(const char (& string)[N])26 std::array<std::uint8_t, N - 1> ArrayFromString(const char (&string)[N]) {
27 std::array<std::uint8_t, N - 1> array;
28 std::copy_n(string, N - 1, array.begin());
29 return array;
30 }
31
32 class IstreamReaderTest : public testing::Test {};
33
TEST_F(IstreamReaderTest,Read)34 TEST_F(IstreamReaderTest, Read) {
35 std::array<std::uint8_t, 15> buffer{};
36 std::uint64_t count;
37 Status status;
38
39 IstreamReader reader =
40 IstreamReader::Emplace<std::istringstream>("abcdefghij");
41
42 status = reader.Read(5, buffer.data(), &count);
43 EXPECT_EQ(Status::kOkCompleted, status.code);
44 EXPECT_EQ(static_cast<std::uint64_t>(5), count);
45
46 status = reader.Read(10, buffer.data() + 5, &count);
47 EXPECT_EQ(Status::kOkPartial, status.code);
48 EXPECT_EQ(static_cast<std::uint64_t>(5), count);
49
50 std::array<std::uint8_t, 15> expected =
51 ArrayFromString("abcdefghij\0\0\0\0\0");
52 EXPECT_EQ(expected, buffer);
53
54 status = reader.Read(buffer.size(), buffer.data(), &count);
55 EXPECT_EQ(Status::kEndOfFile, status.code);
56 EXPECT_EQ(static_cast<std::uint64_t>(0), count);
57 }
58
TEST_F(IstreamReaderTest,Skip)59 TEST_F(IstreamReaderTest, Skip) {
60 std::uint64_t count;
61 Status status;
62
63 IstreamReader reader =
64 IstreamReader::Emplace<std::istringstream>("abcdefghij");
65
66 status = reader.Skip(3, &count);
67 EXPECT_EQ(Status::kOkCompleted, status.code);
68 EXPECT_EQ(static_cast<std::uint64_t>(3), count);
69
70 status = reader.Skip(10, &count);
71 EXPECT_EQ(Status::kOkPartial, status.code);
72 EXPECT_EQ(static_cast<std::uint64_t>(7), count);
73
74 status = reader.Skip(1, &count);
75 EXPECT_EQ(Status::kEndOfFile, status.code);
76 EXPECT_EQ(static_cast<std::uint64_t>(0), count);
77 }
78
TEST_F(IstreamReaderTest,ReadAndSkip)79 TEST_F(IstreamReaderTest, ReadAndSkip) {
80 std::array<std::uint8_t, 10> buffer = {};
81 std::uint64_t count;
82 Status status;
83
84 IstreamReader reader =
85 IstreamReader::Emplace<std::istringstream>("AaBbCcDdEe");
86
87 status = reader.Read(5, buffer.data(), &count);
88 EXPECT_EQ(Status::kOkCompleted, status.code);
89 EXPECT_EQ(static_cast<std::uint64_t>(5), count);
90
91 status = reader.Skip(3, &count);
92 EXPECT_EQ(Status::kOkCompleted, status.code);
93 EXPECT_EQ(static_cast<std::uint64_t>(3), count);
94
95 status = reader.Read(5, buffer.data() + 5, &count);
96 EXPECT_EQ(Status::kOkPartial, status.code);
97 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
98
99 std::array<std::uint8_t, 10> expected = ArrayFromString("AaBbCEe\0\0\0");
100 EXPECT_EQ(expected, buffer);
101 }
102
TEST_F(IstreamReaderTest,Position)103 TEST_F(IstreamReaderTest, Position) {
104 std::array<std::uint8_t, 10> buffer = {};
105 std::uint64_t count;
106 Status status;
107
108 IstreamReader reader =
109 IstreamReader::Emplace<std::istringstream>("AaBbCcDdEe");
110 EXPECT_EQ(static_cast<std::uint64_t>(0), reader.Position());
111
112 status = reader.Read(5, buffer.data(), &count);
113 EXPECT_EQ(Status::kOkCompleted, status.code);
114 EXPECT_EQ(static_cast<std::uint64_t>(5), count);
115 EXPECT_EQ(static_cast<std::uint64_t>(5), reader.Position());
116
117 status = reader.Skip(3, &count);
118 EXPECT_EQ(Status::kOkCompleted, status.code);
119 EXPECT_EQ(static_cast<std::uint64_t>(3), count);
120 EXPECT_EQ(static_cast<std::uint64_t>(8), reader.Position());
121
122 status = reader.Read(5, buffer.data() + 5, &count);
123 EXPECT_EQ(Status::kOkPartial, status.code);
124 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
125 EXPECT_EQ(static_cast<std::uint64_t>(10), reader.Position());
126
127 std::array<std::uint8_t, 10> expected = ArrayFromString("AaBbCEe\0\0\0");
128 EXPECT_EQ(expected, buffer);
129 }
130
131 } // namespace
132