xref: /aosp_15_r20/external/zucchini/buffer_source.cc (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński 
5*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/buffer_source.h"
6*a03ca8b9SKrzysztof Kosiński 
7*a03ca8b9SKrzysztof Kosiński #include <algorithm>
8*a03ca8b9SKrzysztof Kosiński 
9*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/algorithm.h"
10*a03ca8b9SKrzysztof Kosiński 
11*a03ca8b9SKrzysztof Kosiński namespace zucchini {
12*a03ca8b9SKrzysztof Kosiński 
BufferSource(ConstBufferView buffer)13*a03ca8b9SKrzysztof Kosiński BufferSource::BufferSource(ConstBufferView buffer) : ConstBufferView(buffer) {}
14*a03ca8b9SKrzysztof Kosiński 
Skip(size_type n)15*a03ca8b9SKrzysztof Kosiński BufferSource& BufferSource::Skip(size_type n) {
16*a03ca8b9SKrzysztof Kosiński   remove_prefix(std::min(n, Remaining()));
17*a03ca8b9SKrzysztof Kosiński   return *this;
18*a03ca8b9SKrzysztof Kosiński }
19*a03ca8b9SKrzysztof Kosiński 
CheckNextBytes(std::initializer_list<uint8_t> bytes) const20*a03ca8b9SKrzysztof Kosiński bool BufferSource::CheckNextBytes(std::initializer_list<uint8_t> bytes) const {
21*a03ca8b9SKrzysztof Kosiński   if (Remaining() < bytes.size())
22*a03ca8b9SKrzysztof Kosiński     return false;
23*a03ca8b9SKrzysztof Kosiński   return std::mismatch(bytes.begin(), bytes.end(), begin()).first ==
24*a03ca8b9SKrzysztof Kosiński          bytes.end();
25*a03ca8b9SKrzysztof Kosiński }
26*a03ca8b9SKrzysztof Kosiński 
ConsumeBytes(std::initializer_list<uint8_t> bytes)27*a03ca8b9SKrzysztof Kosiński bool BufferSource::ConsumeBytes(std::initializer_list<uint8_t> bytes) {
28*a03ca8b9SKrzysztof Kosiński   if (!CheckNextBytes(bytes))
29*a03ca8b9SKrzysztof Kosiński     return false;
30*a03ca8b9SKrzysztof Kosiński   remove_prefix(bytes.size());
31*a03ca8b9SKrzysztof Kosiński   return true;
32*a03ca8b9SKrzysztof Kosiński }
33*a03ca8b9SKrzysztof Kosiński 
GetRegion(size_type count,ConstBufferView * buffer)34*a03ca8b9SKrzysztof Kosiński bool BufferSource::GetRegion(size_type count, ConstBufferView* buffer) {
35*a03ca8b9SKrzysztof Kosiński   DCHECK_NE(begin(), nullptr);
36*a03ca8b9SKrzysztof Kosiński   if (Remaining() < count)
37*a03ca8b9SKrzysztof Kosiński     return false;
38*a03ca8b9SKrzysztof Kosiński   *buffer = ConstBufferView(begin(), count);
39*a03ca8b9SKrzysztof Kosiński   remove_prefix(count);
40*a03ca8b9SKrzysztof Kosiński   return true;
41*a03ca8b9SKrzysztof Kosiński }
42*a03ca8b9SKrzysztof Kosiński 
43*a03ca8b9SKrzysztof Kosiński // [0aaaaaaa] => 00000000'00000000'00000000'0aaaaaaa
44*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 0bbbbbbb] => 00000000'00000000'00bbbbbb'baaaaaaa
45*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 1bbbbbbb 0ccccccc] => 00000000'000ccccc'ccbbbbbb'baaaaaaa
46*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 1bbbbbbb 1ccccccc 0ddddddd] => 0000dddd'dddccccc'ccbbbbbb'baaaaaaa
47*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 1bbbbbbb 1ccccccc 1ddddddd 0???eeee]
48*a03ca8b9SKrzysztof Kosiński //     => eeeedddd'dddccccc'ccbbbbbb'baaaaaaa
49*a03ca8b9SKrzysztof Kosiński // Note that "???" is discarded. Meanwhile, 1???eeee is invalid.
GetUleb128(uint32_t * ret)50*a03ca8b9SKrzysztof Kosiński bool BufferSource::GetUleb128(uint32_t* ret) {
51*a03ca8b9SKrzysztof Kosiński   int shift_lim =
52*a03ca8b9SKrzysztof Kosiński       static_cast<int>(std::min<size_type>(kMaxLeb128Size, size())) * 7;
53*a03ca8b9SKrzysztof Kosiński   const_iterator cur = cbegin();
54*a03ca8b9SKrzysztof Kosiński   uint32_t value = 0U;
55*a03ca8b9SKrzysztof Kosiński   for (int shift = 0; shift < shift_lim; shift += 7, ++cur) {
56*a03ca8b9SKrzysztof Kosiński     uint32_t b = *cur;
57*a03ca8b9SKrzysztof Kosiński     // When |shift == 28|, |(b & 0x7F) << shift| discards the "???" bits.
58*a03ca8b9SKrzysztof Kosiński     value |= static_cast<uint32_t>(b & 0x7F) << shift;
59*a03ca8b9SKrzysztof Kosiński     if (!(b & 0x80)) {
60*a03ca8b9SKrzysztof Kosiński       *ret = value;
61*a03ca8b9SKrzysztof Kosiński       seek(cur + 1);
62*a03ca8b9SKrzysztof Kosiński       return true;
63*a03ca8b9SKrzysztof Kosiński     }
64*a03ca8b9SKrzysztof Kosiński   }
65*a03ca8b9SKrzysztof Kosiński   return false;
66*a03ca8b9SKrzysztof Kosiński }
67*a03ca8b9SKrzysztof Kosiński 
68*a03ca8b9SKrzysztof Kosiński // [0Saaaaaa] => SSSSSSSS'SSSSSSSS'SSSSSSSS'SSaaaaaa
69*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 0Sbbbbbb] => SSSSSSSS'SSSSSSSS'SSSbbbbb'baaaaaaa
70*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 1bbbbbbb 0Scccccc] => SSSSSSSS'SSSScccc'ccbbbbbb'baaaaaaa
71*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 1bbbbbbb 1ccccccc 0Sdddddd] => SSSSSddd'dddccccc'ccbbbbbb'baaaaaaa
72*a03ca8b9SKrzysztof Kosiński // [1aaaaaaa 1bbbbbbb 1ccccccc 1ddddddd 0???Seee]
73*a03ca8b9SKrzysztof Kosiński //     => Seeedddd'dddccccc'ccbbbbbb'baaaaaaa
74*a03ca8b9SKrzysztof Kosiński // Note that "???" is discarded. Meanwhile, 1???eeee is invalid.
GetSleb128(int32_t * ret)75*a03ca8b9SKrzysztof Kosiński bool BufferSource::GetSleb128(int32_t* ret) {
76*a03ca8b9SKrzysztof Kosiński   int shift_lim =
77*a03ca8b9SKrzysztof Kosiński       static_cast<int>(std::min<size_type>(kMaxLeb128Size, size())) * 7;
78*a03ca8b9SKrzysztof Kosiński   const_iterator cur = cbegin();
79*a03ca8b9SKrzysztof Kosiński   int32_t value = 0;
80*a03ca8b9SKrzysztof Kosiński   for (int shift = 0; shift < shift_lim; shift += 7, ++cur) {
81*a03ca8b9SKrzysztof Kosiński     uint32_t b = *cur;
82*a03ca8b9SKrzysztof Kosiński     // When |shift == 28|, |(b & 0x7F) << shift| discards the "???" bits.
83*a03ca8b9SKrzysztof Kosiński     value |= static_cast<int32_t>(static_cast<uint32_t>(b & 0x7F) << shift);
84*a03ca8b9SKrzysztof Kosiński     if (!(b & 0x80)) {
85*a03ca8b9SKrzysztof Kosiński       *ret = (shift == 28) ? value : SignExtend(shift + 6, value);
86*a03ca8b9SKrzysztof Kosiński       seek(cur + 1);
87*a03ca8b9SKrzysztof Kosiński       return true;
88*a03ca8b9SKrzysztof Kosiński     }
89*a03ca8b9SKrzysztof Kosiński   }
90*a03ca8b9SKrzysztof Kosiński   return false;
91*a03ca8b9SKrzysztof Kosiński }
92*a03ca8b9SKrzysztof Kosiński 
SkipLeb128()93*a03ca8b9SKrzysztof Kosiński bool BufferSource::SkipLeb128() {
94*a03ca8b9SKrzysztof Kosiński   int lim = static_cast<int>(std::min<size_type>(kMaxLeb128Size, size()));
95*a03ca8b9SKrzysztof Kosiński   const_iterator cur = cbegin();
96*a03ca8b9SKrzysztof Kosiński   for (int i = 0; i < lim; ++i, ++cur) {
97*a03ca8b9SKrzysztof Kosiński     if (!(*cur & 0x80)) {
98*a03ca8b9SKrzysztof Kosiński       seek(cur + 1);
99*a03ca8b9SKrzysztof Kosiński       return true;
100*a03ca8b9SKrzysztof Kosiński     }
101*a03ca8b9SKrzysztof Kosiński   }
102*a03ca8b9SKrzysztof Kosiński   return false;
103*a03ca8b9SKrzysztof Kosiński }
104*a03ca8b9SKrzysztof Kosiński 
105*a03ca8b9SKrzysztof Kosiński }  // namespace zucchini
106