/*
 *  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/rtc_base/file.h"

#include <io.h>
#include "webrtc/rtc_base/win32.h"

#include <limits>  // NOLINT: win32.h should be considered a system header

#include "webrtc/rtc_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
