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 "fxcrt_posix.h"
8 
9 #include "core/include/fxcrt/fx_basic.h"
10 
11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
12     _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
13     _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
FXCRT_FileAccess_Create()14 IFXCRT_FileAccess* FXCRT_FileAccess_Create() {
15   return new CFXCRT_FileAccess_Posix;
16 }
FXCRT_Posix_GetFileMode(FX_DWORD dwModes,int32_t & nFlags,int32_t & nMasks)17 void FXCRT_Posix_GetFileMode(FX_DWORD dwModes,
18                              int32_t& nFlags,
19                              int32_t& nMasks) {
20   nFlags = O_BINARY | O_LARGEFILE;
21   if (dwModes & FX_FILEMODE_ReadOnly) {
22     nFlags |= O_RDONLY;
23     nMasks = 0;
24   } else {
25     nFlags |= O_RDWR | O_CREAT;
26     if (dwModes & FX_FILEMODE_Truncate) {
27       nFlags |= O_TRUNC;
28     }
29     nMasks = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
30   }
31 }
CFXCRT_FileAccess_Posix()32 CFXCRT_FileAccess_Posix::CFXCRT_FileAccess_Posix() : m_nFD(-1) {}
~CFXCRT_FileAccess_Posix()33 CFXCRT_FileAccess_Posix::~CFXCRT_FileAccess_Posix() {
34   Close();
35 }
Open(const CFX_ByteStringC & fileName,FX_DWORD dwMode)36 FX_BOOL CFXCRT_FileAccess_Posix::Open(const CFX_ByteStringC& fileName,
37                                       FX_DWORD dwMode) {
38   if (m_nFD > -1) {
39     return FALSE;
40   }
41   int32_t nFlags, nMasks;
42   FXCRT_Posix_GetFileMode(dwMode, nFlags, nMasks);
43   m_nFD = open(fileName.GetCStr(), nFlags, nMasks);
44   return m_nFD > -1;
45 }
Open(const CFX_WideStringC & fileName,FX_DWORD dwMode)46 FX_BOOL CFXCRT_FileAccess_Posix::Open(const CFX_WideStringC& fileName,
47                                       FX_DWORD dwMode) {
48   return Open(FX_UTF8Encode(fileName), dwMode);
49 }
Close()50 void CFXCRT_FileAccess_Posix::Close() {
51   if (m_nFD < 0) {
52     return;
53   }
54   close(m_nFD);
55   m_nFD = -1;
56 }
Release()57 void CFXCRT_FileAccess_Posix::Release() {
58   delete this;
59 }
GetSize() const60 FX_FILESIZE CFXCRT_FileAccess_Posix::GetSize() const {
61   if (m_nFD < 0) {
62     return 0;
63   }
64   struct stat s;
65   FXSYS_memset(&s, 0, sizeof(s));
66   fstat(m_nFD, &s);
67   return s.st_size;
68 }
GetPosition() const69 FX_FILESIZE CFXCRT_FileAccess_Posix::GetPosition() const {
70   if (m_nFD < 0) {
71     return (FX_FILESIZE)-1;
72   }
73   return lseek(m_nFD, 0, SEEK_CUR);
74 }
SetPosition(FX_FILESIZE pos)75 FX_FILESIZE CFXCRT_FileAccess_Posix::SetPosition(FX_FILESIZE pos) {
76   if (m_nFD < 0) {
77     return (FX_FILESIZE)-1;
78   }
79   return lseek(m_nFD, pos, SEEK_SET);
80 }
Read(void * pBuffer,size_t szBuffer)81 size_t CFXCRT_FileAccess_Posix::Read(void* pBuffer, size_t szBuffer) {
82   if (m_nFD < 0) {
83     return 0;
84   }
85   return read(m_nFD, pBuffer, szBuffer);
86 }
Write(const void * pBuffer,size_t szBuffer)87 size_t CFXCRT_FileAccess_Posix::Write(const void* pBuffer, size_t szBuffer) {
88   if (m_nFD < 0) {
89     return 0;
90   }
91   return write(m_nFD, pBuffer, szBuffer);
92 }
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)93 size_t CFXCRT_FileAccess_Posix::ReadPos(void* pBuffer,
94                                         size_t szBuffer,
95                                         FX_FILESIZE pos) {
96   if (m_nFD < 0) {
97     return 0;
98   }
99   if (pos >= GetSize()) {
100     return 0;
101   }
102   if (SetPosition(pos) == (FX_FILESIZE)-1) {
103     return 0;
104   }
105   return Read(pBuffer, szBuffer);
106 }
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)107 size_t CFXCRT_FileAccess_Posix::WritePos(const void* pBuffer,
108                                          size_t szBuffer,
109                                          FX_FILESIZE pos) {
110   if (m_nFD < 0) {
111     return 0;
112   }
113   if (SetPosition(pos) == (FX_FILESIZE)-1) {
114     return 0;
115   }
116   return Write(pBuffer, szBuffer);
117 }
Flush()118 FX_BOOL CFXCRT_FileAccess_Posix::Flush() {
119   if (m_nFD < 0) {
120     return FALSE;
121   }
122   return fsync(m_nFD) > -1;
123 }
Truncate(FX_FILESIZE szFile)124 FX_BOOL CFXCRT_FileAccess_Posix::Truncate(FX_FILESIZE szFile) {
125   if (m_nFD < 0) {
126     return FALSE;
127   }
128   return !ftruncate(m_nFD, szFile);
129 }
130 #endif
131