blob: f18199cfa52bd3a323d3c5b57dbee32c886654e8 [file] [log] [blame]
Adam Lesinski06460ef2017-03-14 18:52:13 -07001/*
2 * Copyright (C) 2017 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
Jeremy Meyerb4f83ff2023-11-30 19:29:50 +000017#include "androidfw/BigBufferStream.h"
Adam Lesinski06460ef2017-03-14 18:52:13 -070018
Jeremy Meyerb4f83ff2023-11-30 19:29:50 +000019#include <algorithm>
20
21namespace android {
Adam Lesinski06460ef2017-03-14 18:52:13 -070022
23//
24// BigBufferInputStream
25//
26
27bool BigBufferInputStream::Next(const void** data, size_t* size) {
28 if (iter_ == buffer_->end()) {
29 return false;
30 }
31
32 if (offset_ == iter_->size) {
33 ++iter_;
34 if (iter_ == buffer_->end()) {
35 return false;
36 }
37 offset_ = 0;
38 }
39
40 *data = iter_->buffer.get() + offset_;
41 *size = iter_->size - offset_;
42 bytes_read_ += iter_->size - offset_;
43 offset_ = iter_->size;
44 return true;
45}
46
47void BigBufferInputStream::BackUp(size_t count) {
48 if (count > offset_) {
49 bytes_read_ -= offset_;
50 offset_ = 0;
51 } else {
52 offset_ -= count;
53 bytes_read_ -= count;
54 }
55}
56
Adam Lesinski00451162017-10-03 07:44:08 -070057bool BigBufferInputStream::CanRewind() const {
58 return true;
59}
Adam Lesinski06460ef2017-03-14 18:52:13 -070060
61bool BigBufferInputStream::Rewind() {
62 iter_ = buffer_->begin();
63 offset_ = 0;
64 bytes_read_ = 0;
65 return true;
66}
67
Adam Lesinski00451162017-10-03 07:44:08 -070068size_t BigBufferInputStream::ByteCount() const {
69 return bytes_read_;
70}
Adam Lesinski06460ef2017-03-14 18:52:13 -070071
Adam Lesinski00451162017-10-03 07:44:08 -070072bool BigBufferInputStream::HadError() const {
73 return false;
74}
75
76size_t BigBufferInputStream::TotalSize() const {
77 return buffer_->size();
78}
Adam Lesinski06460ef2017-03-14 18:52:13 -070079
Jeremy Meyerb4f83ff2023-11-30 19:29:50 +000080bool BigBufferInputStream::ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) {
81 if (byte_count == 0) {
82 return true;
83 }
84 if (offset < 0) {
85 return false;
86 }
87 if (offset > std::numeric_limits<off64_t>::max() - byte_count) {
88 return false;
89 }
90 if (offset + byte_count > buffer_->size()) {
91 return false;
92 }
93 auto p = reinterpret_cast<uint8_t*>(data);
94 for (auto iter = buffer_->begin(); iter != buffer_->end() && byte_count > 0; ++iter) {
95 if (offset < iter->size) {
96 size_t to_read = std::min(byte_count, (size_t)(iter->size - offset));
97 memcpy(p, iter->buffer.get() + offset, to_read);
98 byte_count -= to_read;
99 p += to_read;
100 offset = 0;
101 } else {
102 offset -= iter->size;
103 }
104 }
105 return byte_count == 0;
106}
107
Adam Lesinski06460ef2017-03-14 18:52:13 -0700108//
109// BigBufferOutputStream
110//
111
112bool BigBufferOutputStream::Next(void** data, size_t* size) {
113 *data = buffer_->NextBlock(size);
114 return true;
115}
116
Adam Lesinski00451162017-10-03 07:44:08 -0700117void BigBufferOutputStream::BackUp(size_t count) {
118 buffer_->BackUp(count);
119}
Adam Lesinski06460ef2017-03-14 18:52:13 -0700120
Adam Lesinski00451162017-10-03 07:44:08 -0700121size_t BigBufferOutputStream::ByteCount() const {
122 return buffer_->size();
123}
Adam Lesinski06460ef2017-03-14 18:52:13 -0700124
Adam Lesinski00451162017-10-03 07:44:08 -0700125bool BigBufferOutputStream::HadError() const {
126 return false;
127}
Adam Lesinski06460ef2017-03-14 18:52:13 -0700128
Jeremy Meyerb4f83ff2023-11-30 19:29:50 +0000129} // namespace android