Home | History | Annotate | Download | only in payload_consumer
      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 }  // namespace chromeos_update_engine
     77