xref: /aosp_15_r20/frameworks/base/libs/androidfw/BigBufferStream.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #include "androidfw/BigBufferStream.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <algorithm>
20*d57664e9SAndroid Build Coastguard Worker 
21*d57664e9SAndroid Build Coastguard Worker namespace android {
22*d57664e9SAndroid Build Coastguard Worker 
23*d57664e9SAndroid Build Coastguard Worker //
24*d57664e9SAndroid Build Coastguard Worker // BigBufferInputStream
25*d57664e9SAndroid Build Coastguard Worker //
26*d57664e9SAndroid Build Coastguard Worker 
Next(const void ** data,size_t * size)27*d57664e9SAndroid Build Coastguard Worker bool BigBufferInputStream::Next(const void** data, size_t* size) {
28*d57664e9SAndroid Build Coastguard Worker   if (iter_ == buffer_->end()) {
29*d57664e9SAndroid Build Coastguard Worker     return false;
30*d57664e9SAndroid Build Coastguard Worker   }
31*d57664e9SAndroid Build Coastguard Worker 
32*d57664e9SAndroid Build Coastguard Worker   if (offset_ == iter_->size) {
33*d57664e9SAndroid Build Coastguard Worker     ++iter_;
34*d57664e9SAndroid Build Coastguard Worker     if (iter_ == buffer_->end()) {
35*d57664e9SAndroid Build Coastguard Worker       return false;
36*d57664e9SAndroid Build Coastguard Worker     }
37*d57664e9SAndroid Build Coastguard Worker     offset_ = 0;
38*d57664e9SAndroid Build Coastguard Worker   }
39*d57664e9SAndroid Build Coastguard Worker 
40*d57664e9SAndroid Build Coastguard Worker   *data = iter_->buffer.get() + offset_;
41*d57664e9SAndroid Build Coastguard Worker   *size = iter_->size - offset_;
42*d57664e9SAndroid Build Coastguard Worker   bytes_read_ += iter_->size - offset_;
43*d57664e9SAndroid Build Coastguard Worker   offset_ = iter_->size;
44*d57664e9SAndroid Build Coastguard Worker   return true;
45*d57664e9SAndroid Build Coastguard Worker }
46*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)47*d57664e9SAndroid Build Coastguard Worker void BigBufferInputStream::BackUp(size_t count) {
48*d57664e9SAndroid Build Coastguard Worker   if (count > offset_) {
49*d57664e9SAndroid Build Coastguard Worker     bytes_read_ -= offset_;
50*d57664e9SAndroid Build Coastguard Worker     offset_ = 0;
51*d57664e9SAndroid Build Coastguard Worker   } else {
52*d57664e9SAndroid Build Coastguard Worker     offset_ -= count;
53*d57664e9SAndroid Build Coastguard Worker     bytes_read_ -= count;
54*d57664e9SAndroid Build Coastguard Worker   }
55*d57664e9SAndroid Build Coastguard Worker }
56*d57664e9SAndroid Build Coastguard Worker 
CanRewind() const57*d57664e9SAndroid Build Coastguard Worker bool BigBufferInputStream::CanRewind() const {
58*d57664e9SAndroid Build Coastguard Worker   return true;
59*d57664e9SAndroid Build Coastguard Worker }
60*d57664e9SAndroid Build Coastguard Worker 
Rewind()61*d57664e9SAndroid Build Coastguard Worker bool BigBufferInputStream::Rewind() {
62*d57664e9SAndroid Build Coastguard Worker   iter_ = buffer_->begin();
63*d57664e9SAndroid Build Coastguard Worker   offset_ = 0;
64*d57664e9SAndroid Build Coastguard Worker   bytes_read_ = 0;
65*d57664e9SAndroid Build Coastguard Worker   return true;
66*d57664e9SAndroid Build Coastguard Worker }
67*d57664e9SAndroid Build Coastguard Worker 
ByteCount() const68*d57664e9SAndroid Build Coastguard Worker size_t BigBufferInputStream::ByteCount() const {
69*d57664e9SAndroid Build Coastguard Worker   return bytes_read_;
70*d57664e9SAndroid Build Coastguard Worker }
71*d57664e9SAndroid Build Coastguard Worker 
HadError() const72*d57664e9SAndroid Build Coastguard Worker bool BigBufferInputStream::HadError() const {
73*d57664e9SAndroid Build Coastguard Worker   return false;
74*d57664e9SAndroid Build Coastguard Worker }
75*d57664e9SAndroid Build Coastguard Worker 
TotalSize() const76*d57664e9SAndroid Build Coastguard Worker size_t BigBufferInputStream::TotalSize() const {
77*d57664e9SAndroid Build Coastguard Worker   return buffer_->size();
78*d57664e9SAndroid Build Coastguard Worker }
79*d57664e9SAndroid Build Coastguard Worker 
ReadFullyAtOffset(void * data,size_t byte_count,off64_t offset)80*d57664e9SAndroid Build Coastguard Worker bool BigBufferInputStream::ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) {
81*d57664e9SAndroid Build Coastguard Worker   if (byte_count == 0) {
82*d57664e9SAndroid Build Coastguard Worker     return true;
83*d57664e9SAndroid Build Coastguard Worker   }
84*d57664e9SAndroid Build Coastguard Worker   if (offset < 0) {
85*d57664e9SAndroid Build Coastguard Worker     return false;
86*d57664e9SAndroid Build Coastguard Worker   }
87*d57664e9SAndroid Build Coastguard Worker   if (offset > std::numeric_limits<off64_t>::max() - byte_count) {
88*d57664e9SAndroid Build Coastguard Worker     return false;
89*d57664e9SAndroid Build Coastguard Worker   }
90*d57664e9SAndroid Build Coastguard Worker   if (offset + byte_count > buffer_->size()) {
91*d57664e9SAndroid Build Coastguard Worker     return false;
92*d57664e9SAndroid Build Coastguard Worker   }
93*d57664e9SAndroid Build Coastguard Worker   auto p = reinterpret_cast<uint8_t*>(data);
94*d57664e9SAndroid Build Coastguard Worker   for (auto iter = buffer_->begin(); iter != buffer_->end() && byte_count > 0; ++iter) {
95*d57664e9SAndroid Build Coastguard Worker     if (offset < iter->size) {
96*d57664e9SAndroid Build Coastguard Worker       size_t to_read = std::min(byte_count, (size_t)(iter->size - offset));
97*d57664e9SAndroid Build Coastguard Worker       memcpy(p, iter->buffer.get() + offset, to_read);
98*d57664e9SAndroid Build Coastguard Worker       byte_count -= to_read;
99*d57664e9SAndroid Build Coastguard Worker       p += to_read;
100*d57664e9SAndroid Build Coastguard Worker       offset = 0;
101*d57664e9SAndroid Build Coastguard Worker     } else {
102*d57664e9SAndroid Build Coastguard Worker       offset -= iter->size;
103*d57664e9SAndroid Build Coastguard Worker     }
104*d57664e9SAndroid Build Coastguard Worker   }
105*d57664e9SAndroid Build Coastguard Worker   return byte_count == 0;
106*d57664e9SAndroid Build Coastguard Worker }
107*d57664e9SAndroid Build Coastguard Worker 
108*d57664e9SAndroid Build Coastguard Worker //
109*d57664e9SAndroid Build Coastguard Worker // BigBufferOutputStream
110*d57664e9SAndroid Build Coastguard Worker //
111*d57664e9SAndroid Build Coastguard Worker 
Next(void ** data,size_t * size)112*d57664e9SAndroid Build Coastguard Worker bool BigBufferOutputStream::Next(void** data, size_t* size) {
113*d57664e9SAndroid Build Coastguard Worker   *data = buffer_->NextBlock(size);
114*d57664e9SAndroid Build Coastguard Worker   return true;
115*d57664e9SAndroid Build Coastguard Worker }
116*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)117*d57664e9SAndroid Build Coastguard Worker void BigBufferOutputStream::BackUp(size_t count) {
118*d57664e9SAndroid Build Coastguard Worker   buffer_->BackUp(count);
119*d57664e9SAndroid Build Coastguard Worker }
120*d57664e9SAndroid Build Coastguard Worker 
ByteCount() const121*d57664e9SAndroid Build Coastguard Worker size_t BigBufferOutputStream::ByteCount() const {
122*d57664e9SAndroid Build Coastguard Worker   return buffer_->size();
123*d57664e9SAndroid Build Coastguard Worker }
124*d57664e9SAndroid Build Coastguard Worker 
HadError() const125*d57664e9SAndroid Build Coastguard Worker bool BigBufferOutputStream::HadError() const {
126*d57664e9SAndroid Build Coastguard Worker   return false;
127*d57664e9SAndroid Build Coastguard Worker }
128*d57664e9SAndroid Build Coastguard Worker 
129*d57664e9SAndroid Build Coastguard Worker }  // namespace android
130