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