// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcrt/fxcrt_windows.h"

#include "core/fxcrt/include/fx_string.h"

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
IFXCRT_FileAccess* FXCRT_FileAccess_Create() {
  return new CFXCRT_FileAccess_Win64;
}
void FXCRT_Windows_GetFileMode(uint32_t dwMode,
                               uint32_t& dwAccess,
                               uint32_t& dwShare,
                               uint32_t& dwCreation) {
  dwAccess = GENERIC_READ;
  dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
  if (!(dwMode & FX_FILEMODE_ReadOnly)) {
    dwAccess |= GENERIC_WRITE;
    dwCreation = (dwMode & FX_FILEMODE_Truncate) ? CREATE_ALWAYS : OPEN_ALWAYS;
  } else {
    dwCreation = OPEN_EXISTING;
  }
}
#ifdef __cplusplus
extern "C" {
#endif
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
WINBASEAPI BOOL WINAPI SetFilePointerEx(HANDLE hFile,
                                        LARGE_INTEGER liDistanceToMove,
                                        PLARGE_INTEGER lpNewFilePointer,
                                        DWORD dwMoveMethod);
#ifdef __cplusplus
}
#endif
CFXCRT_FileAccess_Win64::CFXCRT_FileAccess_Win64() : m_hFile(NULL) {}
CFXCRT_FileAccess_Win64::~CFXCRT_FileAccess_Win64() {
  Close();
}
FX_BOOL CFXCRT_FileAccess_Win64::Open(const CFX_ByteStringC& fileName,
                                      uint32_t dwMode) {
  if (m_hFile) {
    return FALSE;
  }
  uint32_t dwAccess, dwShare, dwCreation;
  FXCRT_Windows_GetFileMode(dwMode, dwAccess, dwShare, dwCreation);
  m_hFile = ::CreateFileA(fileName.c_str(), dwAccess, dwShare, NULL, dwCreation,
                          FILE_ATTRIBUTE_NORMAL, NULL);
  if (m_hFile == INVALID_HANDLE_VALUE) {
    m_hFile = NULL;
  }
  return m_hFile != NULL;
}
FX_BOOL CFXCRT_FileAccess_Win64::Open(const CFX_WideStringC& fileName,
                                      uint32_t dwMode) {
  if (m_hFile) {
    return FALSE;
  }
  uint32_t dwAccess, dwShare, dwCreation;
  FXCRT_Windows_GetFileMode(dwMode, dwAccess, dwShare, dwCreation);
  m_hFile = ::CreateFileW((LPCWSTR)fileName.raw_str(), dwAccess, dwShare, NULL,
                          dwCreation, FILE_ATTRIBUTE_NORMAL, NULL);
  if (m_hFile == INVALID_HANDLE_VALUE) {
    m_hFile = NULL;
  }
  return m_hFile != NULL;
}
void CFXCRT_FileAccess_Win64::Close() {
  if (!m_hFile) {
    return;
  }
  ::CloseHandle(m_hFile);
  m_hFile = NULL;
}
void CFXCRT_FileAccess_Win64::Release() {
  delete this;
}
FX_FILESIZE CFXCRT_FileAccess_Win64::GetSize() const {
  if (!m_hFile) {
    return 0;
  }
  LARGE_INTEGER size = {};
  if (!::GetFileSizeEx(m_hFile, &size)) {
    return 0;
  }
  return (FX_FILESIZE)size.QuadPart;
}
FX_FILESIZE CFXCRT_FileAccess_Win64::GetPosition() const {
  if (!m_hFile) {
    return (FX_FILESIZE)-1;
  }
  LARGE_INTEGER dist = {};
  LARGE_INTEGER newPos = {};
  if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT)) {
    return (FX_FILESIZE)-1;
  }
  return (FX_FILESIZE)newPos.QuadPart;
}
FX_FILESIZE CFXCRT_FileAccess_Win64::SetPosition(FX_FILESIZE pos) {
  if (!m_hFile) {
    return (FX_FILESIZE)-1;
  }
  LARGE_INTEGER dist;
  dist.QuadPart = pos;
  LARGE_INTEGER newPos = {};
  if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN)) {
    return (FX_FILESIZE)-1;
  }
  return (FX_FILESIZE)newPos.QuadPart;
}
size_t CFXCRT_FileAccess_Win64::Read(void* pBuffer, size_t szBuffer) {
  if (!m_hFile) {
    return 0;
  }
  size_t szRead = 0;
  if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead, NULL)) {
    return 0;
  }
  return szRead;
}
size_t CFXCRT_FileAccess_Win64::Write(const void* pBuffer, size_t szBuffer) {
  if (!m_hFile) {
    return 0;
  }
  size_t szWrite = 0;
  if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite,
                   NULL)) {
    return 0;
  }
  return szWrite;
}
size_t CFXCRT_FileAccess_Win64::ReadPos(void* pBuffer,
                                        size_t szBuffer,
                                        FX_FILESIZE pos) {
  if (!m_hFile) {
    return 0;
  }
  if (pos >= GetSize()) {
    return 0;
  }
  if (SetPosition(pos) == (FX_FILESIZE)-1) {
    return 0;
  }
  return Read(pBuffer, szBuffer);
}
size_t CFXCRT_FileAccess_Win64::WritePos(const void* pBuffer,
                                         size_t szBuffer,
                                         FX_FILESIZE pos) {
  if (!m_hFile) {
    return 0;
  }
  if (SetPosition(pos) == (FX_FILESIZE)-1) {
    return 0;
  }
  return Write(pBuffer, szBuffer);
}
FX_BOOL CFXCRT_FileAccess_Win64::Flush() {
  if (!m_hFile) {
    return FALSE;
  }
  return ::FlushFileBuffers(m_hFile);
}
FX_BOOL CFXCRT_FileAccess_Win64::Truncate(FX_FILESIZE szFile) {
  if (SetPosition(szFile) == (FX_FILESIZE)-1) {
    return FALSE;
  }
  return ::SetEndOfFile(m_hFile);
}
#endif
