1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2009 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker
17*5a923131SAndroid Build Coastguard Worker #include "update_engine/payload_consumer/extent_writer.h"
18*5a923131SAndroid Build Coastguard Worker
19*5a923131SAndroid Build Coastguard Worker #include <errno.h>
20*5a923131SAndroid Build Coastguard Worker #include <sys/types.h>
21*5a923131SAndroid Build Coastguard Worker #include <unistd.h>
22*5a923131SAndroid Build Coastguard Worker
23*5a923131SAndroid Build Coastguard Worker #include <algorithm>
24*5a923131SAndroid Build Coastguard Worker
25*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/utils.h"
26*5a923131SAndroid Build Coastguard Worker #include "update_engine/payload_consumer/payload_constants.h"
27*5a923131SAndroid Build Coastguard Worker
28*5a923131SAndroid Build Coastguard Worker using std::min;
29*5a923131SAndroid Build Coastguard Worker
30*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
31*5a923131SAndroid Build Coastguard Worker
Write(const void * bytes,size_t count)32*5a923131SAndroid Build Coastguard Worker bool DirectExtentWriter::Write(const void* bytes, size_t count) {
33*5a923131SAndroid Build Coastguard Worker if (count == 0)
34*5a923131SAndroid Build Coastguard Worker return true;
35*5a923131SAndroid Build Coastguard Worker const char* c_bytes = reinterpret_cast<const char*>(bytes);
36*5a923131SAndroid Build Coastguard Worker size_t bytes_written = 0;
37*5a923131SAndroid Build Coastguard Worker while (bytes_written < count) {
38*5a923131SAndroid Build Coastguard Worker TEST_AND_RETURN_FALSE(cur_extent_ != extents_.end());
39*5a923131SAndroid Build Coastguard Worker uint64_t bytes_remaining_cur_extent =
40*5a923131SAndroid Build Coastguard Worker cur_extent_->num_blocks() * block_size_ - extent_bytes_written_;
41*5a923131SAndroid Build Coastguard Worker CHECK_NE(bytes_remaining_cur_extent, static_cast<uint64_t>(0));
42*5a923131SAndroid Build Coastguard Worker size_t bytes_to_write =
43*5a923131SAndroid Build Coastguard Worker static_cast<size_t>(min(static_cast<uint64_t>(count - bytes_written),
44*5a923131SAndroid Build Coastguard Worker bytes_remaining_cur_extent));
45*5a923131SAndroid Build Coastguard Worker TEST_AND_RETURN_FALSE(bytes_to_write > 0);
46*5a923131SAndroid Build Coastguard Worker
47*5a923131SAndroid Build Coastguard Worker if (cur_extent_->start_block() != kSparseHole) {
48*5a923131SAndroid Build Coastguard Worker const off64_t offset =
49*5a923131SAndroid Build Coastguard Worker cur_extent_->start_block() * block_size_ + extent_bytes_written_;
50*5a923131SAndroid Build Coastguard Worker TEST_AND_RETURN_FALSE_ERRNO(fd_->Seek(offset, SEEK_SET) !=
51*5a923131SAndroid Build Coastguard Worker static_cast<off64_t>(-1));
52*5a923131SAndroid Build Coastguard Worker TEST_AND_RETURN_FALSE(
53*5a923131SAndroid Build Coastguard Worker utils::WriteAll(fd_, c_bytes + bytes_written, bytes_to_write));
54*5a923131SAndroid Build Coastguard Worker }
55*5a923131SAndroid Build Coastguard Worker bytes_written += bytes_to_write;
56*5a923131SAndroid Build Coastguard Worker extent_bytes_written_ += bytes_to_write;
57*5a923131SAndroid Build Coastguard Worker if (bytes_remaining_cur_extent == bytes_to_write) {
58*5a923131SAndroid Build Coastguard Worker // We filled this extent
59*5a923131SAndroid Build Coastguard Worker CHECK_EQ(extent_bytes_written_, cur_extent_->num_blocks() * block_size_);
60*5a923131SAndroid Build Coastguard Worker // move to next extent
61*5a923131SAndroid Build Coastguard Worker extent_bytes_written_ = 0;
62*5a923131SAndroid Build Coastguard Worker cur_extent_++;
63*5a923131SAndroid Build Coastguard Worker }
64*5a923131SAndroid Build Coastguard Worker }
65*5a923131SAndroid Build Coastguard Worker return true;
66*5a923131SAndroid Build Coastguard Worker }
67*5a923131SAndroid Build Coastguard Worker
68*5a923131SAndroid Build Coastguard Worker } // namespace chromeos_update_engine
69