1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "../../include/fxcrt/fx_ext.h"
8#include "fxcrt_platforms.h"
9#if (_FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ && _FXM_PLATFORM_ != _FXM_PLATFORM_LINUX_ && _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ && _FXM_PLATFORM_ != _FXM_PLATFORM_ANDROID_)
10IFXCRT_FileAccess* FXCRT_FileAccess_Create(IFX_Allocator* pAllocator)
11{
12    if (pAllocator) {
13        return FX_NewAtAllocator(pAllocator) CFXCRT_FileAccess_CRT;
14    } else {
15        return FX_NEW CFXCRT_FileAccess_CRT;
16    }
17}
18void FXCRT_GetFileModeString(FX_DWORD dwModes, CFX_ByteString &bsMode)
19{
20    if (dwModes & FX_FILEMODE_ReadOnly) {
21        bsMode = FX_BSTRC("rb");
22    } else if (dwModes & FX_FILEMODE_Truncate) {
23        bsMode = FX_BSTRC("w+b");
24    } else {
25        bsMode = FX_BSTRC("a+b");
26    }
27}
28void FXCRT_GetFileModeString(FX_DWORD dwModes, CFX_WideString &wsMode)
29{
30    if (dwModes & FX_FILEMODE_ReadOnly) {
31        wsMode = FX_WSTRC(L"rb");
32    } else if (dwModes & FX_FILEMODE_Truncate) {
33        wsMode = FX_WSTRC(L"w+b");
34    } else {
35        wsMode = FX_WSTRC(L"a+b");
36    }
37}
38CFXCRT_FileAccess_CRT::CFXCRT_FileAccess_CRT()
39    : m_hFile(NULL)
40{
41}
42CFXCRT_FileAccess_CRT::~CFXCRT_FileAccess_CRT()
43{
44    Close();
45}
46FX_BOOL CFXCRT_FileAccess_CRT::Open(FX_BSTR fileName, FX_DWORD dwMode)
47{
48    if (m_hFile) {
49        return FALSE;
50    }
51    CFX_ByteString strMode;
52    FXCRT_GetFileModeString(dwMode, strMode);
53    m_hFile = FXSYS_fopen(fileName.GetCStr(), (FX_LPCSTR)strMode);
54    return m_hFile != NULL;
55}
56FX_BOOL CFXCRT_FileAccess_CRT::Open(FX_WSTR fileName, FX_DWORD dwMode)
57{
58    if (m_hFile) {
59        return FALSE;
60    }
61    CFX_WideString strMode;
62    FXCRT_GetFileModeString(dwMode, strMode);
63    m_hFile = FXSYS_wfopen(fileName.GetPtr(), (FX_LPCWSTR)strMode);
64    return m_hFile != NULL;
65}
66void CFXCRT_FileAccess_CRT::Close()
67{
68    if (!m_hFile) {
69        return;
70    }
71    FXSYS_fclose(m_hFile);
72    m_hFile = NULL;
73}
74void CFXCRT_FileAccess_CRT::Release(IFX_Allocator* pAllocator)
75{
76    if (pAllocator) {
77        FX_DeleteAtAllocator(this, pAllocator, CFXCRT_FileAccess_CRT);
78    } else {
79        delete this;
80    }
81}
82FX_FILESIZE CFXCRT_FileAccess_CRT::GetSize() const
83{
84    if (!m_hFile) {
85        return 0;
86    }
87    FX_FILESIZE pos = (FX_FILESIZE)FXSYS_ftell(m_hFile);
88    FXSYS_fseek(m_hFile, 0, FXSYS_SEEK_END);
89    FX_FILESIZE size = (FX_FILESIZE)FXSYS_ftell(m_hFile);
90    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
91    return size;
92}
93FX_FILESIZE CFXCRT_FileAccess_CRT::GetPosition() const
94{
95    if (!m_hFile) {
96        return (FX_FILESIZE) - 1;
97    }
98    return (FX_FILESIZE)FXSYS_ftell(m_hFile);
99}
100FX_FILESIZE CFXCRT_FileAccess_CRT::SetPosition(FX_FILESIZE pos)
101{
102    if (!m_hFile) {
103        return (FX_FILESIZE) - 1;
104    }
105    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
106    return (FX_FILESIZE)FXSYS_ftell(m_hFile);
107}
108size_t CFXCRT_FileAccess_CRT::Read(void* pBuffer, size_t szBuffer)
109{
110    if (!m_hFile) {
111        return 0;
112    }
113    return FXSYS_fread(pBuffer, 1, szBuffer, m_hFile);
114}
115size_t CFXCRT_FileAccess_CRT::Write(const void* pBuffer, size_t szBuffer)
116{
117    if (!m_hFile) {
118        return 0;
119    }
120    return FXSYS_fwrite(pBuffer, 1, szBuffer, m_hFile);
121}
122size_t CFXCRT_FileAccess_CRT::ReadPos(void* pBuffer, size_t szBuffer, FX_FILESIZE pos)
123{
124    if (!m_hFile) {
125        return (FX_FILESIZE) - 1;
126    }
127    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
128    return FXSYS_fread(pBuffer, 1, szBuffer, m_hFile);
129}
130size_t CFXCRT_FileAccess_CRT::WritePos(const void* pBuffer, size_t szBuffer, FX_FILESIZE pos)
131{
132    if (!m_hFile) {
133        return (FX_FILESIZE) - 1;
134    }
135    FXSYS_fseek(m_hFile, pos, FXSYS_SEEK_SET);
136    return FXSYS_fwrite(pBuffer, 1, szBuffer, m_hFile);
137}
138FX_BOOL CFXCRT_FileAccess_CRT::Flush()
139{
140    if (!m_hFile) {
141        return FALSE;
142    }
143    return !FXSYS_fflush(m_hFile);
144}
145FX_BOOL CFXCRT_FileAccess_CRT::Truncate(FX_FILESIZE szFile)
146{
147    return FALSE;
148}
149FX_BOOL FX_File_Exist(FX_BSTR fileName)
150{
151    return access(fileName.GetCStr(), F_OK) > -1;
152}
153FX_BOOL FX_File_Exist(FX_WSTR fileName)
154{
155    return FX_File_Exist(FX_UTF8Encode(fileName));
156}
157FX_BOOL FX_File_Delete(FX_BSTR fileName)
158{
159    return remove(fileName.GetCStr()) > -1;
160}
161FX_BOOL FX_File_Delete(FX_WSTR fileName)
162{
163    return FX_File_Delete(FX_UTF8Encode(fileName));
164}
165FX_BOOL FX_File_Copy(FX_BSTR fileNameSrc, FX_BSTR fileNameDst)
166{
167    CFXCRT_FileAccess_CRT src, dst;
168    if (!src.Open(fileNameSrc, FX_FILEMODE_ReadOnly)) {
169        return FALSE;
170    }
171    FX_FILESIZE size = src.GetSize();
172    if (!size) {
173        return FALSE;
174    }
175    if (!dst.Open(fileNameDst, FX_FILEMODE_Truncate)) {
176        return FALSE;
177    }
178    FX_FILESIZE num = 0;
179    FX_LPBYTE pBuffer = FX_Alloc(FX_BYTE, 32768);
180    if (!pBuffer) {
181        return FALSE;
182    }
183    while (num = src.Read(pBuffer, 32768)) {
184        if (dst.Write(pBuffer, num) != num) {
185            break;
186        }
187    }
188    FX_Free(pBuffer);
189    return TRUE;
190}
191FX_BOOL FX_File_Copy(FX_WSTR fileNameSrc, FX_WSTR fileNameDst)
192{
193    return FX_File_Copy(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
194}
195FX_BOOL FX_File_Move(FX_BSTR fileNameSrc, FX_BSTR fileNameDst)
196{
197    return rename(fileNameSrc.GetCStr(), fileNameDst.GetCStr());
198}
199FX_BOOL FX_File_Move(FX_WSTR fileNameSrc, FX_WSTR fileNameDst)
200{
201    return FX_File_Move(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
202}
203#endif
204