• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "byte_input_stream.h"
18 
19 #include "berberis/base/checks.h"
20 
21 #include "leb128.h"
22 
23 namespace nogrod {
24 
ByteInputStream(const uint8_t * buffer,size_t size)25 ByteInputStream::ByteInputStream(const uint8_t* buffer, size_t size)
26     : buffer_(buffer), size_(size), offset_(0) {}
27 
available() const28 bool ByteInputStream::available() const {
29   return offset_ < size_;
30 }
31 
offset() const32 uint64_t ByteInputStream::offset() const {
33   return offset_;
34 }
35 
ReadUint8()36 uint8_t ByteInputStream::ReadUint8() {
37   CHECK(offset_ < size_);
38   return buffer_[offset_++];
39 }
40 
ReadUint16()41 uint16_t ByteInputStream::ReadUint16() {
42   uint16_t result;
43   CHECK(offset_ + sizeof(result) <= size_);
44   memcpy(&result, buffer_ + offset_, sizeof(result));
45   offset_ += sizeof(result);
46 
47   return result;
48 }
49 
ReadUint24()50 uint32_t ByteInputStream::ReadUint24() {
51   uint32_t result = 0;
52   CHECK_LE(offset_ + 3, size_);
53   memcpy(&result, buffer_ + offset_, 3);
54   offset_ += 3;
55 
56   return result;
57 }
58 
ReadUint32()59 uint32_t ByteInputStream::ReadUint32() {
60   uint32_t result;
61   CHECK(offset_ + sizeof(result) <= size_);
62   memcpy(&result, buffer_ + offset_, sizeof(result));
63   offset_ += sizeof(result);
64 
65   return result;
66 }
67 
ReadUint64()68 uint64_t ByteInputStream::ReadUint64() {
69   uint64_t result;
70   CHECK(offset_ + sizeof(result) <= size_);
71   memcpy(&result, buffer_ + offset_, sizeof(result));
72   offset_ += sizeof(result);
73 
74   return result;
75 }
76 
ReadLeb128()77 uint64_t ByteInputStream::ReadLeb128() {
78   uint64_t result;
79   size_t bytes = DecodeLeb128(buffer_ + offset_, size_ - offset_, &result);
80   offset_ += bytes;
81   return result;
82 }
83 
ReadSleb128()84 int64_t ByteInputStream::ReadSleb128() {
85   int64_t result;
86   size_t bytes = DecodeSleb128(buffer_ + offset_, size_ - offset_, &result);
87   offset_ += bytes;
88   return result;
89 }
90 
ReadBytes(uint64_t size)91 std::vector<uint8_t> ByteInputStream::ReadBytes(uint64_t size) {
92   CHECK_LE(offset_ + size, size_);
93   // WORKAROUND(http://b/227598583): libc++ on tm-dev branch crashes of you call std::vector c-tor
94   // with size = 0;
95   if (size == 0) return {};
96   // End of workaround
97   std::vector<uint8_t> result(size);
98   memcpy(result.data(), buffer_ + offset_, size);
99   offset_ += size;
100 
101   return result;
102 }
103 
ReadString()104 std::string ByteInputStream::ReadString() {
105   CHECK_LT(offset_, size_);  // there should be a place for at least one 0
106 
107   const char* candidate = reinterpret_cast<const char*>(buffer_ + offset_);
108   while (buffer_[offset_++] != 0) {
109     CHECK_LT(offset_, size_);
110   }
111 
112   return std::string{candidate};
113 }
114 
115 }  // namespace nogrod
116