// 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 "../../include/fxcrt/fx_ext.h"
#include "fxcrt_platforms.h"
#if (_FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ && _FXM_PLATFORM_ != _FXM_PLATFORM_LINUX_ && _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ && _FXM_PLATFORM_ != _FXM_PLATFORM_ANDROID_)
IFXCRT_FileAccess* FXCRT_FileAccess_Create(IFX_Allocator* pAllocator)
{
    if (pAllocator) {
        return FX_NewAtAllocator(pAllocator) CFXCRT_FileAccess_CRT;
    } else {
        return FX_NEW CFXCRT_FileAccess_CRT;
    }
}
void FXCRT_GetFileModeString(FX_DWORD dwModes, CFX_ByteString &bsMode)
{
    if (dwModes & FX_FILEMODE_ReadOnly) {
        bsMode = FX_BSTRC("rb");
    } else if (dwModes & FX_FILEMODE_Truncate) {
        bsMode = FX_BSTRC("w+b");
    } else {
        bsMode = FX_BSTRC("a+b");
    }
}
void FXCRT_GetFileModeString(FX_DWORD dwModes, CFX_WideString &wsMode)
{
    if (dwModes & FX_FILEMODE_ReadOnly) {
        wsMode = FX_WSTRC(L"rb");
    } else if (dwModes & FX_FILEMODE_Truncate) {
        wsMode = FX_WSTRC(L"w+b");
    } else {
        wsMode = FX_WSTRC(L"a+b");
    }
}
CFXCRT_FileAccess_CRT::CFXCRT_FileAccess_CRT()
    : m_hFile(NULL)
{
}
CFXCRT_FileAccess_CRT::~CFXCRT_FileAccess_CRT()
{
    Close();
}
FX_BOOL CFXCRT_FileAccess_CRT::Open(FX_BSTR fileName, FX_DWORD dwMode)
{
    if (m_hFile) {
        return FALSE;
    }
    CFX_ByteString strMode;
    FXCRT_GetFileModeString(dwMode, strMode);
    m_hFile = FXSYS_fopen(fileName.GetCStr(), (FX_LPCSTR)strMode);
    return m_hFile != NULL;
}
FX_BOOL CFXCRT_FileAccess_CRT::Open(FX_WSTR fileName, FX_DWORD dwMode)
{
    if (m_hFile) {
        return FALSE;
    }
    CFX_WideString strMode;
    FXCRT_GetFileModeString(dwMode, strMode);
    m_hFile = FXSYS_wfopen(fileName.GetPtr(), (FX_LPCWSTR)strMode);
    return m_hFile != NULL;
}
void CFXCRT_FileAccess_CRT::Close()
{
    if (!m_hFile) {
        return;
    }
    FXSYS_fclose(m_hFile);
    m_hFile = NULL;
}
void CFXCRT_FileAccess_CRT::Release(IFX_Allocator* pAllocator)
{
    if (pAllocator) {
        FX_DeleteAtAllocator(this, pAllocator, CFXCRT_FileAccess_CRT);
    } else {
        delete this;
    }
}
FX_FILESIZE CFXCRT_FileAccess_CRT::GetSize() const
{
    if (!m_hFile) {
        return 0;
    }
    FX_FILESIZE pos = (FX_FILESIZE)FXSYS_ftell(m_hFile);
    FXSYS_fseek(m_hFile, 0, FXSYS_SEEK_END);
    FX_FILESIZE size = (FX_FILESIZE)FXSYS_ftell(m_hFile);
    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
    return size;
}
FX_FILESIZE CFXCRT_FileAccess_CRT::GetPosition() const
{
    if (!m_hFile) {
        return (FX_FILESIZE) - 1;
    }
    return (FX_FILESIZE)FXSYS_ftell(m_hFile);
}
FX_FILESIZE CFXCRT_FileAccess_CRT::SetPosition(FX_FILESIZE pos)
{
    if (!m_hFile) {
        return (FX_FILESIZE) - 1;
    }
    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
    return (FX_FILESIZE)FXSYS_ftell(m_hFile);
}
size_t CFXCRT_FileAccess_CRT::Read(void* pBuffer, size_t szBuffer)
{
    if (!m_hFile) {
        return 0;
    }
    return FXSYS_fread(pBuffer, 1, szBuffer, m_hFile);
}
size_t CFXCRT_FileAccess_CRT::Write(const void* pBuffer, size_t szBuffer)
{
    if (!m_hFile) {
        return 0;
    }
    return FXSYS_fwrite(pBuffer, 1, szBuffer, m_hFile);
}
size_t CFXCRT_FileAccess_CRT::ReadPos(void* pBuffer, size_t szBuffer, FX_FILESIZE pos)
{
    if (!m_hFile) {
        return (FX_FILESIZE) - 1;
    }
    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
    return FXSYS_fread(pBuffer, 1, szBuffer, m_hFile);
}
size_t CFXCRT_FileAccess_CRT::WritePos(const void* pBuffer, size_t szBuffer, FX_FILESIZE pos)
{
    if (!m_hFile) {
        return (FX_FILESIZE) - 1;
    }
    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
    return FXSYS_fwrite(pBuffer, 1, szBuffer, m_hFile);
}
FX_BOOL CFXCRT_FileAccess_CRT::Flush()
{
    if (!m_hFile) {
        return FALSE;
    }
    return !FXSYS_fflush(m_hFile);
}
FX_BOOL CFXCRT_FileAccess_CRT::Truncate(FX_FILESIZE szFile)
{
    return FALSE;
}
FX_BOOL FX_File_Exist(FX_BSTR fileName)
{
    return access(fileName.GetCStr(), F_OK) > -1;
}
FX_BOOL FX_File_Exist(FX_WSTR fileName)
{
    return FX_File_Exist(FX_UTF8Encode(fileName));
}
FX_BOOL FX_File_Delete(FX_BSTR fileName)
{
    return remove(fileName.GetCStr()) > -1;
}
FX_BOOL FX_File_Delete(FX_WSTR fileName)
{
    return FX_File_Delete(FX_UTF8Encode(fileName));
}
FX_BOOL FX_File_Copy(FX_BSTR fileNameSrc, FX_BSTR fileNameDst)
{
    CFXCRT_FileAccess_CRT src, dst;
    if (!src.Open(fileNameSrc, FX_FILEMODE_ReadOnly)) {
        return FALSE;
    }
    FX_FILESIZE size = src.GetSize();
    if (!size) {
        return FALSE;
    }
    if (!dst.Open(fileNameDst, FX_FILEMODE_Truncate)) {
        return FALSE;
    }
    FX_FILESIZE num = 0;
    FX_LPBYTE pBuffer = FX_Alloc(FX_BYTE, 32768);
    if (!pBuffer) {
        return FALSE;
    }
    while (num = src.Read(pBuffer, 32768)) {
        if (dst.Write(pBuffer, num) != num) {
            break;
        }
    }
    FX_Free(pBuffer);
    return TRUE;
}
FX_BOOL FX_File_Copy(FX_WSTR fileNameSrc, FX_WSTR fileNameDst)
{
    return FX_File_Copy(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
}
FX_BOOL FX_File_Move(FX_BSTR fileNameSrc, FX_BSTR fileNameDst)
{
    return rename(fileNameSrc.GetCStr(), fileNameDst.GetCStr());
}
FX_BOOL FX_File_Move(FX_WSTR fileNameSrc, FX_WSTR fileNameDst)
{
    return FX_File_Move(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
}
#endif
