1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/paint_preview/common/file_stream.h"
#include <stdint.h>
#include <utility>
#include "base/compiler_specific.h"
namespace paint_preview {
namespace {
bool ShouldWrite(size_t current_size, size_t max_size, size_t added_size) {
// If |current_size| + |added_size| overflow then don't write.
if (std::numeric_limits<size_t>::max() - current_size < added_size)
return false;
return max_size >= current_size + added_size;
}
} // namespace
// FileWStream
FileWStream::FileWStream(base::File file)
: file_(std::move(file)),
max_size_(0),
bytes_written_(0),
fake_bytes_written_(0),
has_write_failed_(false) {
DCHECK(file_.IsValid());
}
FileWStream::FileWStream(base::File file, size_t max_size)
: file_(std::move(file)),
max_size_(max_size),
bytes_written_(0),
fake_bytes_written_(0),
has_write_failed_(false) {
DCHECK(file_.IsValid());
}
// Close() is called in the destructor of |file_|.
FileWStream::~FileWStream() = default;
bool FileWStream::write(const void* buffer, size_t size) {
fake_bytes_written_ += size;
if (!file_.IsValid() || has_write_failed_)
return false;
if (max_size_ && !ShouldWrite(bytes_written_, max_size_, size)) {
has_write_failed_ = true;
return false;
}
int bytes = UNSAFE_TODO(
file_.WriteAtCurrentPos(reinterpret_cast<const char*>(buffer), size));
if (bytes < 0) {
has_write_failed_ = true;
return false;
}
bytes_written_ += bytes;
if (static_cast<size_t>(bytes) != size) {
has_write_failed_ = true;
return false;
}
return true;
}
void FileWStream::flush() {
if (!file_.IsValid())
return;
file_.Flush();
}
size_t FileWStream::bytesWritten() const {
return fake_bytes_written_;
}
void FileWStream::Close() {
if (!file_.IsValid())
return;
file_.Close();
}
// FileRStream
FileRStream::FileRStream(base::File file)
: file_(std::move(file)), length_(file_.GetLength()), bytes_read_(0) {
DCHECK(file_.IsValid());
}
FileRStream::~FileRStream() = default;
size_t FileRStream::read(void* buffer, size_t size) {
if (!file_.IsValid())
return 0;
int64_t num_bytes;
if (!buffer) {
int64_t origin = file_.Seek(base::File::FROM_CURRENT, 0);
if (origin < 0)
return 0;
num_bytes = file_.Seek(base::File::FROM_CURRENT, size);
if (num_bytes < 0)
return 0;
num_bytes = num_bytes - origin;
} else {
num_bytes = UNSAFE_TODO(
file_.ReadAtCurrentPos(reinterpret_cast<char*>(buffer), size));
}
if (num_bytes < 0)
return 0;
bytes_read_ += num_bytes;
return num_bytes;
}
bool FileRStream::isAtEnd() const {
return bytes_read_ == length_;
}
bool FileRStream::hasLength() const {
return true;
}
size_t FileRStream::getLength() const {
return length_;
}
} // namespace paint_preview
|