buffer_view_unittest.cc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/zucchini/buffer_view.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <iterator>
  8. #include <type_traits>
  9. #include <vector>
  10. #include "base/test/gtest_util.h"
  11. #include "components/zucchini/test_utils.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace zucchini {
  14. class BufferViewTest : public testing::Test {
  15. protected:
  16. // Some tests might modify this.
  17. std::vector<uint8_t> bytes_ = ParseHexString("10 32 54 76 98 BA DC FE 10 00");
  18. };
  19. TEST_F(BufferViewTest, Size) {
  20. for (size_t len = 0; len <= bytes_.size(); ++len) {
  21. EXPECT_EQ(len, ConstBufferView(bytes_.data(), len).size());
  22. EXPECT_EQ(len, MutableBufferView(bytes_.data(), len).size());
  23. }
  24. }
  25. TEST_F(BufferViewTest, Empty) {
  26. // Empty view.
  27. EXPECT_TRUE(ConstBufferView(bytes_.data(), 0).empty());
  28. EXPECT_TRUE(MutableBufferView(bytes_.data(), 0).empty());
  29. for (size_t len = 1; len <= bytes_.size(); ++len) {
  30. EXPECT_FALSE(ConstBufferView(bytes_.data(), len).empty());
  31. EXPECT_FALSE(MutableBufferView(bytes_.data(), len).empty());
  32. }
  33. }
  34. TEST_F(BufferViewTest, FromRange) {
  35. constexpr size_t kSize = 10;
  36. uint8_t raw_data[kSize] = {0x10, 0x32, 0x54, 0x76, 0x98,
  37. 0xBA, 0xDC, 0xFE, 0x10, 0x00};
  38. ConstBufferView buffer =
  39. ConstBufferView::FromRange(std::begin(raw_data), std::end(raw_data));
  40. EXPECT_EQ(bytes_.size(), buffer.size());
  41. EXPECT_EQ(std::begin(raw_data), buffer.begin());
  42. MutableBufferView mutable_buffer =
  43. MutableBufferView::FromRange(std::begin(raw_data), std::end(raw_data));
  44. EXPECT_EQ(bytes_.size(), mutable_buffer.size());
  45. EXPECT_EQ(std::begin(raw_data), mutable_buffer.begin());
  46. EXPECT_DCHECK_DEATH(
  47. ConstBufferView::FromRange(std::end(raw_data), std::begin(raw_data)));
  48. EXPECT_DCHECK_DEATH(MutableBufferView::FromRange(std::begin(raw_data) + 1,
  49. std::begin(raw_data)));
  50. }
  51. TEST_F(BufferViewTest, Subscript) {
  52. ConstBufferView view(bytes_.data(), bytes_.size());
  53. EXPECT_EQ(0x10, view[0]);
  54. static_assert(!std::is_assignable<decltype(view[0]), uint8_t>::value,
  55. "BufferView values should not be mutable.");
  56. MutableBufferView mutable_view(bytes_.data(), bytes_.size());
  57. EXPECT_EQ(bytes_.data(), &mutable_view[0]);
  58. mutable_view[0] = 42;
  59. EXPECT_EQ(42, mutable_view[0]);
  60. }
  61. TEST_F(BufferViewTest, SubRegion) {
  62. ConstBufferView view(bytes_.data(), bytes_.size());
  63. ConstBufferView sub_view = view[{2, 4}];
  64. EXPECT_EQ(view.begin() + 2, sub_view.begin());
  65. EXPECT_EQ(size_t(4), sub_view.size());
  66. }
  67. TEST_F(BufferViewTest, Shrink) {
  68. ConstBufferView buffer(bytes_.data(), bytes_.size());
  69. buffer.shrink(bytes_.size());
  70. EXPECT_EQ(bytes_.size(), buffer.size());
  71. buffer.shrink(2);
  72. EXPECT_EQ(size_t(2), buffer.size());
  73. EXPECT_DCHECK_DEATH(buffer.shrink(bytes_.size()));
  74. }
  75. TEST_F(BufferViewTest, Read) {
  76. ConstBufferView buffer(bytes_.data(), bytes_.size());
  77. EXPECT_EQ(0x10U, buffer.read<uint8_t>(0));
  78. EXPECT_EQ(0x54U, buffer.read<uint8_t>(2));
  79. EXPECT_EQ(0x3210U, buffer.read<uint16_t>(0));
  80. EXPECT_EQ(0x7654U, buffer.read<uint16_t>(2));
  81. EXPECT_EQ(0x76543210U, buffer.read<uint32_t>(0));
  82. EXPECT_EQ(0xBA987654U, buffer.read<uint32_t>(2));
  83. EXPECT_EQ(0xFEDCBA9876543210ULL, buffer.read<uint64_t>(0));
  84. EXPECT_EQ(0x00, buffer.read<uint8_t>(9));
  85. EXPECT_DEATH(buffer.read<uint8_t>(10), "");
  86. EXPECT_EQ(0x0010FEDCU, buffer.read<uint32_t>(6));
  87. EXPECT_DEATH(buffer.read<uint32_t>(7), "");
  88. }
  89. TEST_F(BufferViewTest, Write) {
  90. MutableBufferView buffer(bytes_.data(), bytes_.size());
  91. buffer.write<uint32_t>(0, 0x01234567);
  92. buffer.write<uint32_t>(4, 0x89ABCDEF);
  93. EXPECT_EQ(ParseHexString("67 45 23 01 EF CD AB 89 10 00"),
  94. std::vector<uint8_t>(buffer.begin(), buffer.end()));
  95. buffer.write<uint8_t>(9, 0xFF);
  96. EXPECT_DEATH(buffer.write<uint8_t>(10, 0xFF), "");
  97. buffer.write<uint32_t>(6, 0xFFFFFFFF);
  98. EXPECT_DEATH(buffer.write<uint32_t>(7, 0xFFFFFFFF), "");
  99. }
  100. TEST_F(BufferViewTest, Modify) {
  101. struct TestStruct {
  102. uint32_t a;
  103. uint32_t b;
  104. };
  105. MutableBufferView buffer(bytes_.data(), bytes_.size());
  106. buffer.modify<TestStruct>(0).a = 0x01234567;
  107. buffer.modify<TestStruct>(0).b = 0x89ABCDEF;
  108. EXPECT_EQ(ParseHexString("67 45 23 01 EF CD AB 89 10 00"),
  109. std::vector<uint8_t>(buffer.begin(), buffer.end()));
  110. buffer.modify<uint8_t>(9);
  111. EXPECT_DEATH(buffer.modify<uint8_t>(10), "");
  112. buffer.modify<uint32_t>(6);
  113. EXPECT_DEATH(buffer.modify<uint32_t>(7), "");
  114. }
  115. TEST_F(BufferViewTest, CanAccess) {
  116. MutableBufferView buffer(bytes_.data(), bytes_.size());
  117. EXPECT_TRUE(buffer.can_access<uint32_t>(0));
  118. EXPECT_TRUE(buffer.can_access<uint32_t>(6));
  119. EXPECT_FALSE(buffer.can_access<uint32_t>(7));
  120. EXPECT_FALSE(buffer.can_access<uint32_t>(10));
  121. EXPECT_FALSE(buffer.can_access<uint32_t>(0xFFFFFFFFU));
  122. EXPECT_TRUE(buffer.can_access<uint8_t>(0));
  123. EXPECT_TRUE(buffer.can_access<uint8_t>(7));
  124. EXPECT_TRUE(buffer.can_access<uint8_t>(9));
  125. EXPECT_FALSE(buffer.can_access<uint8_t>(10));
  126. EXPECT_FALSE(buffer.can_access<uint8_t>(0xFFFFFFFF));
  127. }
  128. TEST_F(BufferViewTest, LocalRegion) {
  129. ConstBufferView view(bytes_.data(), bytes_.size());
  130. BufferRegion region = view.local_region();
  131. EXPECT_EQ(0U, region.offset);
  132. EXPECT_EQ(bytes_.size(), region.size);
  133. }
  134. TEST_F(BufferViewTest, Covers) {
  135. EXPECT_TRUE(ConstBufferView().covers({0, 0}));
  136. EXPECT_FALSE(ConstBufferView().covers({0, 1}));
  137. ConstBufferView view(bytes_.data(), bytes_.size());
  138. EXPECT_TRUE(view.covers({0, 0}));
  139. EXPECT_TRUE(view.covers({0, 1}));
  140. EXPECT_TRUE(view.covers({0, bytes_.size()}));
  141. EXPECT_FALSE(view.covers({0, bytes_.size() + 1}));
  142. EXPECT_FALSE(view.covers({1, bytes_.size()}));
  143. EXPECT_TRUE(view.covers({bytes_.size() - 1, 0}));
  144. EXPECT_TRUE(view.covers({bytes_.size() - 1, 1}));
  145. EXPECT_FALSE(view.covers({bytes_.size() - 1, 2}));
  146. EXPECT_TRUE(view.covers({bytes_.size(), 0}));
  147. EXPECT_FALSE(view.covers({bytes_.size(), 1}));
  148. EXPECT_FALSE(view.covers({bytes_.size() + 1, 0}));
  149. EXPECT_FALSE(view.covers({bytes_.size() + 1, 1}));
  150. EXPECT_FALSE(view.covers({1, size_t(-1)}));
  151. EXPECT_FALSE(view.covers({size_t(-1), 1}));
  152. EXPECT_FALSE(view.covers({size_t(-1), size_t(-1)}));
  153. }
  154. TEST_F(BufferViewTest, CoversArray) {
  155. ConstBufferView view(bytes_.data(), bytes_.size());
  156. for (uint32_t i = 1; i <= bytes_.size(); ++i) {
  157. EXPECT_TRUE(view.covers_array(0, 1, i));
  158. EXPECT_TRUE(view.covers_array(0, i, 1));
  159. EXPECT_TRUE(view.covers_array(0, i, bytes_.size() / i));
  160. EXPECT_TRUE(view.covers_array(0, bytes_.size() / i, i));
  161. if (i < bytes_.size()) {
  162. EXPECT_TRUE(view.covers_array(i, 1, bytes_.size() - i));
  163. EXPECT_TRUE(view.covers_array(i, bytes_.size() - i, 1));
  164. }
  165. EXPECT_TRUE(view.covers_array(bytes_.size() - (bytes_.size() / i) * i, 1,
  166. bytes_.size() / i));
  167. }
  168. EXPECT_TRUE(view.covers_array(0, 0, bytes_.size()));
  169. EXPECT_TRUE(view.covers_array(bytes_.size() - 1, 0, bytes_.size()));
  170. EXPECT_TRUE(view.covers_array(bytes_.size(), 0, bytes_.size()));
  171. EXPECT_TRUE(view.covers_array(0, 0, 0x10000));
  172. EXPECT_TRUE(view.covers_array(bytes_.size() - 1, 0, 0x10000));
  173. EXPECT_TRUE(view.covers_array(bytes_.size(), 0, 0x10000));
  174. EXPECT_FALSE(view.covers_array(0, 1, bytes_.size() + 1));
  175. EXPECT_FALSE(view.covers_array(0, 2, bytes_.size()));
  176. EXPECT_FALSE(view.covers_array(0, bytes_.size() + 11, 1));
  177. EXPECT_FALSE(view.covers_array(0, bytes_.size(), 2));
  178. EXPECT_FALSE(view.covers_array(1, bytes_.size(), 1));
  179. EXPECT_FALSE(view.covers_array(bytes_.size(), 1, 1));
  180. EXPECT_TRUE(view.covers_array(bytes_.size(), 0, 1));
  181. EXPECT_FALSE(view.covers_array(0, 0x10000, 0x10000));
  182. }
  183. TEST_F(BufferViewTest, Equals) {
  184. // Almost identical to |bytes_|, except at 2 places: v v
  185. std::vector<uint8_t> bytes2 = ParseHexString("10 32 54 76 98 AB CD FE 10 00");
  186. ConstBufferView view1(bytes_.data(), bytes_.size());
  187. ConstBufferView view2(&bytes2[0], bytes2.size());
  188. EXPECT_TRUE(view1.equals(view1));
  189. EXPECT_TRUE(view2.equals(view2));
  190. EXPECT_FALSE(view1.equals(view2));
  191. EXPECT_FALSE(view2.equals(view1));
  192. EXPECT_TRUE((view1[{0, 0}]).equals(view2[{0, 0}]));
  193. EXPECT_TRUE((view1[{0, 0}]).equals(view2[{5, 0}]));
  194. EXPECT_TRUE((view1[{0, 5}]).equals(view2[{0, 5}]));
  195. EXPECT_FALSE((view1[{0, 6}]).equals(view2[{0, 6}]));
  196. EXPECT_FALSE((view1[{0, 7}]).equals(view1[{0, 6}]));
  197. EXPECT_TRUE((view1[{5, 3}]).equals(view1[{5, 3}]));
  198. EXPECT_FALSE((view1[{5, 1}]).equals(view1[{5, 3}]));
  199. EXPECT_TRUE((view2[{0, 1}]).equals(view2[{8, 1}]));
  200. EXPECT_FALSE((view2[{1, 1}]).equals(view2[{8, 1}]));
  201. }
  202. TEST_F(BufferViewTest, AlignOn) {
  203. using size_type = ConstBufferView::size_type;
  204. ConstBufferView image(bytes_.data(), bytes_.size());
  205. ConstBufferView view = image;
  206. ASSERT_EQ(10U, view.size());
  207. auto get_pos = [&image, &view]() -> size_type {
  208. EXPECT_TRUE(view.begin() >= image.begin()); // Iterator compare.
  209. return static_cast<size_type>(view.begin() - image.begin());
  210. };
  211. EXPECT_EQ(0U, get_pos());
  212. view.remove_prefix(1U);
  213. EXPECT_EQ(1U, get_pos());
  214. view.remove_prefix(4U);
  215. EXPECT_EQ(5U, get_pos());
  216. // Align.
  217. EXPECT_TRUE(view.AlignOn(image, 1U)); // Trival case.
  218. EXPECT_EQ(5U, get_pos());
  219. EXPECT_TRUE(view.AlignOn(image, 2U));
  220. EXPECT_EQ(6U, get_pos());
  221. EXPECT_TRUE(view.AlignOn(image, 2U));
  222. EXPECT_EQ(6U, get_pos());
  223. EXPECT_TRUE(view.AlignOn(image, 4U));
  224. EXPECT_EQ(8U, get_pos());
  225. EXPECT_TRUE(view.AlignOn(image, 2U));
  226. EXPECT_EQ(8U, get_pos());
  227. view.remove_prefix(1U);
  228. EXPECT_EQ(9U, get_pos());
  229. // Pos is at 9, align to 4 would yield 12, but size is 10, so this fails.
  230. EXPECT_FALSE(view.AlignOn(image, 4U));
  231. EXPECT_EQ(9U, get_pos());
  232. EXPECT_TRUE(view.AlignOn(image, 2U));
  233. EXPECT_EQ(10U, get_pos());
  234. }
  235. } // namespace zucchini