1 // 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 17 #include "update_engine/payload_consumer/fake_file_descriptor.h" 18 19 namespace chromeos_update_engine { 20 21 ssize_t FakeFileDescriptor::Read(void* buf, size_t count) { 22 // Record the read operation so it can later be inspected. 23 read_ops_.emplace_back(offset_, count); 24 25 // Check for the EOF condition first to avoid reporting it as a failure. 26 if (offset_ >= static_cast<uint64_t>(size_) || count == 0) 27 return 0; 28 // Find the first offset greater or equal than the current position where a 29 // failure will occur. This will mark the end of the read chunk. 30 uint64_t first_failure = size_; 31 for (const auto& failure : failure_ranges_) { 32 // A failure range that includes the current offset results in an 33 // immediate failure to read any bytes. 34 if (failure.first <= offset_ && offset_ < failure.first + failure.second) { 35 errno = EIO; 36 return -1; 37 } 38 if (failure.first > offset_) 39 first_failure = std::min(first_failure, failure.first); 40 } 41 count = std::min(static_cast<uint64_t>(count), first_failure - offset_); 42 static const char kHexChars[] = "0123456789ABCDEF"; 43 for (size_t i = 0; i < count; ++i) { 44 // Encode the 16-bit number "offset_ / 4" as a hex digit in big-endian. 45 uint16_t current_num = offset_ / 4; 46 uint8_t current_digit = (current_num >> (4 * (3 - offset_ % 4))) & 0x0f; 47 48 static_cast<uint8_t*>(buf)[i] = kHexChars[current_digit]; 49 offset_++; 50 } 51 52 return count; 53 } 54 55 off64_t FakeFileDescriptor::Seek(off64_t offset, int whence) { 56 switch (whence) { 57 case SEEK_SET: 58 offset_ = offset; 59 break; 60 case SEEK_CUR: 61 offset_ += offset; 62 break; 63 case SEEK_END: 64 if (offset > size_) 65 offset_ = 0; 66 else 67 offset_ = size_ - offset_; 68 break; 69 default: 70 errno = EINVAL; 71 return -1; 72 } 73 return offset_; 74 } 75 76 brillo::Blob FakeFileDescriptorData(size_t size) { 77 brillo::Blob ret(size); 78 FakeFileDescriptor fd; 79 fd.SetFileSize(size); 80 fd.Read(ret.data(), size); 81 return ret; 82 } 83 84 } // namespace chromeos_update_engine 85