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 "src/chapter_atom_parser.h"
9
10 #include "gtest/gtest.h"
11
12 #include "test_utils/element_parser_test.h"
13 #include "webm/id.h"
14 #include "webm/status.h"
15
16 using webm::ChapterAtom;
17 using webm::ChapterAtomParser;
18 using webm::ChapterDisplay;
19 using webm::ElementParserTest;
20 using webm::Id;
21 using webm::Status;
22
23 namespace {
24
25 class ChapterAtomParserTest
26 : public ElementParserTest<ChapterAtomParser, Id::kChapterAtom> {};
27
TEST_F(ChapterAtomParserTest,DefaultParse)28 TEST_F(ChapterAtomParserTest, DefaultParse) {
29 ParseAndVerify();
30
31 const ChapterAtom chapter_atom = parser_.value();
32
33 EXPECT_FALSE(chapter_atom.uid.is_present());
34 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.uid.value());
35
36 EXPECT_FALSE(chapter_atom.string_uid.is_present());
37 EXPECT_EQ("", chapter_atom.string_uid.value());
38
39 EXPECT_FALSE(chapter_atom.time_start.is_present());
40 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_start.value());
41
42 EXPECT_FALSE(chapter_atom.time_end.is_present());
43 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_end.value());
44
45 EXPECT_EQ(static_cast<std::size_t>(0), chapter_atom.displays.size());
46
47 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.atoms.size());
48 }
49
TEST_F(ChapterAtomParserTest,DefaultValues)50 TEST_F(ChapterAtomParserTest, DefaultValues) {
51 SetReaderData({
52 0x73, 0xC4, // ID = 0x73C4 (ChapterUID).
53 0x80, // Size = 0.
54
55 0x56, 0x54, // ID = 0x73C4 (ChapterStringUID).
56 0x80, // Size = 0.
57
58 0x91, // ID = 0x91 (ChapterTimeStart).
59 0x40, 0x00, // Size = 0.
60
61 0x92, // ID = 0x91 (ChapterTimeEnd).
62 0x40, 0x00, // Size = 0.
63
64 0x80, // ID = 0x80 (ChapterDisplay).
65 0x40, 0x00, // Size = 0.
66
67 0xB6, // ID = 0xB6 (ChapterAtom).
68 0x40, 0x00, // Size = 0.
69 });
70
71 ParseAndVerify();
72
73 const ChapterAtom chapter_atom = parser_.value();
74
75 EXPECT_TRUE(chapter_atom.uid.is_present());
76 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.uid.value());
77
78 EXPECT_TRUE(chapter_atom.string_uid.is_present());
79 EXPECT_EQ("", chapter_atom.string_uid.value());
80
81 EXPECT_TRUE(chapter_atom.time_start.is_present());
82 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_start.value());
83
84 EXPECT_TRUE(chapter_atom.time_end.is_present());
85 EXPECT_EQ(static_cast<std::uint64_t>(0), chapter_atom.time_end.value());
86
87 ASSERT_EQ(static_cast<std::uint64_t>(1), chapter_atom.displays.size());
88 EXPECT_TRUE(chapter_atom.displays[0].is_present());
89 EXPECT_EQ(ChapterDisplay{}, chapter_atom.displays[0].value());
90
91 ASSERT_EQ(static_cast<std::uint64_t>(1), chapter_atom.atoms.size());
92 EXPECT_TRUE(chapter_atom.atoms[0].is_present());
93 EXPECT_EQ(ChapterAtom{}, chapter_atom.atoms[0].value());
94 }
95
TEST_F(ChapterAtomParserTest,CustomValues)96 TEST_F(ChapterAtomParserTest, CustomValues) {
97 SetReaderData({
98 0x73, 0xC4, // ID = 0x73C4 (ChapterUID).
99 0x81, // Size = 1.
100 0x01, // Body (value = 1).
101
102 0x56, 0x54, // ID = 0x73C4 (ChapterStringUID).
103 0x81, // Size = 1.
104 0x41, // Body (value = "A").
105
106 0x91, // ID = 0x91 (ChapterTimeStart).
107 0x40, 0x01, // Size = 1.
108 0x02, // Body (value = 2).
109
110 0x92, // ID = 0x91 (ChapterTimeEnd).
111 0x40, 0x01, // Size = 1.
112 0x03, // Body (value = 3).
113
114 0x80, // ID = 0x80 (ChapterDisplay).
115 0x40, 0x04, // Size = 4.
116
117 0x85, // ID = 0x85 (ChapString).
118 0x40, 0x01, // Size = 1.
119 0x42, // Body (value = "B").
120
121 0x80, // ID = 0x80 (ChapterDisplay).
122 0x40, 0x04, // Size = 4.
123
124 0x85, // ID = 0x85 (ChapString).
125 0x40, 0x01, // Size = 1.
126 0x43, // Body (value = "C").
127
128 0xB6, // ID = 0xB6 (ChapterAtom).
129 0x40, 0x12, // Size = 18.
130
131 0x73, 0xC4, // ID = 0x73C4 (ChapterUID).
132 0x81, // Size = 1.
133 0x04, // Body (value = 4).
134
135 0xB6, // ID = 0xB6 (ChapterAtom).
136 0x40, 0x04, // Size = 4.
137
138 0x73, 0xC4, // ID = 0x73C4 (ChapterUID).
139 0x81, // Size = 1.
140 0x05, // Body (value = 5).
141
142 0xB6, // ID = 0xB6 (ChapterAtom).
143 0x40, 0x04, // Size = 4.
144
145 0x73, 0xC4, // ID = 0x73C4 (ChapterUID).
146 0x81, // Size = 1.
147 0x06, // Body (value = 6).
148 });
149
150 ParseAndVerify();
151
152 const ChapterAtom chapter_atom = parser_.value();
153
154 EXPECT_TRUE(chapter_atom.uid.is_present());
155 EXPECT_EQ(static_cast<std::uint64_t>(1), chapter_atom.uid.value());
156
157 EXPECT_TRUE(chapter_atom.string_uid.is_present());
158 EXPECT_EQ("A", chapter_atom.string_uid.value());
159
160 EXPECT_TRUE(chapter_atom.time_start.is_present());
161 EXPECT_EQ(static_cast<std::uint64_t>(2), chapter_atom.time_start.value());
162
163 EXPECT_TRUE(chapter_atom.time_end.is_present());
164 EXPECT_EQ(static_cast<std::uint64_t>(3), chapter_atom.time_end.value());
165
166 ChapterDisplay expected_chapter_display;
167
168 ASSERT_EQ(static_cast<std::size_t>(2), chapter_atom.displays.size());
169 expected_chapter_display.string.Set("B", true);
170 EXPECT_TRUE(chapter_atom.displays[0].is_present());
171 EXPECT_EQ(expected_chapter_display, chapter_atom.displays[0].value());
172 expected_chapter_display.string.Set("C", true);
173 EXPECT_TRUE(chapter_atom.displays[1].is_present());
174 EXPECT_EQ(expected_chapter_display, chapter_atom.displays[1].value());
175
176 ChapterAtom expected_chapter_atom;
177 expected_chapter_atom.uid.Set(4, true);
178
179 ChapterAtom tmp_atom{};
180 tmp_atom.uid.Set(5, true);
181 expected_chapter_atom.atoms.emplace_back(tmp_atom, true);
182 tmp_atom.uid.Set(6, true);
183 expected_chapter_atom.atoms.emplace_back(tmp_atom, true);
184
185 ASSERT_EQ(static_cast<std::size_t>(1), chapter_atom.atoms.size());
186 EXPECT_TRUE(chapter_atom.atoms[0].is_present());
187 EXPECT_EQ(expected_chapter_atom, chapter_atom.atoms[0].value());
188 }
189
TEST_F(ChapterAtomParserTest,ExceedMaxRecursionDepth)190 TEST_F(ChapterAtomParserTest, ExceedMaxRecursionDepth) {
191 ResetParser(1);
192
193 SetReaderData({
194 0xB6, // ID = 0xB6 (ChapterAtom).
195 0x80, // Size = 0.
196 });
197 ParseAndVerify();
198
199 SetReaderData({
200 0xB6, // ID = 0xB6 (ChapterAtom).
201 0x82, // Size = 2.
202
203 0xB6, // ID = 0xB6 (ChapterAtom).
204 0x80, // Size = 0.
205 });
206 ParseAndExpectResult(Status::kExceededRecursionDepthLimit);
207 }
208
209 } // namespace
210