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 25namespace { 26 27void 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 44std::unique_ptr<IFX_FileAccess> IFX_FileAccess::Create() { 45 return pdfium::MakeUnique<CFX_FileAccess_Posix>(); 46} 47 48CFX_FileAccess_Posix::CFX_FileAccess_Posix() : m_nFD(-1) {} 49 50CFX_FileAccess_Posix::~CFX_FileAccess_Posix() { 51 Close(); 52} 53 54bool 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 68bool CFX_FileAccess_Posix::Open(const WideStringView& fileName, 69 uint32_t dwMode) { 70 return Open(FX_UTF8Encode(fileName).AsStringView(), dwMode); 71} 72 73void CFX_FileAccess_Posix::Close() { 74 if (m_nFD < 0) { 75 return; 76 } 77 close(m_nFD); 78 m_nFD = -1; 79} 80FX_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} 89FX_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} 95FX_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} 101size_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} 107size_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} 113size_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} 127size_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 139bool CFX_FileAccess_Posix::Flush() { 140 if (m_nFD < 0) 141 return false; 142 143 return fsync(m_nFD) > -1; 144} 145 146bool 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