1 #ifndef DALI_INTERNAL_PLATFORM_FILECLOSER_H
2 #define DALI_INTERNAL_PLATFORM_FILECLOSER_H
4 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <dali/devel-api/adaptor-framework/file-loader.h>
33 * Opens files and closes them later even if an exception is thrown.
37 protected: // prevent this class being directly instantiated
39 * @brief Construct a FileCloser guarding a new FILE* for accessing the path passed in.
41 FileCloser(const char* const filename, const char* const mode)
43 DALI_ASSERT_DEBUG(filename != 0 && "Can't open a null filename.");
44 DALI_ASSERT_DEBUG(mode != 0 && "Null mode is undefined behaviour in spec.");
46 Dali::FileLoader::FileType fileType = Dali::FileLoader::FileType::TEXT;
48 const char* modeStr = mode;
56 fileType = FileLoader::FileType::BINARY;
58 // Still has to use fopen for append and write modes
62 mFile = fopen(filename, mode);
71 std::streampos bufferSize = 0;
72 if(!Dali::FileLoader::ReadFile(filename, bufferSize, mFileBuffer, fileType))
78 mFile = fmemopen(&mFileBuffer[0], bufferSize, mode);
83 * @brief Construct a FileCloser guarding a FILE* for reading out of the memory buffer passed in.
85 FileCloser(uint8_t* buffer, size_t dataSize, const char* const mode)
86 : mFile(fmemopen(buffer, dataSize, mode))
90 FileCloser(Dali::Vector<uint8_t>& vector, size_t dataSize, const char* const mode)
92 // Resize the buffer to ensure any null that gets written by
93 // fmemopen is written past the end of any data that is written to the buffer.
94 // (Workaround for a bug in Ubuntu that overwrites null to the last byte of the
95 // data block regardless of whether binary mode was specified. Tizen doesn't write
96 // null if binary mode is specified).
97 size_t bufferSize = dataSize;
99 vector.Resize(bufferSize);
101 void* const buffer = &vector[0];
102 mFile = fmemopen(buffer, bufferSize, mode);
104 DALI_ASSERT_DEBUG(buffer != 0 && "Cant open file on null buffer.");
105 DALI_ASSERT_DEBUG(dataSize > 0 && "Pointless to open file on empty buffer.");
106 DALI_ASSERT_DEBUG(mode != 0 && "Null mode is undefined behaviour in spec.");
110 DALI_LOG_WARNING("File open failed for memory buffer at location: \"%p\", of size: \"%u\", in mode: \"%s\".\n", static_cast<void*>(buffer), static_cast<unsigned>(dataSize), mode);
115 * @brief Destroy the FileCloser and clean up its FILE*.
121 const int closeFailed = fclose(mFile);
125 DALI_LOG_WARNING("File close failed for FILE: \"%p\".\n", static_cast<void*>(mFile));
133 * @return The FILE* guarded by this object.
142 FileCloser(const FileCloser& fileCloser);
145 FileCloser& operator=(const FileCloser& fileCloser);
149 Dali::Vector<char> mFileBuffer;
152 } // namespace Platform
154 } // namespace Internal
158 #endif // DALI_INTERNAL_PLATFORM_FILECLOSER_H