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/include/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 }
Open(const CFX_ByteStringC & fileName,uint32_t dwMode)39 FX_BOOL CFXCRT_FileAccess_Posix::Open(const CFX_ByteStringC& fileName,
40                                       uint32_t dwMode) {
41   if (m_nFD > -1) {
42     return FALSE;
43   }
44   int32_t nFlags, nMasks;
45   FXCRT_Posix_GetFileMode(dwMode, nFlags, nMasks);
46   m_nFD = open(fileName.c_str(), nFlags, nMasks);
47   return m_nFD > -1;
48 }
Open(const CFX_WideStringC & fileName,uint32_t dwMode)49 FX_BOOL CFXCRT_FileAccess_Posix::Open(const CFX_WideStringC& fileName,
50                                       uint32_t dwMode) {
51   return Open(FX_UTF8Encode(fileName).AsStringC(), dwMode);
52 }
Close()53 void CFXCRT_FileAccess_Posix::Close() {
54   if (m_nFD < 0) {
55     return;
56   }
57   close(m_nFD);
58   m_nFD = -1;
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 
131 #endif
132