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