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