1c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani// Copyright 2017 The Chromium OS Authors. All rights reserved.
2c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani// Use of this source code is governed by a BSD-style license that can be
3c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani// found in the LICENSE file.
4c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
5c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani#include <cstring>
6c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
7c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani#include "gtest/gtest.h"
8c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
9c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani#include "puffin/src/bit_reader.h"
10c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani#include "puffin/src/bit_writer.h"
11c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani#include "puffin/src/set_errors.h"
12c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani#include "puffin/src/unittest_common.h"
13c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
14c3e6b533aa435516b788ae353a43602c57936afdAmin Hassaninamespace puffin {
15c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
16c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani// Testing |BufferBitReader| and |BufferBitWriter|.
17c3e6b533aa435516b788ae353a43602c57936afdAmin HassaniTEST(BitIOTest, BitWriterAndBitReaderTest) {
18c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  static const size_t kSize = 5;
19c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  uint8_t buf[kSize];
20c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
21c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  puffin::BufferBitWriter bw(buf, kSize);
22c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBits(0, 0x05));
23c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBits(3, 0x05));
24c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBits(8, 0xFF));
25c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBoundaryBits(0x0F));
26c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  uint8_t tmp[] = {1, 2};
27c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  size_t index = 0;
28c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBytes(2, [&tmp, &index](uint8_t* buffer, size_t count) {
29c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani    if (count > 2 - index)
30c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani      return false;
31c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani    memcpy(buffer, &tmp[index], count);
32c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani    return true;
33c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  }));
34c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_FALSE(bw.WriteBits(9, 0x1C));
35c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBits(4, 0x0A));
36c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.WriteBoundaryBits(0xBB));
37c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(bw.Flush());
38c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(5, bw.Size());
39c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
40c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  puffin::BufferBitReader br(buf, kSize);
41c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(br.CacheBits(11));
42c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(br.ReadBits(3), 0x05);
43c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  br.DropBits(3);
44c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(br.ReadBits(8), 0xFF);
45c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  br.DropBits(8);
46c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(br.ReadBoundaryBits(), 0x0F);
47ec69c2b78e2359774678d084510c575cbc593471Amin Hassani  ASSERT_EQ(br.SkipBoundaryBits(), 5);
48c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  std::function<bool(uint8_t*, size_t)> read_fn;
49c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(br.GetByteReaderFn(2, &read_fn));
50c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(read_fn(tmp, 2));
51c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(br.Offset(), 4);
52c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(read_fn(tmp, 0));
53c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_FALSE(read_fn(tmp, 1));
54c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_FALSE(br.CacheBits(9));
55c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_TRUE(br.CacheBits(8));
56c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(br.ReadBits(4), 0x0A);
57c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  br.DropBits(4);
58c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_EQ(br.ReadBoundaryBits(), 0x0B);
59ec69c2b78e2359774678d084510c575cbc593471Amin Hassani  ASSERT_EQ(br.SkipBoundaryBits(), 4);
60ec69c2b78e2359774678d084510c575cbc593471Amin Hassani  ASSERT_EQ(br.ReadBoundaryBits(), 0);
61ec69c2b78e2359774678d084510c575cbc593471Amin Hassani  ASSERT_EQ(br.SkipBoundaryBits(), 0);
62c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani  ASSERT_FALSE(br.CacheBits(1));
63c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani}
64c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani
65c3e6b533aa435516b788ae353a43602c57936afdAmin Hassani}  // namespace puffin
66