1 /* 2 * Copyright (C) 2009 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 "base/unix_file/string_file.h" 18 #include <errno.h> 19 #include <algorithm> 20 #include "base/logging.h" 21 22 namespace unix_file { 23 24 StringFile::StringFile() { 25 } 26 27 StringFile::~StringFile() { 28 } 29 30 int StringFile::Close() { 31 return 0; 32 } 33 34 int StringFile::Flush() { 35 return 0; 36 } 37 38 int64_t StringFile::Read(char *buf, int64_t byte_count, int64_t offset) const { 39 CHECK(buf); 40 CHECK_GE(byte_count, 0); 41 42 if (offset < 0) { 43 return -EINVAL; 44 } 45 46 const int64_t available_bytes = std::min(byte_count, GetLength() - offset); 47 if (available_bytes < 0) { 48 return 0; // Not an error, but nothing for us to do, either. 49 } 50 memcpy(buf, data_.data() + offset, available_bytes); 51 return available_bytes; 52 } 53 54 int StringFile::SetLength(int64_t new_length) { 55 if (new_length < 0) { 56 return -EINVAL; 57 } 58 data_.resize(new_length); 59 return 0; 60 } 61 62 int64_t StringFile::GetLength() const { 63 return data_.size(); 64 } 65 66 int64_t StringFile::Write(const char *buf, int64_t byte_count, int64_t offset) { 67 CHECK(buf); 68 CHECK_GE(byte_count, 0); 69 70 if (offset < 0) { 71 return -EINVAL; 72 } 73 74 if (byte_count == 0) { 75 return 0; 76 } 77 78 // FUSE seems happy to allow writes past the end. (I'd guess it doesn't 79 // synthesize a write of zero bytes so that we're free to implement sparse 80 // files.) GNU as(1) seems to require such writes. Those files are small. 81 const int64_t bytes_past_end = offset - GetLength(); 82 if (bytes_past_end > 0) { 83 data_.append(bytes_past_end, '\0'); 84 } 85 86 data_.replace(offset, byte_count, buf, byte_count); 87 return byte_count; 88 } 89 90 void StringFile::Assign(const art::StringPiece &new_data) { 91 data_.assign(new_data.data(), new_data.size()); 92 } 93 94 const art::StringPiece StringFile::ToStringPiece() const { 95 return data_; 96 } 97 98 } // namespace unix_file 99