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