xref: /llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp (revision 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520)
1e0308279SFrancis Visoiu Mistrih //===- BitstreamWriterTest.cpp - Tests for BitstreamWriter ----------------===//
2e0308279SFrancis Visoiu Mistrih //
3e0308279SFrancis Visoiu Mistrih // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e0308279SFrancis Visoiu Mistrih // See https://llvm.org/LICENSE.txt for license information.
5e0308279SFrancis Visoiu Mistrih // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e0308279SFrancis Visoiu Mistrih //
7e0308279SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===//
8e0308279SFrancis Visoiu Mistrih 
9e0308279SFrancis Visoiu Mistrih #include "llvm/Bitstream/BitstreamWriter.h"
10e0308279SFrancis Visoiu Mistrih #include "llvm/ADT/STLExtras.h"
11e0308279SFrancis Visoiu Mistrih #include "llvm/ADT/SmallString.h"
12*7cfffe74SMircea Trofin #include "llvm/Bitstream/BitCodeEnums.h"
13*7cfffe74SMircea Trofin #include "llvm/Bitstream/BitstreamReader.h"
14*7cfffe74SMircea Trofin #include "llvm/Support/Error.h"
15*7cfffe74SMircea Trofin #include "llvm/Support/MemoryBuffer.h"
16*7cfffe74SMircea Trofin #include "llvm/Testing/Support/SupportHelpers.h"
17*7cfffe74SMircea Trofin #include "gmock/gmock.h"
18e0308279SFrancis Visoiu Mistrih #include "gtest/gtest.h"
19e0308279SFrancis Visoiu Mistrih 
20e0308279SFrancis Visoiu Mistrih using namespace llvm;
21e0308279SFrancis Visoiu Mistrih 
22e0308279SFrancis Visoiu Mistrih namespace {
23e0308279SFrancis Visoiu Mistrih 
TEST(BitstreamWriterTest,emitBlob)24e0308279SFrancis Visoiu Mistrih TEST(BitstreamWriterTest, emitBlob) {
25e0308279SFrancis Visoiu Mistrih   SmallString<64> Buffer;
26e0308279SFrancis Visoiu Mistrih   BitstreamWriter W(Buffer);
27e0308279SFrancis Visoiu Mistrih   W.emitBlob("str", /* ShouldEmitSize */ false);
28e0308279SFrancis Visoiu Mistrih   EXPECT_EQ(StringRef("str\0", 4), Buffer);
29e0308279SFrancis Visoiu Mistrih }
30e0308279SFrancis Visoiu Mistrih 
TEST(BitstreamWriterTest,emitBlobWithSize)31e0308279SFrancis Visoiu Mistrih TEST(BitstreamWriterTest, emitBlobWithSize) {
32e0308279SFrancis Visoiu Mistrih   SmallString<64> Buffer;
33e0308279SFrancis Visoiu Mistrih   {
34e0308279SFrancis Visoiu Mistrih     BitstreamWriter W(Buffer);
35e0308279SFrancis Visoiu Mistrih     W.emitBlob("str");
36e0308279SFrancis Visoiu Mistrih   }
37e0308279SFrancis Visoiu Mistrih   SmallString<64> Expected;
38e0308279SFrancis Visoiu Mistrih   {
39e0308279SFrancis Visoiu Mistrih     BitstreamWriter W(Expected);
40e0308279SFrancis Visoiu Mistrih     W.EmitVBR(3, 6);
41e0308279SFrancis Visoiu Mistrih     W.FlushToWord();
42e0308279SFrancis Visoiu Mistrih     W.Emit('s', 8);
43e0308279SFrancis Visoiu Mistrih     W.Emit('t', 8);
44e0308279SFrancis Visoiu Mistrih     W.Emit('r', 8);
45e0308279SFrancis Visoiu Mistrih     W.Emit(0, 8);
46e0308279SFrancis Visoiu Mistrih   }
471def2579SDavid Blaikie   EXPECT_EQ(Expected.str(), Buffer);
48e0308279SFrancis Visoiu Mistrih }
49e0308279SFrancis Visoiu Mistrih 
TEST(BitstreamWriterTest,emitBlobEmpty)50e0308279SFrancis Visoiu Mistrih TEST(BitstreamWriterTest, emitBlobEmpty) {
51e0308279SFrancis Visoiu Mistrih   SmallString<64> Buffer;
52e0308279SFrancis Visoiu Mistrih   BitstreamWriter W(Buffer);
53e0308279SFrancis Visoiu Mistrih   W.emitBlob("", /* ShouldEmitSize */ false);
54e0308279SFrancis Visoiu Mistrih   EXPECT_EQ(StringRef(""), Buffer);
55e0308279SFrancis Visoiu Mistrih }
56e0308279SFrancis Visoiu Mistrih 
TEST(BitstreamWriterTest,emitBlob4ByteAligned)57e0308279SFrancis Visoiu Mistrih TEST(BitstreamWriterTest, emitBlob4ByteAligned) {
58e0308279SFrancis Visoiu Mistrih   SmallString<64> Buffer;
59e0308279SFrancis Visoiu Mistrih   BitstreamWriter W(Buffer);
60e0308279SFrancis Visoiu Mistrih   W.emitBlob("str0", /* ShouldEmitSize */ false);
61e0308279SFrancis Visoiu Mistrih   EXPECT_EQ(StringRef("str0"), Buffer);
62e0308279SFrancis Visoiu Mistrih }
63e0308279SFrancis Visoiu Mistrih 
64*7cfffe74SMircea Trofin class BitstreamWriterFlushTest : public ::testing::TestWithParam<int> {
65*7cfffe74SMircea Trofin protected:
66*7cfffe74SMircea Trofin   // Any value after bitc::FIRST_APPLICATION_BLOCKID is good, but let's pick a
67*7cfffe74SMircea Trofin   // distinctive one.
68*7cfffe74SMircea Trofin   const unsigned BlkID = bitc::FIRST_APPLICATION_BLOCKID + 17;
69*7cfffe74SMircea Trofin 
write(StringRef TestFilePath,int FlushThreshold,llvm::function_ref<void (BitstreamWriter &)> Action)70*7cfffe74SMircea Trofin   void write(StringRef TestFilePath, int FlushThreshold,
71*7cfffe74SMircea Trofin              llvm::function_ref<void(BitstreamWriter &)> Action) {
72*7cfffe74SMircea Trofin     std::error_code EC;
73*7cfffe74SMircea Trofin     raw_fd_stream Out(TestFilePath, EC);
74*7cfffe74SMircea Trofin     ASSERT_FALSE(EC);
75*7cfffe74SMircea Trofin     BitstreamWriter W(Out, FlushThreshold);
76*7cfffe74SMircea Trofin     Action(W);
77*7cfffe74SMircea Trofin   }
78*7cfffe74SMircea Trofin };
79*7cfffe74SMircea Trofin 
TEST_P(BitstreamWriterFlushTest,simpleExample)80*7cfffe74SMircea Trofin TEST_P(BitstreamWriterFlushTest, simpleExample) {
81*7cfffe74SMircea Trofin   llvm::unittest::TempFile TestFile("bitstream", "", "",
82*7cfffe74SMircea Trofin                                     /*Unique*/ true);
83*7cfffe74SMircea Trofin   write(TestFile.path(), GetParam(),
84*7cfffe74SMircea Trofin         [&](BitstreamWriter &W) { W.EmitVBR(42, 2); });
85*7cfffe74SMircea Trofin 
86*7cfffe74SMircea Trofin   ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
87*7cfffe74SMircea Trofin       MemoryBuffer::getFile(TestFile.path());
88*7cfffe74SMircea Trofin   ASSERT_TRUE(!!MB);
89*7cfffe74SMircea Trofin   ASSERT_NE(*MB, nullptr);
90*7cfffe74SMircea Trofin   BitstreamCursor Cursor((*MB)->getBuffer());
91*7cfffe74SMircea Trofin   auto V = Cursor.ReadVBR(2);
92*7cfffe74SMircea Trofin   EXPECT_TRUE(!!V);
93*7cfffe74SMircea Trofin   EXPECT_EQ(*V, 42U);
94*7cfffe74SMircea Trofin }
95*7cfffe74SMircea Trofin 
TEST_P(BitstreamWriterFlushTest,subBlock)96*7cfffe74SMircea Trofin TEST_P(BitstreamWriterFlushTest, subBlock) {
97*7cfffe74SMircea Trofin   llvm::unittest::TempFile TestFile("bitstream", "", "",
98*7cfffe74SMircea Trofin                                     /*Unique*/ true);
99*7cfffe74SMircea Trofin   write(TestFile.path(), GetParam(), [&](BitstreamWriter &W) {
100*7cfffe74SMircea Trofin     W.EnterSubblock(BlkID, 2);
101*7cfffe74SMircea Trofin     W.EmitVBR(42, 2);
102*7cfffe74SMircea Trofin     W.ExitBlock();
103*7cfffe74SMircea Trofin   });
104*7cfffe74SMircea Trofin   ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
105*7cfffe74SMircea Trofin       MemoryBuffer::getFile(TestFile.path());
106*7cfffe74SMircea Trofin   ASSERT_TRUE(!!MB);
107*7cfffe74SMircea Trofin   ASSERT_NE(*MB, nullptr);
108*7cfffe74SMircea Trofin   BitstreamCursor Cursor((*MB)->getBuffer());
109*7cfffe74SMircea Trofin   auto Blk = Cursor.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
110*7cfffe74SMircea Trofin   ASSERT_TRUE(!!Blk);
111*7cfffe74SMircea Trofin   EXPECT_EQ(Blk->Kind, BitstreamEntry::SubBlock);
112*7cfffe74SMircea Trofin   EXPECT_EQ(Blk->ID, BlkID);
113*7cfffe74SMircea Trofin   EXPECT_FALSE(Cursor.EnterSubBlock(BlkID));
114*7cfffe74SMircea Trofin   auto V = Cursor.ReadVBR(2);
115*7cfffe74SMircea Trofin   EXPECT_TRUE(!!V);
116*7cfffe74SMircea Trofin   EXPECT_EQ(*V, 42U);
117*7cfffe74SMircea Trofin   // ReadBlockEnd() returns false if it actually read the block end.
118*7cfffe74SMircea Trofin   EXPECT_FALSE(Cursor.ReadBlockEnd());
119*7cfffe74SMircea Trofin   EXPECT_TRUE(Cursor.AtEndOfStream());
120*7cfffe74SMircea Trofin }
121*7cfffe74SMircea Trofin 
TEST_P(BitstreamWriterFlushTest,blobRawRead)122*7cfffe74SMircea Trofin TEST_P(BitstreamWriterFlushTest, blobRawRead) {
123*7cfffe74SMircea Trofin   llvm::unittest::TempFile TestFile("bitstream", "", "",
124*7cfffe74SMircea Trofin                                     /*Unique*/ true);
125*7cfffe74SMircea Trofin   write(TestFile.path(), GetParam(), [&](BitstreamWriter &W) {
126*7cfffe74SMircea Trofin     W.emitBlob("str", /* ShouldEmitSize */ false);
127*7cfffe74SMircea Trofin   });
128*7cfffe74SMircea Trofin 
129*7cfffe74SMircea Trofin   ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
130*7cfffe74SMircea Trofin       MemoryBuffer::getFile(TestFile.path());
131*7cfffe74SMircea Trofin   ASSERT_TRUE(!!MB);
132*7cfffe74SMircea Trofin   ASSERT_NE(*MB, nullptr);
133*7cfffe74SMircea Trofin   EXPECT_EQ(StringRef("str\0", 4), (*MB)->getBuffer());
134*7cfffe74SMircea Trofin }
135*7cfffe74SMircea Trofin 
136*7cfffe74SMircea Trofin INSTANTIATE_TEST_SUITE_P(BitstreamWriterFlushCases, BitstreamWriterFlushTest,
137*7cfffe74SMircea Trofin                          ::testing::Values(0, 1 /*MB*/));
138e0308279SFrancis Visoiu Mistrih } // end namespace
139