xref: /aosp_15_r20/frameworks/base/tools/aapt2/io/StringStream.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 "io/StringStream.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker using ::android::StringPiece;
20*d57664e9SAndroid Build Coastguard Worker 
21*d57664e9SAndroid Build Coastguard Worker namespace aapt {
22*d57664e9SAndroid Build Coastguard Worker namespace io {
23*d57664e9SAndroid Build Coastguard Worker 
StringInputStream(StringPiece str)24*d57664e9SAndroid Build Coastguard Worker StringInputStream::StringInputStream(StringPiece str) : str_(str), offset_(0u) {
25*d57664e9SAndroid Build Coastguard Worker }
26*d57664e9SAndroid Build Coastguard Worker 
Next(const void ** data,size_t * size)27*d57664e9SAndroid Build Coastguard Worker bool StringInputStream::Next(const void** data, size_t* size) {
28*d57664e9SAndroid Build Coastguard Worker   if (offset_ == str_.size()) {
29*d57664e9SAndroid Build Coastguard Worker     return false;
30*d57664e9SAndroid Build Coastguard Worker   }
31*d57664e9SAndroid Build Coastguard Worker 
32*d57664e9SAndroid Build Coastguard Worker   *data = str_.data() + offset_;
33*d57664e9SAndroid Build Coastguard Worker   *size = str_.size() - offset_;
34*d57664e9SAndroid Build Coastguard Worker   offset_ = str_.size();
35*d57664e9SAndroid Build Coastguard Worker   return true;
36*d57664e9SAndroid Build Coastguard Worker }
37*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)38*d57664e9SAndroid Build Coastguard Worker void StringInputStream::BackUp(size_t count) {
39*d57664e9SAndroid Build Coastguard Worker   if (count > offset_) {
40*d57664e9SAndroid Build Coastguard Worker     offset_ = 0u;
41*d57664e9SAndroid Build Coastguard Worker   } else {
42*d57664e9SAndroid Build Coastguard Worker     offset_ -= count;
43*d57664e9SAndroid Build Coastguard Worker   }
44*d57664e9SAndroid Build Coastguard Worker }
45*d57664e9SAndroid Build Coastguard Worker 
ByteCount() const46*d57664e9SAndroid Build Coastguard Worker size_t StringInputStream::ByteCount() const {
47*d57664e9SAndroid Build Coastguard Worker   return offset_;
48*d57664e9SAndroid Build Coastguard Worker }
49*d57664e9SAndroid Build Coastguard Worker 
TotalSize() const50*d57664e9SAndroid Build Coastguard Worker size_t StringInputStream::TotalSize() const {
51*d57664e9SAndroid Build Coastguard Worker   return str_.size();
52*d57664e9SAndroid Build Coastguard Worker }
53*d57664e9SAndroid Build Coastguard Worker 
ReadFullyAtOffset(void * data,size_t byte_count,off64_t offset)54*d57664e9SAndroid Build Coastguard Worker bool StringInputStream::ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) {
55*d57664e9SAndroid Build Coastguard Worker   if (byte_count == 0) {
56*d57664e9SAndroid Build Coastguard Worker     return true;
57*d57664e9SAndroid Build Coastguard Worker   }
58*d57664e9SAndroid Build Coastguard Worker   if (offset < 0) {
59*d57664e9SAndroid Build Coastguard Worker     return false;
60*d57664e9SAndroid Build Coastguard Worker   }
61*d57664e9SAndroid Build Coastguard Worker   if (offset > std::numeric_limits<off64_t>::max() - byte_count) {
62*d57664e9SAndroid Build Coastguard Worker     return false;
63*d57664e9SAndroid Build Coastguard Worker   }
64*d57664e9SAndroid Build Coastguard Worker   if (offset + byte_count > str_.size()) {
65*d57664e9SAndroid Build Coastguard Worker     return false;
66*d57664e9SAndroid Build Coastguard Worker   }
67*d57664e9SAndroid Build Coastguard Worker   memcpy(data, str_.data() + offset, byte_count);
68*d57664e9SAndroid Build Coastguard Worker   return true;
69*d57664e9SAndroid Build Coastguard Worker }
70*d57664e9SAndroid Build Coastguard Worker 
StringOutputStream(std::string * str,size_t buffer_capacity)71*d57664e9SAndroid Build Coastguard Worker StringOutputStream::StringOutputStream(std::string* str, size_t buffer_capacity)
72*d57664e9SAndroid Build Coastguard Worker     : str_(str),
73*d57664e9SAndroid Build Coastguard Worker       buffer_capacity_(buffer_capacity),
74*d57664e9SAndroid Build Coastguard Worker       buffer_offset_(0u),
75*d57664e9SAndroid Build Coastguard Worker       buffer_(new char[buffer_capacity]) {
76*d57664e9SAndroid Build Coastguard Worker }
77*d57664e9SAndroid Build Coastguard Worker 
~StringOutputStream()78*d57664e9SAndroid Build Coastguard Worker StringOutputStream::~StringOutputStream() {
79*d57664e9SAndroid Build Coastguard Worker   Flush();
80*d57664e9SAndroid Build Coastguard Worker }
81*d57664e9SAndroid Build Coastguard Worker 
Next(void ** data,size_t * size)82*d57664e9SAndroid Build Coastguard Worker bool StringOutputStream::Next(void** data, size_t* size) {
83*d57664e9SAndroid Build Coastguard Worker   if (buffer_offset_ == buffer_capacity_) {
84*d57664e9SAndroid Build Coastguard Worker     FlushImpl();
85*d57664e9SAndroid Build Coastguard Worker   }
86*d57664e9SAndroid Build Coastguard Worker 
87*d57664e9SAndroid Build Coastguard Worker   *data = buffer_.get() + buffer_offset_;
88*d57664e9SAndroid Build Coastguard Worker   *size = buffer_capacity_ - buffer_offset_;
89*d57664e9SAndroid Build Coastguard Worker   buffer_offset_ = buffer_capacity_;
90*d57664e9SAndroid Build Coastguard Worker   return true;
91*d57664e9SAndroid Build Coastguard Worker }
92*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)93*d57664e9SAndroid Build Coastguard Worker void StringOutputStream::BackUp(size_t count) {
94*d57664e9SAndroid Build Coastguard Worker   if (count > buffer_offset_) {
95*d57664e9SAndroid Build Coastguard Worker     buffer_offset_ = 0u;
96*d57664e9SAndroid Build Coastguard Worker   } else {
97*d57664e9SAndroid Build Coastguard Worker     buffer_offset_ -= count;
98*d57664e9SAndroid Build Coastguard Worker   }
99*d57664e9SAndroid Build Coastguard Worker }
100*d57664e9SAndroid Build Coastguard Worker 
ByteCount() const101*d57664e9SAndroid Build Coastguard Worker size_t StringOutputStream::ByteCount() const {
102*d57664e9SAndroid Build Coastguard Worker   return str_->size() + buffer_offset_;
103*d57664e9SAndroid Build Coastguard Worker }
104*d57664e9SAndroid Build Coastguard Worker 
Flush()105*d57664e9SAndroid Build Coastguard Worker void StringOutputStream::Flush() {
106*d57664e9SAndroid Build Coastguard Worker   if (buffer_offset_ != 0u) {
107*d57664e9SAndroid Build Coastguard Worker     FlushImpl();
108*d57664e9SAndroid Build Coastguard Worker   }
109*d57664e9SAndroid Build Coastguard Worker }
110*d57664e9SAndroid Build Coastguard Worker 
FlushImpl()111*d57664e9SAndroid Build Coastguard Worker void StringOutputStream::FlushImpl() {
112*d57664e9SAndroid Build Coastguard Worker   str_->append(buffer_.get(), buffer_offset_);
113*d57664e9SAndroid Build Coastguard Worker   buffer_offset_ = 0u;
114*d57664e9SAndroid Build Coastguard Worker }
115*d57664e9SAndroid Build Coastguard Worker 
116*d57664e9SAndroid Build Coastguard Worker }  // namespace io
117*d57664e9SAndroid Build Coastguard Worker }  // namespace aapt
118