Line data Source code
1 : // 2 : // Copyright 2024 OpenModelViewer Authors 3 : // 4 : // Licensed under the Apache License, Version 2.0 (the "License"); 5 : // you may not use this file except in compliance with the License. 6 : // You may obtain a copy of the License at 7 : // 8 : // http://www.apache.org/licenses/LICENSE-2.0 9 : // 10 : // Unless required by applicable law or agreed to in writing, software 11 : // distributed under the License is distributed on an "AS IS" BASIS, 12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 : // See the License for the specific language governing permissions and 14 : // limitations under the License. 15 : // 16 : 17 : #include "openmodelviewer/core/io/ofile.hpp" 18 : 19 : #include <fstream> 20 : 21 : namespace openmodelviewer::core::io 22 : { 23 1 : IOResult OFile::writeStringToFile(const std::filesystem::path& path, const std::string& content, FileOpenMode writeMode) 24 : { 25 2 : return openFileToExecute(path, writeMode, 26 1 : [&content](std::ofstream& out) -> IOResult 27 : { 28 1 : out << content; 29 1 : return out.good() ? IOResult::Success : IOResult::WriteError; 30 : } 31 2 : ); 32 : } 33 : 34 1 : IOResult OFile::writeBufferToFile(const std::filesystem::path& path, const std::vector<uint8_t>& buffer, FileOpenMode writeMode) 35 : { 36 2 : return openFileToExecute(path, writeMode, 37 2 : [&buffer](std::ofstream& out) -> IOResult 38 : { 39 1 : out.write(reinterpret_cast<const char*>(buffer.data()), static_cast<std::streamsize>(buffer.size())); 40 1 : return out.good() ? IOResult::Success : IOResult::WriteError; 41 : } 42 2 : ); 43 : } 44 : 45 3 : IOResult OFile::openFileToExecute(const std::filesystem::path& path, FileOpenMode writeMode, const std::function<IOResult(std::ofstream&)>& action) 46 : { 47 3 : std::ofstream out; 48 3 : IOResult openResult = openOutFileStream(path, writeMode, out); 49 : 50 3 : if (openResult != IOResult::Success) 51 : { 52 0 : return openResult; 53 : } 54 : 55 3 : IOResult actionResult = action(out); 56 : 57 3 : out.flush(); 58 3 : out.close(); 59 3 : return actionResult; 60 3 : } 61 : 62 13 : IOResult OFile::openOutFileStream(const std::filesystem::path& path, FileOpenMode mode, std::ofstream& outStream) 63 : { 64 13 : if (path.empty()) 65 : { 66 0 : return IOResult::EmptyPath; 67 : } 68 : 69 13 : if (std::filesystem::is_directory(path)) 70 : { 71 0 : return IOResult::FilePathExpected; 72 : } 73 : 74 13 : bool fileExists = std::filesystem::exists(path); 75 : 76 13 : std::ios::openmode openMode = std::ios::binary; 77 13 : switch (mode) 78 : { 79 12 : case FileOpenMode::OverwriteAlways: 80 12 : openMode |= std::ios::trunc; 81 12 : break; 82 : 83 1 : case FileOpenMode::AppendAlways: 84 1 : openMode |= std::ios::app; 85 1 : break; 86 : 87 0 : case FileOpenMode::OverwriteIfExists: 88 0 : if (!fileExists) 89 : { 90 0 : return IOResult::FileNotFound; 91 : } 92 0 : openMode |= std::ios::trunc; 93 0 : break; 94 : 95 0 : case FileOpenMode::AppendIfExists: 96 0 : if (!fileExists) 97 : { 98 0 : return IOResult::FileNotFound; 99 : } 100 0 : openMode |= std::ios::app; 101 0 : break; 102 : 103 0 : case FileOpenMode::FailIfExists: 104 0 : if (fileExists) 105 : { 106 0 : return IOResult::FileAlreadyExists; 107 : } 108 0 : break; 109 : } 110 : 111 13 : outStream.open(path, openMode); 112 13 : return outStream.is_open() ? IOResult::Success : IOResult::PermissionDenied; 113 : } 114 : }