// 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.GetCStr(), 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.GetPtr(), 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
