• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/cfx_fileaccess_posix.h"
8 
9 #include <memory>
10 
11 #include "third_party/base/ptr_util.h"
12 
13 #ifndef O_BINARY
14 #define O_BINARY 0
15 #endif  // O_BINARY
16 
17 #ifndef O_LARGEFILE
18 #define O_LARGEFILE 0
19 #endif  // O_LARGEFILE
20 
21 #if _FX_PLATFORM_ == _FX_PLATFORM_LINUX_ || \
22     _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ || \
23     _FX_PLATFORM_ == _FX_PLATFORM_ANDROID_
24 
25 namespace {
26 
GetFileMode(uint32_t dwModes,int32_t & nFlags,int32_t & nMasks)27 void GetFileMode(uint32_t dwModes, int32_t& nFlags, int32_t& nMasks) {
28   nFlags = O_BINARY | O_LARGEFILE;
29   if (dwModes & FX_FILEMODE_ReadOnly) {
30     nFlags |= O_RDONLY;
31     nMasks = 0;
32   } else {
33     nFlags |= O_RDWR | O_CREAT;
34     if (dwModes & FX_FILEMODE_Truncate) {
35       nFlags |= O_TRUNC;
36     }
37     nMasks = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
38   }
39 }
40 
41 }  // namespace
42 
43 // static
Create()44 std::unique_ptr<IFX_FileAccess> IFX_FileAccess::Create() {
45   return pdfium::MakeUnique<CFX_FileAccess_Posix>();
46 }
47 
CFX_FileAccess_Posix()48 CFX_FileAccess_Posix::CFX_FileAccess_Posix() : m_nFD(-1) {}
49 
~CFX_FileAccess_Posix()50 CFX_FileAccess_Posix::~CFX_FileAccess_Posix() {
51   Close();
52 }
53 
Open(const ByteStringView & fileName,uint32_t dwMode)54 bool CFX_FileAccess_Posix::Open(const ByteStringView& fileName,
55                                 uint32_t dwMode) {
56   if (m_nFD > -1)
57     return false;
58 
59   int32_t nFlags;
60   int32_t nMasks;
61   GetFileMode(dwMode, nFlags, nMasks);
62 
63   // TODO(tsepez): check usage of c_str() below.
64   m_nFD = open(fileName.unterminated_c_str(), nFlags, nMasks);
65   return m_nFD > -1;
66 }
67 
Open(const WideStringView & fileName,uint32_t dwMode)68 bool CFX_FileAccess_Posix::Open(const WideStringView& fileName,
69                                 uint32_t dwMode) {
70   return Open(FX_UTF8Encode(fileName).AsStringView(), dwMode);
71 }
72 
Close()73 void CFX_FileAccess_Posix::Close() {
74   if (m_nFD < 0) {
75     return;
76   }
77   close(m_nFD);
78   m_nFD = -1;
79 }
GetSize() const80 FX_FILESIZE CFX_FileAccess_Posix::GetSize() const {
81   if (m_nFD < 0) {
82     return 0;
83   }
84   struct stat s;
85   memset(&s, 0, sizeof(s));
86   fstat(m_nFD, &s);
87   return s.st_size;
88 }
GetPosition() const89 FX_FILESIZE CFX_FileAccess_Posix::GetPosition() const {
90   if (m_nFD < 0) {
91     return (FX_FILESIZE)-1;
92   }
93   return lseek(m_nFD, 0, SEEK_CUR);
94 }
SetPosition(FX_FILESIZE pos)95 FX_FILESIZE CFX_FileAccess_Posix::SetPosition(FX_FILESIZE pos) {
96   if (m_nFD < 0) {
97     return (FX_FILESIZE)-1;
98   }
99   return lseek(m_nFD, pos, SEEK_SET);
100 }
Read(void * pBuffer,size_t szBuffer)101 size_t CFX_FileAccess_Posix::Read(void* pBuffer, size_t szBuffer) {
102   if (m_nFD < 0) {
103     return 0;
104   }
105   return read(m_nFD, pBuffer, szBuffer);
106 }
Write(const void * pBuffer,size_t szBuffer)107 size_t CFX_FileAccess_Posix::Write(const void* pBuffer, size_t szBuffer) {
108   if (m_nFD < 0) {
109     return 0;
110   }
111   return write(m_nFD, pBuffer, szBuffer);
112 }
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)113 size_t CFX_FileAccess_Posix::ReadPos(void* pBuffer,
114                                      size_t szBuffer,
115                                      FX_FILESIZE pos) {
116   if (m_nFD < 0) {
117     return 0;
118   }
119   if (pos >= GetSize()) {
120     return 0;
121   }
122   if (SetPosition(pos) == (FX_FILESIZE)-1) {
123     return 0;
124   }
125   return Read(pBuffer, szBuffer);
126 }
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)127 size_t CFX_FileAccess_Posix::WritePos(const void* pBuffer,
128                                       size_t szBuffer,
129                                       FX_FILESIZE pos) {
130   if (m_nFD < 0) {
131     return 0;
132   }
133   if (SetPosition(pos) == (FX_FILESIZE)-1) {
134     return 0;
135   }
136   return Write(pBuffer, szBuffer);
137 }
138 
Flush()139 bool CFX_FileAccess_Posix::Flush() {
140   if (m_nFD < 0)
141     return false;
142 
143   return fsync(m_nFD) > -1;
144 }
145 
Truncate(FX_FILESIZE szFile)146 bool CFX_FileAccess_Posix::Truncate(FX_FILESIZE szFile) {
147   if (m_nFD < 0)
148     return false;
149 
150   return !ftruncate(m_nFD, szFile);
151 }
152 
153 #endif
154