/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #if defined(_WIN32) # include # include #endif #ifdef UNX # include # include #endif #include #ifdef SAL_UNX #define SEPARATOR '/' #else #define SEPARATOR '\\' #endif using namespace ::osl; OString getTempDir(const OString& sFileName) { sal_Int32 index = 0; #ifdef SAL_UNX if ((index=sFileName.lastIndexOf('/')) > 0) return sFileName.copy(0, index); #else if ((index=sFileName.lastIndexOf('\\')) > 0) return sFileName.copy(0, index); #endif return "."_ostr; } OString createFileNameFromType( const OString& destination, const OString& typeName, const OString& postfix ) { OString type(typeName.replace('.', '/')); sal_Int32 length = destination.getLength(); bool bWithPoint = false; if (length == 0) { length++; bWithPoint = true; } length += type.getLength() + postfix.getLength(); bool bWithSeparator = false; if (!(destination.endsWith("\\") || destination.endsWith("/")) && !(type.startsWith("\\") || type.startsWith("/"))) { length++; bWithSeparator = true; } OStringBuffer fileNameBuf(length); if (bWithPoint) fileNameBuf.append('.'); else fileNameBuf.append(destination); if (bWithSeparator) fileNameBuf.append("/"); fileNameBuf.append(type + postfix); OString fileName(fileNameBuf.makeStringAndClear()); char token; #ifdef SAL_UNX fileName = fileName.replace('\\', '/'); token = '/'; #else fileName = fileName.replace('/', '\\'); token = '\\'; #endif OStringBuffer buffer(length); sal_Int32 nIndex = 0; do { buffer.append(o3tl::getToken(fileName, 0, token, nIndex)); if( nIndex == -1 ) break; if (buffer.isEmpty() || std::string_view(".") == buffer) { buffer.append(token); continue; } #if defined(SAL_UNX) if (mkdir(buffer.getStr(), 0777) == -1) #else if (mkdir(buffer.getStr()) == -1) #endif { if ( errno == ENOENT ) return OString(); } buffer.append(token); } while(true); OUString uSysFileName; OSL_VERIFY( FileBase::getSystemPathFromFileURL( convertToFileUrl(fileName), uSysFileName) == FileBase::E_None ); return OUStringToOString(uSysFileName, osl_getThreadTextEncoding()); } bool fileExists(const OString& fileName) { FILE *f= fopen(fileName.getStr(), "r"); if (f != nullptr) { fclose(f); return true; } return false; } static bool checkFileContent(const OString& targetFileName, const OString& tmpFileName) { FILE *target = fopen(targetFileName.getStr(), "r"); FILE *tmp = fopen(tmpFileName.getStr(), "r"); bool bFindChanges = false; if (target != nullptr && tmp != nullptr) { char buffer1[1024+1]; char buffer2[1024+1]; sal_Int32 n1 = 0; sal_Int32 n2 = 0; while ( !bFindChanges && !feof(target) && !feof(tmp)) { n1 = fread(buffer1, sizeof(char), 1024, target); n2 = fread(buffer2, sizeof(char), 1024, tmp); if ( n1 != n2 ) bFindChanges = true; else if ( memcmp(buffer1, buffer2, n2) != 0 ) bFindChanges = true; } } if (target) fclose(target); if (tmp) fclose(tmp); return bFindChanges; } bool makeValidTypeFile(const OString& targetFileName, const OString& tmpFileName, bool bFileCheck) { if (bFileCheck) { if (checkFileContent(targetFileName, tmpFileName)) { if ( !unlink(targetFileName.getStr()) ) if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) ) return true; } else return removeTypeFile(tmpFileName); } else { if (fileExists(targetFileName)) if (!removeTypeFile(targetFileName)) return false; if ( rename(tmpFileName.getStr(), targetFileName.getStr()) ) { if (errno == EEXIST) return true; } else return true; } return false; } bool removeTypeFile(const OString& fileName) { return unlink(fileName.getStr()) == 0; } OUString convertToFileUrl(const OString& fileName) { if ( fileName.startsWith("file://") ) { return OStringToOUString(fileName, osl_getThreadTextEncoding()); } OUString uUrlFileName; OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 ) { OUString uWorkingDir; if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) { OSL_ASSERT(false); } if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) != FileBase::E_None) { OSL_ASSERT(false); } } else { if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) != FileBase::E_None) { OSL_ASSERT(false); } } return uUrlFileName; } // FileStream FileStream::FileStream() : m_file(nullptr) { } FileStream::~FileStream() { if ( isValid() ) osl_closeFile(m_file); } bool FileStream::isValid() const { return m_file != nullptr; } void FileStream::createTempFile(const OString& sPath) { OString sTmp("."_ostr); OUString sTmpPath; OUString sTmpName; if (!sPath.isEmpty()) sTmp = sPath; sTmpPath = convertToFileUrl(sTmp); if (osl_createTempFile(sTmpPath.pData, &m_file, &sTmpName.pData) == osl_File_E_None) { #ifdef SAL_UNX sal_uInt64 const uAttr = osl_File_Attribute_OwnWrite | osl_File_Attribute_OwnRead | osl_File_Attribute_GrpWrite | osl_File_Attribute_GrpRead | osl_File_Attribute_OthRead; if (osl_setFileAttributes(sTmpName.pData, uAttr) != osl_File_E_None) { m_file = nullptr; return; } #endif OUString sSysTmpName; FileBase::getSystemPathFromFileURL(sTmpName, sSysTmpName); m_name = OUStringToOString(sSysTmpName, osl_getThreadTextEncoding()); } else m_file = nullptr; } void FileStream::close() { if ( isValid() ) { osl_closeFile(m_file); m_file = nullptr; m_name.clear(); } } bool FileStream::write(void const * buffer, sal_uInt64 size) { while (size > 0) { sal_uInt64 written; if (osl_writeFile(m_file, buffer, size, &written) != osl_File_E_None) { return false; } OSL_ASSERT(written <= size); size -= written; buffer = static_cast< char const * >(buffer) + written; } return true; } FileStream &operator<<(FileStream& o, sal_uInt32 i) { sal_uInt64 writtenBytes; OString s = OString::number(static_cast(i)); osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(char), &writtenBytes); return o; } FileStream &operator<<(FileStream& o, char const * s) { sal_uInt64 writtenBytes; osl_writeFile(o.m_file, s, strlen(s), &writtenBytes); return o; } FileStream &operator<<(FileStream& o, OString const * s) { sal_uInt64 writtenBytes; osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(char), &writtenBytes); return o; } FileStream &operator<<(FileStream& o, const OString& s) { sal_uInt64 writtenBytes; osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(char), &writtenBytes); return o; } FileStream &operator<<(FileStream& o, OStringBuffer const * s) { sal_uInt64 writtenBytes; osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(char), &writtenBytes); return o; } FileStream &operator<<(FileStream& o, const OStringBuffer& s) { sal_uInt64 writtenBytes; osl_writeFile( o.m_file, s.getStr(), s.getLength() * sizeof(char), &writtenBytes); return o; } FileStream & operator <<(FileStream & out, std::u16string_view s) { return out << OUStringToOString(s, RTL_TEXTENCODING_UTF8); } CannotDumpException::~CannotDumpException() noexcept {} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */