BinaryStreamTest.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. //===- llvm/unittest/Support/BinaryStreamTest.cpp -------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Support/BinaryByteStream.h"
  9. #include "llvm/Support/BinaryItemStream.h"
  10. #include "llvm/Support/BinaryStreamArray.h"
  11. #include "llvm/Support/BinaryStreamReader.h"
  12. #include "llvm/Support/BinaryStreamRef.h"
  13. #include "llvm/Support/BinaryStreamWriter.h"
  14. #include "llvm/Testing/Support/Error.h"
  15. #include "gtest/gtest.h"
  16. using namespace llvm;
  17. using namespace llvm::support;
  18. namespace {
  19. class BrokenStream : public WritableBinaryStream {
  20. public:
  21. BrokenStream(MutableArrayRef<uint8_t> Data, endianness Endian,
  22. uint32_t Align)
  23. : Data(Data), PartitionIndex(alignDown(Data.size() / 2, Align)),
  24. Endian(Endian) {}
  25. endianness getEndian() const override { return Endian; }
  26. Error readBytes(uint32_t Offset, uint32_t Size,
  27. ArrayRef<uint8_t> &Buffer) override {
  28. if (auto EC = checkOffsetForRead(Offset, Size))
  29. return EC;
  30. uint32_t S = startIndex(Offset);
  31. auto Ref = Data.drop_front(S);
  32. if (Ref.size() >= Size) {
  33. Buffer = Ref.take_front(Size);
  34. return Error::success();
  35. }
  36. uint32_t BytesLeft = Size - Ref.size();
  37. uint8_t *Ptr = Allocator.Allocate<uint8_t>(Size);
  38. ::memcpy(Ptr, Ref.data(), Ref.size());
  39. ::memcpy(Ptr + Ref.size(), Data.data(), BytesLeft);
  40. Buffer = makeArrayRef<uint8_t>(Ptr, Size);
  41. return Error::success();
  42. }
  43. Error readLongestContiguousChunk(uint32_t Offset,
  44. ArrayRef<uint8_t> &Buffer) override {
  45. if (auto EC = checkOffsetForRead(Offset, 1))
  46. return EC;
  47. uint32_t S = startIndex(Offset);
  48. Buffer = Data.drop_front(S);
  49. return Error::success();
  50. }
  51. uint32_t getLength() override { return Data.size(); }
  52. Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) override {
  53. if (auto EC = checkOffsetForWrite(Offset, SrcData.size()))
  54. return EC;
  55. if (SrcData.empty())
  56. return Error::success();
  57. uint32_t S = startIndex(Offset);
  58. MutableArrayRef<uint8_t> Ref(Data);
  59. Ref = Ref.drop_front(S);
  60. if (Ref.size() >= SrcData.size()) {
  61. ::memcpy(Ref.data(), SrcData.data(), SrcData.size());
  62. return Error::success();
  63. }
  64. uint32_t BytesLeft = SrcData.size() - Ref.size();
  65. ::memcpy(Ref.data(), SrcData.data(), Ref.size());
  66. ::memcpy(&Data[0], SrcData.data() + Ref.size(), BytesLeft);
  67. return Error::success();
  68. }
  69. Error commit() override { return Error::success(); }
  70. private:
  71. uint32_t startIndex(uint32_t Offset) const {
  72. return (Offset + PartitionIndex) % Data.size();
  73. }
  74. uint32_t endIndex(uint32_t Offset, uint32_t Size) const {
  75. return (startIndex(Offset) + Size - 1) % Data.size();
  76. }
  77. // Buffer is organized like this:
  78. // -------------------------------------------------
  79. // | N/2 | N/2+1 | ... | N-1 | 0 | 1 | ... | N/2-1 |
  80. // -------------------------------------------------
  81. // So reads from the beginning actually come from the middle.
  82. MutableArrayRef<uint8_t> Data;
  83. uint32_t PartitionIndex = 0;
  84. endianness Endian;
  85. BumpPtrAllocator Allocator;
  86. };
  87. constexpr endianness Endians[] = {big, little, native};
  88. constexpr uint32_t NumEndians = llvm::array_lengthof(Endians);
  89. constexpr uint32_t NumStreams = 2 * NumEndians;
  90. class BinaryStreamTest : public testing::Test {
  91. public:
  92. BinaryStreamTest() {}
  93. void SetUp() override {
  94. Streams.clear();
  95. Streams.resize(NumStreams);
  96. for (uint32_t I = 0; I < NumStreams; ++I)
  97. Streams[I].IsContiguous = (I % 2 == 0);
  98. InputData.clear();
  99. OutputData.clear();
  100. }
  101. protected:
  102. struct StreamPair {
  103. bool IsContiguous;
  104. std::unique_ptr<BinaryStream> Input;
  105. std::unique_ptr<WritableBinaryStream> Output;
  106. };
  107. void initializeInput(ArrayRef<uint8_t> Input, uint32_t Align) {
  108. InputData = Input;
  109. BrokenInputData.resize(InputData.size());
  110. if (!Input.empty()) {
  111. uint32_t PartitionIndex = alignDown(InputData.size() / 2, Align);
  112. uint32_t RightBytes = InputData.size() - PartitionIndex;
  113. uint32_t LeftBytes = PartitionIndex;
  114. if (RightBytes > 0)
  115. ::memcpy(&BrokenInputData[PartitionIndex], Input.data(), RightBytes);
  116. if (LeftBytes > 0)
  117. ::memcpy(&BrokenInputData[0], Input.data() + RightBytes, LeftBytes);
  118. }
  119. for (uint32_t I = 0; I < NumEndians; ++I) {
  120. auto InByteStream =
  121. std::make_unique<BinaryByteStream>(InputData, Endians[I]);
  122. auto InBrokenStream = std::make_unique<BrokenStream>(
  123. BrokenInputData, Endians[I], Align);
  124. Streams[I * 2].Input = std::move(InByteStream);
  125. Streams[I * 2 + 1].Input = std::move(InBrokenStream);
  126. }
  127. }
  128. void initializeOutput(uint32_t Size, uint32_t Align) {
  129. OutputData.resize(Size);
  130. BrokenOutputData.resize(Size);
  131. for (uint32_t I = 0; I < NumEndians; ++I) {
  132. Streams[I * 2].Output =
  133. std::make_unique<MutableBinaryByteStream>(OutputData, Endians[I]);
  134. Streams[I * 2 + 1].Output = std::make_unique<BrokenStream>(
  135. BrokenOutputData, Endians[I], Align);
  136. }
  137. }
  138. void initializeOutputFromInput(uint32_t Align) {
  139. for (uint32_t I = 0; I < NumEndians; ++I) {
  140. Streams[I * 2].Output =
  141. std::make_unique<MutableBinaryByteStream>(InputData, Endians[I]);
  142. Streams[I * 2 + 1].Output = std::make_unique<BrokenStream>(
  143. BrokenInputData, Endians[I], Align);
  144. }
  145. }
  146. void initializeInputFromOutput(uint32_t Align) {
  147. for (uint32_t I = 0; I < NumEndians; ++I) {
  148. Streams[I * 2].Input =
  149. std::make_unique<BinaryByteStream>(OutputData, Endians[I]);
  150. Streams[I * 2 + 1].Input = std::make_unique<BrokenStream>(
  151. BrokenOutputData, Endians[I], Align);
  152. }
  153. }
  154. std::vector<uint8_t> InputData;
  155. std::vector<uint8_t> BrokenInputData;
  156. std::vector<uint8_t> OutputData;
  157. std::vector<uint8_t> BrokenOutputData;
  158. std::vector<StreamPair> Streams;
  159. };
  160. // Tests that a we can read from a BinaryByteStream without a StreamReader.
  161. TEST_F(BinaryStreamTest, BinaryByteStreamBounds) {
  162. std::vector<uint8_t> InputData = {1, 2, 3, 4, 5};
  163. initializeInput(InputData, 1);
  164. for (auto &Stream : Streams) {
  165. ArrayRef<uint8_t> Buffer;
  166. // 1. If the read fits it should work.
  167. ASSERT_EQ(InputData.size(), Stream.Input->getLength());
  168. ASSERT_THAT_ERROR(Stream.Input->readBytes(2, 1, Buffer), Succeeded());
  169. EXPECT_EQ(makeArrayRef(InputData).slice(2, 1), Buffer);
  170. ASSERT_THAT_ERROR(Stream.Input->readBytes(0, 4, Buffer), Succeeded());
  171. EXPECT_EQ(makeArrayRef(InputData).slice(0, 4), Buffer);
  172. // 2. Reading past the bounds of the input should fail.
  173. EXPECT_THAT_ERROR(Stream.Input->readBytes(4, 2, Buffer), Failed());
  174. }
  175. }
  176. TEST_F(BinaryStreamTest, StreamRefBounds) {
  177. std::vector<uint8_t> InputData = {1, 2, 3, 4, 5};
  178. initializeInput(InputData, 1);
  179. for (const auto &Stream : Streams) {
  180. ArrayRef<uint8_t> Buffer;
  181. BinaryStreamRef Ref(*Stream.Input);
  182. // Read 1 byte from offset 2 should work
  183. ASSERT_EQ(InputData.size(), Ref.getLength());
  184. ASSERT_THAT_ERROR(Ref.readBytes(2, 1, Buffer), Succeeded());
  185. EXPECT_EQ(makeArrayRef(InputData).slice(2, 1), Buffer);
  186. // Reading everything from offset 2 on.
  187. ASSERT_THAT_ERROR(Ref.readLongestContiguousChunk(2, Buffer), Succeeded());
  188. if (Stream.IsContiguous)
  189. EXPECT_EQ(makeArrayRef(InputData).slice(2), Buffer);
  190. else
  191. EXPECT_FALSE(Buffer.empty());
  192. // Reading 6 bytes from offset 0 is too big.
  193. EXPECT_THAT_ERROR(Ref.readBytes(0, 6, Buffer), Failed());
  194. EXPECT_THAT_ERROR(Ref.readLongestContiguousChunk(6, Buffer), Failed());
  195. // Reading 1 byte from offset 2 after dropping 1 byte is the same as reading
  196. // 1 byte from offset 3.
  197. Ref = Ref.drop_front(1);
  198. ASSERT_THAT_ERROR(Ref.readBytes(2, 1, Buffer), Succeeded());
  199. if (Stream.IsContiguous)
  200. EXPECT_EQ(makeArrayRef(InputData).slice(3, 1), Buffer);
  201. else
  202. EXPECT_FALSE(Buffer.empty());
  203. // Reading everything from offset 2 on after dropping 1 byte.
  204. ASSERT_THAT_ERROR(Ref.readLongestContiguousChunk(2, Buffer), Succeeded());
  205. if (Stream.IsContiguous)
  206. EXPECT_EQ(makeArrayRef(InputData).slice(3), Buffer);
  207. else
  208. EXPECT_FALSE(Buffer.empty());
  209. // Reading 2 bytes from offset 2 after dropping 2 bytes is the same as
  210. // reading 2 bytes from offset 4, and should fail.
  211. Ref = Ref.drop_front(1);
  212. EXPECT_THAT_ERROR(Ref.readBytes(2, 2, Buffer), Failed());
  213. // But if we read the longest contiguous chunk instead, we should still
  214. // get the 1 byte at the end.
  215. ASSERT_THAT_ERROR(Ref.readLongestContiguousChunk(2, Buffer), Succeeded());
  216. EXPECT_EQ(makeArrayRef(InputData).take_back(), Buffer);
  217. }
  218. }
  219. TEST_F(BinaryStreamTest, StreamRefDynamicSize) {
  220. StringRef Strings[] = {"1", "2", "3", "4"};
  221. AppendingBinaryByteStream Stream(support::little);
  222. BinaryStreamWriter Writer(Stream);
  223. BinaryStreamReader Reader(Stream);
  224. const uint8_t *Byte;
  225. StringRef Str;
  226. // When the stream is empty, it should report a 0 length and we should get an
  227. // error trying to read even 1 byte from it.
  228. BinaryStreamRef ConstRef(Stream);
  229. EXPECT_EQ(0U, ConstRef.getLength());
  230. EXPECT_THAT_ERROR(Reader.readObject(Byte), Failed());
  231. // But if we write to it, its size should increase and we should be able to
  232. // read not just a byte, but the string that was written.
  233. EXPECT_THAT_ERROR(Writer.writeCString(Strings[0]), Succeeded());
  234. EXPECT_EQ(2U, ConstRef.getLength());
  235. EXPECT_THAT_ERROR(Reader.readObject(Byte), Succeeded());
  236. Reader.setOffset(0);
  237. EXPECT_THAT_ERROR(Reader.readCString(Str), Succeeded());
  238. EXPECT_EQ(Str, Strings[0]);
  239. // If we drop some bytes from the front, we should still track the length as
  240. // the
  241. // underlying stream grows.
  242. BinaryStreamRef Dropped = ConstRef.drop_front(1);
  243. EXPECT_EQ(1U, Dropped.getLength());
  244. EXPECT_THAT_ERROR(Writer.writeCString(Strings[1]), Succeeded());
  245. EXPECT_EQ(4U, ConstRef.getLength());
  246. EXPECT_EQ(3U, Dropped.getLength());
  247. // If we drop zero bytes from the back, we should continue tracking the
  248. // length.
  249. Dropped = Dropped.drop_back(0);
  250. EXPECT_THAT_ERROR(Writer.writeCString(Strings[2]), Succeeded());
  251. EXPECT_EQ(6U, ConstRef.getLength());
  252. EXPECT_EQ(5U, Dropped.getLength());
  253. // If we drop non-zero bytes from the back, we should stop tracking the
  254. // length.
  255. Dropped = Dropped.drop_back(1);
  256. EXPECT_THAT_ERROR(Writer.writeCString(Strings[3]), Succeeded());
  257. EXPECT_EQ(8U, ConstRef.getLength());
  258. EXPECT_EQ(4U, Dropped.getLength());
  259. }
  260. TEST_F(BinaryStreamTest, DropOperations) {
  261. std::vector<uint8_t> InputData = {1, 2, 3, 4, 5, 4, 3, 2, 1};
  262. auto RefData = makeArrayRef(InputData);
  263. initializeInput(InputData, 1);
  264. ArrayRef<uint8_t> Result;
  265. BinaryStreamRef Original(InputData, support::little);
  266. ASSERT_EQ(InputData.size(), Original.getLength());
  267. EXPECT_THAT_ERROR(Original.readBytes(0, InputData.size(), Result),
  268. Succeeded());
  269. EXPECT_EQ(RefData, Result);
  270. auto Dropped = Original.drop_front(2);
  271. EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
  272. Succeeded());
  273. EXPECT_EQ(RefData.drop_front(2), Result);
  274. Dropped = Original.drop_back(2);
  275. EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
  276. Succeeded());
  277. EXPECT_EQ(RefData.drop_back(2), Result);
  278. Dropped = Original.keep_front(2);
  279. EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
  280. Succeeded());
  281. EXPECT_EQ(RefData.take_front(2), Result);
  282. Dropped = Original.keep_back(2);
  283. EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
  284. Succeeded());
  285. EXPECT_EQ(RefData.take_back(2), Result);
  286. Dropped = Original.drop_symmetric(2);
  287. EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
  288. Succeeded());
  289. EXPECT_EQ(RefData.drop_front(2).drop_back(2), Result);
  290. }
  291. // Test that we can write to a BinaryStream without a StreamWriter.
  292. TEST_F(BinaryStreamTest, MutableBinaryByteStreamBounds) {
  293. std::vector<uint8_t> InputData = {'T', 'e', 's', 't', '\0'};
  294. initializeInput(InputData, 1);
  295. initializeOutput(InputData.size(), 1);
  296. // For every combination of input stream and output stream.
  297. for (auto &Stream : Streams) {
  298. ASSERT_EQ(InputData.size(), Stream.Input->getLength());
  299. // 1. Try two reads that are supposed to work. One from offset 0, and one
  300. // from the middle.
  301. uint32_t Offsets[] = {0, 3};
  302. for (auto Offset : Offsets) {
  303. uint32_t ExpectedSize = Stream.Input->getLength() - Offset;
  304. // Read everything from Offset until the end of the input data.
  305. ArrayRef<uint8_t> Data;
  306. ASSERT_THAT_ERROR(Stream.Input->readBytes(Offset, ExpectedSize, Data),
  307. Succeeded());
  308. ASSERT_EQ(ExpectedSize, Data.size());
  309. // Then write it to the destination.
  310. ASSERT_THAT_ERROR(Stream.Output->writeBytes(0, Data), Succeeded());
  311. // Then we read back what we wrote, it should match the corresponding
  312. // slice of the original input data.
  313. ArrayRef<uint8_t> Data2;
  314. ASSERT_THAT_ERROR(Stream.Output->readBytes(Offset, ExpectedSize, Data2),
  315. Succeeded());
  316. EXPECT_EQ(makeArrayRef(InputData).drop_front(Offset), Data2);
  317. }
  318. std::vector<uint8_t> BigData = {0, 1, 2, 3, 4};
  319. // 2. If the write is too big, it should fail.
  320. EXPECT_THAT_ERROR(Stream.Output->writeBytes(3, BigData), Failed());
  321. }
  322. }
  323. TEST_F(BinaryStreamTest, AppendingStream) {
  324. AppendingBinaryByteStream Stream(llvm::support::little);
  325. EXPECT_EQ(0U, Stream.getLength());
  326. std::vector<uint8_t> InputData = {'T', 'e', 's', 't', 'T', 'e', 's', 't'};
  327. auto Test = makeArrayRef(InputData).take_front(4);
  328. // Writing past the end of the stream is an error.
  329. EXPECT_THAT_ERROR(Stream.writeBytes(4, Test), Failed());
  330. // Writing exactly at the end of the stream is ok.
  331. EXPECT_THAT_ERROR(Stream.writeBytes(0, Test), Succeeded());
  332. EXPECT_EQ(Test, Stream.data());
  333. // And now that the end of the stream is where we couldn't write before, now
  334. // we can write.
  335. EXPECT_THAT_ERROR(Stream.writeBytes(4, Test), Succeeded());
  336. EXPECT_EQ(MutableArrayRef<uint8_t>(InputData), Stream.data());
  337. }
  338. // Test that FixedStreamArray works correctly.
  339. TEST_F(BinaryStreamTest, FixedStreamArray) {
  340. std::vector<uint32_t> Ints = {90823, 12908, 109823, 209823};
  341. ArrayRef<uint8_t> IntBytes(reinterpret_cast<uint8_t *>(Ints.data()),
  342. Ints.size() * sizeof(uint32_t));
  343. initializeInput(IntBytes, alignof(uint32_t));
  344. for (auto &Stream : Streams) {
  345. ASSERT_EQ(InputData.size(), Stream.Input->getLength());
  346. FixedStreamArray<uint32_t> Array(*Stream.Input);
  347. auto Iter = Array.begin();
  348. ASSERT_EQ(Ints[0], *Iter++);
  349. ASSERT_EQ(Ints[1], *Iter++);
  350. ASSERT_EQ(Ints[2], *Iter++);
  351. ASSERT_EQ(Ints[3], *Iter++);
  352. ASSERT_EQ(Array.end(), Iter);
  353. }
  354. }
  355. // Ensure FixedStreamArrayIterator::operator-> works.
  356. // Added for coverage of r302257.
  357. TEST_F(BinaryStreamTest, FixedStreamArrayIteratorArrow) {
  358. std::vector<std::pair<uint32_t, uint32_t>> Pairs = {{867, 5309}, {555, 1212}};
  359. ArrayRef<uint8_t> PairBytes(reinterpret_cast<uint8_t *>(Pairs.data()),
  360. Pairs.size() * sizeof(Pairs[0]));
  361. initializeInput(PairBytes, alignof(uint32_t));
  362. for (auto &Stream : Streams) {
  363. ASSERT_EQ(InputData.size(), Stream.Input->getLength());
  364. const FixedStreamArray<std::pair<uint32_t, uint32_t>> Array(*Stream.Input);
  365. auto Iter = Array.begin();
  366. ASSERT_EQ(Pairs[0].first, Iter->first);
  367. ASSERT_EQ(Pairs[0].second, Iter->second);
  368. ++Iter;
  369. ASSERT_EQ(Pairs[1].first, Iter->first);
  370. ASSERT_EQ(Pairs[1].second, Iter->second);
  371. ++Iter;
  372. ASSERT_EQ(Array.end(), Iter);
  373. }
  374. }
  375. // Test that VarStreamArray works correctly.
  376. TEST_F(BinaryStreamTest, VarStreamArray) {
  377. StringLiteral Strings("1. Test2. Longer Test3. Really Long Test4. Super "
  378. "Extra Longest Test Of All");
  379. ArrayRef<uint8_t> StringBytes(
  380. reinterpret_cast<const uint8_t *>(Strings.data()), Strings.size());
  381. initializeInput(StringBytes, 1);
  382. struct StringExtractor {
  383. public:
  384. Error operator()(BinaryStreamRef Stream, uint32_t &Len, StringRef &Item) {
  385. if (Index == 0)
  386. Len = strlen("1. Test");
  387. else if (Index == 1)
  388. Len = strlen("2. Longer Test");
  389. else if (Index == 2)
  390. Len = strlen("3. Really Long Test");
  391. else
  392. Len = strlen("4. Super Extra Longest Test Of All");
  393. ArrayRef<uint8_t> Bytes;
  394. if (auto EC = Stream.readBytes(0, Len, Bytes))
  395. return EC;
  396. Item =
  397. StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
  398. ++Index;
  399. return Error::success();
  400. }
  401. uint32_t Index = 0;
  402. };
  403. for (auto &Stream : Streams) {
  404. VarStreamArray<StringRef, StringExtractor> Array(*Stream.Input);
  405. auto Iter = Array.begin();
  406. ASSERT_EQ("1. Test", *Iter++);
  407. ASSERT_EQ("2. Longer Test", *Iter++);
  408. ASSERT_EQ("3. Really Long Test", *Iter++);
  409. ASSERT_EQ("4. Super Extra Longest Test Of All", *Iter++);
  410. ASSERT_EQ(Array.end(), Iter);
  411. }
  412. }
  413. TEST_F(BinaryStreamTest, StreamReaderBounds) {
  414. std::vector<uint8_t> Bytes;
  415. initializeInput(Bytes, 1);
  416. for (auto &Stream : Streams) {
  417. StringRef S;
  418. BinaryStreamReader Reader(*Stream.Input);
  419. EXPECT_EQ(0U, Reader.bytesRemaining());
  420. EXPECT_THAT_ERROR(Reader.readFixedString(S, 1), Failed());
  421. }
  422. Bytes.resize(5);
  423. initializeInput(Bytes, 1);
  424. for (auto &Stream : Streams) {
  425. StringRef S;
  426. BinaryStreamReader Reader(*Stream.Input);
  427. EXPECT_EQ(Bytes.size(), Reader.bytesRemaining());
  428. EXPECT_THAT_ERROR(Reader.readFixedString(S, 5), Succeeded());
  429. EXPECT_THAT_ERROR(Reader.readFixedString(S, 6), Failed());
  430. }
  431. }
  432. TEST_F(BinaryStreamTest, StreamReaderIntegers) {
  433. support::ulittle64_t Little{908234};
  434. support::ubig32_t Big{28907823};
  435. short NS = 2897;
  436. int NI = -89723;
  437. unsigned long NUL = 902309023UL;
  438. constexpr uint32_t Size =
  439. sizeof(Little) + sizeof(Big) + sizeof(NS) + sizeof(NI) + sizeof(NUL);
  440. initializeOutput(Size, alignof(support::ulittle64_t));
  441. initializeInputFromOutput(alignof(support::ulittle64_t));
  442. for (auto &Stream : Streams) {
  443. BinaryStreamWriter Writer(*Stream.Output);
  444. ASSERT_THAT_ERROR(Writer.writeObject(Little), Succeeded());
  445. ASSERT_THAT_ERROR(Writer.writeObject(Big), Succeeded());
  446. ASSERT_THAT_ERROR(Writer.writeInteger(NS), Succeeded());
  447. ASSERT_THAT_ERROR(Writer.writeInteger(NI), Succeeded());
  448. ASSERT_THAT_ERROR(Writer.writeInteger(NUL), Succeeded());
  449. const support::ulittle64_t *Little2;
  450. const support::ubig32_t *Big2;
  451. short NS2;
  452. int NI2;
  453. unsigned long NUL2;
  454. // 1. Reading fields individually.
  455. BinaryStreamReader Reader(*Stream.Input);
  456. ASSERT_THAT_ERROR(Reader.readObject(Little2), Succeeded());
  457. ASSERT_THAT_ERROR(Reader.readObject(Big2), Succeeded());
  458. ASSERT_THAT_ERROR(Reader.readInteger(NS2), Succeeded());
  459. ASSERT_THAT_ERROR(Reader.readInteger(NI2), Succeeded());
  460. ASSERT_THAT_ERROR(Reader.readInteger(NUL2), Succeeded());
  461. ASSERT_EQ(0U, Reader.bytesRemaining());
  462. EXPECT_EQ(Little, *Little2);
  463. EXPECT_EQ(Big, *Big2);
  464. EXPECT_EQ(NS, NS2);
  465. EXPECT_EQ(NI, NI2);
  466. EXPECT_EQ(NUL, NUL2);
  467. }
  468. }
  469. TEST_F(BinaryStreamTest, StreamReaderIntegerArray) {
  470. // 1. Arrays of integers
  471. std::vector<int> Ints = {1, 2, 3, 4, 5};
  472. ArrayRef<uint8_t> IntBytes(reinterpret_cast<uint8_t *>(&Ints[0]),
  473. Ints.size() * sizeof(int));
  474. initializeInput(IntBytes, alignof(int));
  475. for (auto &Stream : Streams) {
  476. BinaryStreamReader Reader(*Stream.Input);
  477. ArrayRef<int> IntsRef;
  478. ASSERT_THAT_ERROR(Reader.readArray(IntsRef, Ints.size()), Succeeded());
  479. ASSERT_EQ(0U, Reader.bytesRemaining());
  480. EXPECT_EQ(makeArrayRef(Ints), IntsRef);
  481. Reader.setOffset(0);
  482. FixedStreamArray<int> FixedIntsRef;
  483. ASSERT_THAT_ERROR(Reader.readArray(FixedIntsRef, Ints.size()), Succeeded());
  484. ASSERT_EQ(0U, Reader.bytesRemaining());
  485. ASSERT_EQ(Ints, std::vector<int>(FixedIntsRef.begin(), FixedIntsRef.end()));
  486. }
  487. }
  488. TEST_F(BinaryStreamTest, StreamReaderEnum) {
  489. enum class MyEnum : int64_t { Foo = -10, Bar = 0, Baz = 10 };
  490. std::vector<MyEnum> Enums = {MyEnum::Bar, MyEnum::Baz, MyEnum::Foo};
  491. initializeOutput(Enums.size() * sizeof(MyEnum), alignof(MyEnum));
  492. initializeInputFromOutput(alignof(MyEnum));
  493. for (auto &Stream : Streams) {
  494. BinaryStreamWriter Writer(*Stream.Output);
  495. for (auto Value : Enums)
  496. ASSERT_THAT_ERROR(Writer.writeEnum(Value), Succeeded());
  497. BinaryStreamReader Reader(*Stream.Input);
  498. FixedStreamArray<MyEnum> FSA;
  499. for (size_t I = 0; I < Enums.size(); ++I) {
  500. MyEnum Value;
  501. ASSERT_THAT_ERROR(Reader.readEnum(Value), Succeeded());
  502. EXPECT_EQ(Enums[I], Value);
  503. }
  504. ASSERT_EQ(0U, Reader.bytesRemaining());
  505. }
  506. }
  507. TEST_F(BinaryStreamTest, StreamReaderULEB128) {
  508. std::vector<uint64_t> TestValues = {
  509. 0, // Zero
  510. 0x7F, // One byte
  511. 0xFF, // One byte, all-ones
  512. 0xAAAA, // Two bytes
  513. 0xAAAAAAAA, // Four bytes
  514. 0xAAAAAAAAAAAAAAAA, // Eight bytes
  515. 0xffffffffffffffff // Eight bytess, all-ones
  516. };
  517. // Conservatively assume a 10-byte encoding for each of our LEB128s, with no
  518. // alignment requirement.
  519. initializeOutput(10 * TestValues.size(), 1);
  520. initializeInputFromOutput(1);
  521. for (auto &Stream : Streams) {
  522. // Write fields.
  523. BinaryStreamWriter Writer(*Stream.Output);
  524. for (const auto &Value : TestValues)
  525. ASSERT_THAT_ERROR(Writer.writeULEB128(Value), Succeeded());
  526. // Read fields.
  527. BinaryStreamReader Reader(*Stream.Input);
  528. std::vector<uint64_t> Results;
  529. Results.resize(TestValues.size());
  530. for (unsigned I = 0; I != TestValues.size(); ++I)
  531. ASSERT_THAT_ERROR(Reader.readULEB128(Results[I]), Succeeded());
  532. for (unsigned I = 0; I != TestValues.size(); ++I)
  533. EXPECT_EQ(TestValues[I], Results[I]);
  534. }
  535. }
  536. TEST_F(BinaryStreamTest, StreamReaderSLEB128) {
  537. std::vector<int64_t> TestValues = {
  538. 0, // Zero
  539. 0x7F, // One byte
  540. -0x7F, // One byte, negative
  541. 0xFF, // One byte, all-ones
  542. 0xAAAA, // Two bytes
  543. -0xAAAA, // Two bytes, negative
  544. 0xAAAAAAAA, // Four bytes
  545. -0xAAAAAAAA, // Four bytes, negative
  546. 0x2AAAAAAAAAAAAAAA, // Eight bytes
  547. -0x7ffffffffffffff // Eight bytess, negative
  548. };
  549. // Conservatively assume a 10-byte encoding for each of our LEB128s, with no
  550. // alignment requirement.
  551. initializeOutput(10 * TestValues.size(), 1);
  552. initializeInputFromOutput(1);
  553. for (auto &Stream : Streams) {
  554. // Write fields.
  555. BinaryStreamWriter Writer(*Stream.Output);
  556. for (const auto &Value : TestValues)
  557. ASSERT_THAT_ERROR(Writer.writeSLEB128(Value), Succeeded());
  558. // Read fields.
  559. BinaryStreamReader Reader(*Stream.Input);
  560. std::vector<int64_t> Results;
  561. Results.resize(TestValues.size());
  562. for (unsigned I = 0; I != TestValues.size(); ++I)
  563. ASSERT_THAT_ERROR(Reader.readSLEB128(Results[I]), Succeeded());
  564. for (unsigned I = 0; I != TestValues.size(); ++I)
  565. EXPECT_EQ(TestValues[I], Results[I]);
  566. }
  567. }
  568. TEST_F(BinaryStreamTest, StreamReaderObject) {
  569. struct Foo {
  570. int X;
  571. double Y;
  572. char Z;
  573. bool operator==(const Foo &Other) const {
  574. return X == Other.X && Y == Other.Y && Z == Other.Z;
  575. }
  576. };
  577. std::vector<Foo> Foos;
  578. Foos.push_back({-42, 42.42, 42});
  579. Foos.push_back({100, 3.1415, static_cast<char>(-89)});
  580. Foos.push_back({200, 2.718, static_cast<char>(-12) });
  581. const uint8_t *Bytes = reinterpret_cast<const uint8_t *>(&Foos[0]);
  582. initializeInput(makeArrayRef(Bytes, 3 * sizeof(Foo)), alignof(Foo));
  583. for (auto &Stream : Streams) {
  584. // 1. Reading object pointers.
  585. BinaryStreamReader Reader(*Stream.Input);
  586. const Foo *FPtrOut = nullptr;
  587. const Foo *GPtrOut = nullptr;
  588. const Foo *HPtrOut = nullptr;
  589. ASSERT_THAT_ERROR(Reader.readObject(FPtrOut), Succeeded());
  590. ASSERT_THAT_ERROR(Reader.readObject(GPtrOut), Succeeded());
  591. ASSERT_THAT_ERROR(Reader.readObject(HPtrOut), Succeeded());
  592. EXPECT_EQ(0U, Reader.bytesRemaining());
  593. EXPECT_EQ(Foos[0], *FPtrOut);
  594. EXPECT_EQ(Foos[1], *GPtrOut);
  595. EXPECT_EQ(Foos[2], *HPtrOut);
  596. }
  597. }
  598. TEST_F(BinaryStreamTest, StreamReaderStrings) {
  599. std::vector<uint8_t> Bytes = {'O', 'n', 'e', '\0', 'T', 'w', 'o',
  600. '\0', 'T', 'h', 'r', 'e', 'e', '\0',
  601. 'F', 'o', 'u', 'r', '\0'};
  602. initializeInput(Bytes, 1);
  603. for (auto &Stream : Streams) {
  604. BinaryStreamReader Reader(*Stream.Input);
  605. StringRef S1;
  606. StringRef S2;
  607. StringRef S3;
  608. StringRef S4;
  609. ASSERT_THAT_ERROR(Reader.readCString(S1), Succeeded());
  610. ASSERT_THAT_ERROR(Reader.readCString(S2), Succeeded());
  611. ASSERT_THAT_ERROR(Reader.readCString(S3), Succeeded());
  612. ASSERT_THAT_ERROR(Reader.readCString(S4), Succeeded());
  613. ASSERT_EQ(0U, Reader.bytesRemaining());
  614. EXPECT_EQ("One", S1);
  615. EXPECT_EQ("Two", S2);
  616. EXPECT_EQ("Three", S3);
  617. EXPECT_EQ("Four", S4);
  618. S1 = S2 = S3 = S4 = "";
  619. Reader.setOffset(0);
  620. ASSERT_THAT_ERROR(Reader.readFixedString(S1, 3), Succeeded());
  621. ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
  622. ASSERT_THAT_ERROR(Reader.readFixedString(S2, 3), Succeeded());
  623. ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
  624. ASSERT_THAT_ERROR(Reader.readFixedString(S3, 5), Succeeded());
  625. ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
  626. ASSERT_THAT_ERROR(Reader.readFixedString(S4, 4), Succeeded());
  627. ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
  628. ASSERT_EQ(0U, Reader.bytesRemaining());
  629. EXPECT_EQ("One", S1);
  630. EXPECT_EQ("Two", S2);
  631. EXPECT_EQ("Three", S3);
  632. EXPECT_EQ("Four", S4);
  633. }
  634. }
  635. TEST_F(BinaryStreamTest, StreamWriterBounds) {
  636. initializeOutput(5, 1);
  637. for (auto &Stream : Streams) {
  638. BinaryStreamWriter Writer(*Stream.Output);
  639. // 1. Can write a string that exactly fills the buffer.
  640. EXPECT_EQ(5U, Writer.bytesRemaining());
  641. EXPECT_THAT_ERROR(Writer.writeFixedString("abcde"), Succeeded());
  642. EXPECT_EQ(0U, Writer.bytesRemaining());
  643. // 2. Can write an empty string even when you're full
  644. EXPECT_THAT_ERROR(Writer.writeFixedString(""), Succeeded());
  645. EXPECT_THAT_ERROR(Writer.writeFixedString("a"), Failed());
  646. // 3. Can't write a string that is one character too long.
  647. Writer.setOffset(0);
  648. EXPECT_THAT_ERROR(Writer.writeFixedString("abcdef"), Failed());
  649. }
  650. }
  651. TEST_F(BinaryStreamTest, StreamWriterIntegerArrays) {
  652. // 3. Arrays of integers
  653. std::vector<int> SourceInts = {1, 2, 3, 4, 5};
  654. ArrayRef<uint8_t> SourceBytes(reinterpret_cast<uint8_t *>(&SourceInts[0]),
  655. SourceInts.size() * sizeof(int));
  656. initializeInput(SourceBytes, alignof(int));
  657. initializeOutputFromInput(alignof(int));
  658. for (auto &Stream : Streams) {
  659. BinaryStreamReader Reader(*Stream.Input);
  660. BinaryStreamWriter Writer(*Stream.Output);
  661. ArrayRef<int> Ints;
  662. ArrayRef<int> Ints2;
  663. // First read them, then write them, then read them back.
  664. ASSERT_THAT_ERROR(Reader.readArray(Ints, SourceInts.size()), Succeeded());
  665. ASSERT_THAT_ERROR(Writer.writeArray(Ints), Succeeded());
  666. BinaryStreamReader ReaderBacker(*Stream.Output);
  667. ASSERT_THAT_ERROR(ReaderBacker.readArray(Ints2, SourceInts.size()),
  668. Succeeded());
  669. EXPECT_EQ(makeArrayRef(SourceInts), Ints2);
  670. }
  671. }
  672. TEST_F(BinaryStreamTest, StringWriterStrings) {
  673. StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
  674. size_t Length = 0;
  675. for (auto S : Strings)
  676. Length += S.size() + 1;
  677. initializeOutput(Length, 1);
  678. initializeInputFromOutput(1);
  679. for (auto &Stream : Streams) {
  680. BinaryStreamWriter Writer(*Stream.Output);
  681. for (auto S : Strings)
  682. ASSERT_THAT_ERROR(Writer.writeCString(S), Succeeded());
  683. std::vector<StringRef> InStrings;
  684. BinaryStreamReader Reader(*Stream.Input);
  685. while (!Reader.empty()) {
  686. StringRef S;
  687. ASSERT_THAT_ERROR(Reader.readCString(S), Succeeded());
  688. InStrings.push_back(S);
  689. }
  690. EXPECT_EQ(makeArrayRef(Strings), makeArrayRef(InStrings));
  691. }
  692. }
  693. TEST_F(BinaryStreamTest, StreamWriterAppend) {
  694. StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
  695. AppendingBinaryByteStream Stream(support::little);
  696. BinaryStreamWriter Writer(Stream);
  697. for (auto &Str : Strings) {
  698. EXPECT_THAT_ERROR(Writer.writeCString(Str), Succeeded());
  699. }
  700. BinaryStreamReader Reader(Stream);
  701. for (auto &Str : Strings) {
  702. StringRef S;
  703. EXPECT_THAT_ERROR(Reader.readCString(S), Succeeded());
  704. EXPECT_EQ(Str, S);
  705. }
  706. }
  707. }
  708. namespace {
  709. struct BinaryItemStreamObject {
  710. explicit BinaryItemStreamObject(ArrayRef<uint8_t> Bytes) : Bytes(Bytes) {}
  711. ArrayRef<uint8_t> Bytes;
  712. };
  713. }
  714. namespace llvm {
  715. template <> struct BinaryItemTraits<BinaryItemStreamObject> {
  716. static size_t length(const BinaryItemStreamObject &Item) {
  717. return Item.Bytes.size();
  718. }
  719. static ArrayRef<uint8_t> bytes(const BinaryItemStreamObject &Item) {
  720. return Item.Bytes;
  721. }
  722. };
  723. }
  724. namespace {
  725. TEST_F(BinaryStreamTest, BinaryItemStream) {
  726. std::vector<BinaryItemStreamObject> Objects;
  727. struct Foo {
  728. int X;
  729. double Y;
  730. };
  731. std::vector<Foo> Foos = {{1, 1.0}, {2, 2.0}, {3, 3.0}};
  732. BumpPtrAllocator Allocator;
  733. for (const auto &F : Foos) {
  734. uint8_t *Ptr = static_cast<uint8_t *>(Allocator.Allocate(sizeof(Foo),
  735. alignof(Foo)));
  736. MutableArrayRef<uint8_t> Buffer(Ptr, sizeof(Foo));
  737. MutableBinaryByteStream Stream(Buffer, llvm::support::big);
  738. BinaryStreamWriter Writer(Stream);
  739. ASSERT_THAT_ERROR(Writer.writeObject(F), Succeeded());
  740. Objects.push_back(BinaryItemStreamObject(Buffer));
  741. }
  742. BinaryItemStream<BinaryItemStreamObject> ItemStream(big);
  743. ItemStream.setItems(Objects);
  744. BinaryStreamReader Reader(ItemStream);
  745. for (const auto &F : Foos) {
  746. const Foo *F2;
  747. ASSERT_THAT_ERROR(Reader.readObject(F2), Succeeded());
  748. EXPECT_EQ(F.X, F2->X);
  749. EXPECT_DOUBLE_EQ(F.Y, F2->Y);
  750. }
  751. }
  752. } // end anonymous namespace