1//===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/Bitcode/BitstreamReader.h"
12#include "llvm/Bitcode/BitstreamWriter.h"
13#include "llvm/Support/StreamingMemoryObject.h"
14#include "gtest/gtest.h"
15
16using namespace llvm;
17
18namespace {
19
20class BufferStreamer : public DataStreamer {
21  StringRef Buffer;
22
23public:
24  BufferStreamer(StringRef Buffer) : Buffer(Buffer) {}
25  size_t GetBytes(unsigned char *OutBuffer, size_t Length) override {
26    if (Length >= Buffer.size())
27      Length = Buffer.size();
28
29    std::copy(Buffer.begin(), Buffer.begin() + Length, OutBuffer);
30    Buffer = Buffer.drop_front(Length);
31    return Length;
32  }
33};
34
35TEST(BitstreamReaderTest, AtEndOfStream) {
36  uint8_t Bytes[4] = {
37    0x00, 0x01, 0x02, 0x03
38  };
39  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
40  BitstreamCursor Cursor(Reader);
41
42  EXPECT_FALSE(Cursor.AtEndOfStream());
43  (void)Cursor.Read(8);
44  EXPECT_FALSE(Cursor.AtEndOfStream());
45  (void)Cursor.Read(24);
46  EXPECT_TRUE(Cursor.AtEndOfStream());
47
48  Cursor.JumpToBit(0);
49  EXPECT_FALSE(Cursor.AtEndOfStream());
50
51  Cursor.JumpToBit(32);
52  EXPECT_TRUE(Cursor.AtEndOfStream());
53}
54
55TEST(BitstreamReaderTest, AtEndOfStreamJump) {
56  uint8_t Bytes[4] = {
57    0x00, 0x01, 0x02, 0x03
58  };
59  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
60  BitstreamCursor Cursor(Reader);
61
62  Cursor.JumpToBit(32);
63  EXPECT_TRUE(Cursor.AtEndOfStream());
64}
65
66TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
67  uint8_t Dummy = 0xFF;
68  BitstreamReader Reader(&Dummy, &Dummy);
69  BitstreamCursor Cursor(Reader);
70
71  EXPECT_TRUE(Cursor.AtEndOfStream());
72}
73
74TEST(BitstreamReaderTest, getCurrentByteNo) {
75  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
76  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
77  SimpleBitstreamCursor Cursor(Reader);
78
79  for (unsigned I = 0, E = 33; I != E; ++I) {
80    EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
81    (void)Cursor.Read(1);
82  }
83  EXPECT_EQ(4u, Cursor.getCurrentByteNo());
84}
85
86TEST(BitstreamReaderTest, getPointerToByte) {
87  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
88  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
89  SimpleBitstreamCursor Cursor(Reader);
90
91  for (unsigned I = 0, E = 8; I != E; ++I) {
92    EXPECT_EQ(Bytes + I, Cursor.getPointerToByte(I, 1));
93  }
94}
95
96TEST(BitstreamReaderTest, getPointerToBit) {
97  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
98  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
99  SimpleBitstreamCursor Cursor(Reader);
100
101  for (unsigned I = 0, E = 8; I != E; ++I) {
102    EXPECT_EQ(Bytes + I, Cursor.getPointerToBit(I * 8, 1));
103  }
104}
105
106TEST(BitstreamReaderTest, jumpToPointer) {
107  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
108  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
109  SimpleBitstreamCursor Cursor(Reader);
110
111  for (unsigned I : {0, 6, 2, 7}) {
112    Cursor.jumpToPointer(Bytes + I);
113    EXPECT_EQ(I, Cursor.getCurrentByteNo());
114  }
115}
116
117TEST(BitstreamReaderTest, setArtificialByteLimit) {
118  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
119                     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
120  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
121  SimpleBitstreamCursor Cursor(Reader);
122
123  Cursor.setArtificialByteLimit(8);
124  EXPECT_EQ(8u, Cursor.getSizeIfKnown());
125  while (!Cursor.AtEndOfStream())
126    (void)Cursor.Read(1);
127
128  EXPECT_EQ(8u, Cursor.getCurrentByteNo());
129}
130
131TEST(BitstreamReaderTest, setArtificialByteLimitNotWordBoundary) {
132  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
133                     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
134  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
135  SimpleBitstreamCursor Cursor(Reader);
136
137  Cursor.setArtificialByteLimit(5);
138  EXPECT_EQ(8u, Cursor.getSizeIfKnown());
139  while (!Cursor.AtEndOfStream())
140    (void)Cursor.Read(1);
141
142  EXPECT_EQ(8u, Cursor.getCurrentByteNo());
143}
144
145TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEnd) {
146  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
147                     0x08, 0x09, 0x0a, 0x0b};
148  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
149  SimpleBitstreamCursor Cursor(Reader);
150
151  // The size of the memory object isn't known yet.  Set it too high and
152  // confirm that we don't read too far.
153  Cursor.setArtificialByteLimit(24);
154  EXPECT_EQ(24u, Cursor.getSizeIfKnown());
155  while (!Cursor.AtEndOfStream())
156    (void)Cursor.Read(1);
157
158  EXPECT_EQ(12u, Cursor.getCurrentByteNo());
159  EXPECT_EQ(12u, Cursor.getSizeIfKnown());
160}
161
162TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEndKnown) {
163  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
164                     0x08, 0x09, 0x0a, 0x0b};
165  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
166  SimpleBitstreamCursor Cursor(Reader);
167
168  // Save the size of the memory object in the cursor.
169  while (!Cursor.AtEndOfStream())
170    (void)Cursor.Read(1);
171  EXPECT_EQ(12u, Cursor.getCurrentByteNo());
172  EXPECT_EQ(12u, Cursor.getSizeIfKnown());
173
174  Cursor.setArtificialByteLimit(20);
175  EXPECT_TRUE(Cursor.AtEndOfStream());
176  EXPECT_EQ(12u, Cursor.getSizeIfKnown());
177}
178
179TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
180  SmallVector<uint8_t, 1> BlobData;
181  for (unsigned I = 0, E = 1024; I != E; ++I)
182    BlobData.push_back(I);
183
184  // Try a bunch of different sizes.
185  const unsigned Magic = 0x12345678;
186  const unsigned BlockID = bitc::FIRST_APPLICATION_BLOCKID;
187  const unsigned RecordID = 1;
188  for (unsigned I = 0, BlobSize = 0, E = BlobData.size(); BlobSize < E;
189       BlobSize += ++I) {
190    StringRef BlobIn((const char *)BlobData.begin(), BlobSize);
191
192    // Write the bitcode.
193    SmallVector<char, 1> Buffer;
194    unsigned AbbrevID;
195    {
196      BitstreamWriter Stream(Buffer);
197      Stream.Emit(Magic, 32);
198      Stream.EnterSubblock(BlockID, 3);
199
200      BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
201      Abbrev->Add(BitCodeAbbrevOp(RecordID));
202      Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
203      AbbrevID = Stream.EmitAbbrev(Abbrev);
204      unsigned Record[] = {RecordID};
205      Stream.EmitRecordWithBlob(AbbrevID, makeArrayRef(Record), BlobIn);
206
207      Stream.ExitBlock();
208    }
209
210    // Stream the buffer into the reader.
211    BitstreamReader R(llvm::make_unique<StreamingMemoryObject>(
212        llvm::make_unique<BufferStreamer>(
213            StringRef(Buffer.begin(), Buffer.size()))));
214    BitstreamCursor Stream(R);
215
216    // Header.  Included in test so that we can run llvm-bcanalyzer to debug
217    // when there are problems.
218    ASSERT_EQ(Magic, Stream.Read(32));
219
220    // Block.
221    BitstreamEntry Entry =
222        Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
223    ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
224    ASSERT_EQ(BlockID, Entry.ID);
225    ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
226
227    // Abbreviation.
228    Entry = Stream.advance();
229    ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
230    ASSERT_EQ(AbbrevID, Entry.ID);
231
232    // Record.
233    StringRef BlobOut;
234    SmallVector<uint64_t, 1> Record;
235    ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
236    EXPECT_TRUE(Record.empty());
237    EXPECT_EQ(BlobIn, BlobOut);
238  }
239}
240
241} // end anonymous namespace
242