|  | /* | 
|  | *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #include "webrtc/base/file.h" | 
|  |  | 
|  | #include <io.h> | 
|  | #include "webrtc/base/win32.h" | 
|  |  | 
|  | #include <limits>  // NOLINT: win32.h should be considered a system header | 
|  |  | 
|  | #include "webrtc/base/checks.h" | 
|  |  | 
|  | namespace rtc { | 
|  |  | 
|  | size_t File::Write(const uint8_t* data, size_t length) { | 
|  | RTC_DCHECK_LT(length, std::numeric_limits<DWORD>::max()); | 
|  | size_t total_written = 0; | 
|  | do { | 
|  | DWORD written; | 
|  | if (!::WriteFile(file_, data + total_written, | 
|  | static_cast<DWORD>(length - total_written), &written, | 
|  | nullptr)) { | 
|  | break; | 
|  | } | 
|  | total_written += written; | 
|  | } while (total_written < length); | 
|  | return total_written; | 
|  | } | 
|  |  | 
|  | size_t File::Read(uint8_t* buffer, size_t length) { | 
|  | RTC_DCHECK_LT(length, std::numeric_limits<DWORD>::max()); | 
|  | size_t total_read = 0; | 
|  | do { | 
|  | DWORD read; | 
|  | if (!::ReadFile(file_, buffer + total_read, | 
|  | static_cast<DWORD>(length - total_read), &read, nullptr)) { | 
|  | break; | 
|  | } | 
|  | total_read += read; | 
|  | } while (total_read < length); | 
|  | return total_read; | 
|  | } | 
|  |  | 
|  | size_t File::WriteAt(const uint8_t* data, size_t length, size_t offset) { | 
|  | RTC_DCHECK_LT(length, std::numeric_limits<DWORD>::max()); | 
|  | size_t total_written = 0; | 
|  | do { | 
|  | DWORD written; | 
|  |  | 
|  | LARGE_INTEGER offset_li; | 
|  | offset_li.QuadPart = offset + total_written; | 
|  |  | 
|  | OVERLAPPED overlapped = {0}; | 
|  | overlapped.Offset = offset_li.LowPart; | 
|  | overlapped.OffsetHigh = offset_li.HighPart; | 
|  |  | 
|  | if (!::WriteFile(file_, data + total_written, | 
|  | static_cast<DWORD>(length - total_written), &written, | 
|  | &overlapped)) { | 
|  | break; | 
|  | } | 
|  |  | 
|  | total_written += written; | 
|  | } while (total_written < length); | 
|  | return total_written; | 
|  | } | 
|  |  | 
|  | size_t File::ReadAt(uint8_t* buffer, size_t length, size_t offset) { | 
|  | RTC_DCHECK_LT(length, std::numeric_limits<DWORD>::max()); | 
|  | size_t total_read = 0; | 
|  | do { | 
|  | DWORD read; | 
|  |  | 
|  | LARGE_INTEGER offset_li; | 
|  | offset_li.QuadPart = offset + total_read; | 
|  |  | 
|  | OVERLAPPED overlapped = {0}; | 
|  | overlapped.Offset = offset_li.LowPart; | 
|  | overlapped.OffsetHigh = offset_li.HighPart; | 
|  |  | 
|  | if (!::ReadFile(file_, buffer + total_read, | 
|  | static_cast<DWORD>(length - total_read), &read, | 
|  | &overlapped)) { | 
|  | break; | 
|  | } | 
|  |  | 
|  | total_read += read; | 
|  | } while (total_read < length); | 
|  | return total_read; | 
|  | } | 
|  |  | 
|  | bool File::Seek(size_t offset) { | 
|  | LARGE_INTEGER distance; | 
|  | distance.QuadPart = offset; | 
|  | return SetFilePointerEx(file_, distance, nullptr, FILE_BEGIN) != 0; | 
|  | } | 
|  |  | 
|  | bool File::Close() { | 
|  | if (file_ == kInvalidPlatformFileValue) | 
|  | return false; | 
|  | bool ret = CloseHandle(file_) != 0; | 
|  | file_ = kInvalidPlatformFileValue; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | }  // namespace rtc |