1 /* 2 * Copyright 2018 Google Inc. 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 "file_handler.hpp" 18 19 #include <filesystem> 20 #include <ios> 21 #include <optional> 22 #include <utility> 23 #include <vector> 24 25 namespace ipmi_flash 26 { 27 28 bool FileHandler::open(const std::string& path, std::ios_base::openmode mode) 29 { 30 /* force binary mode */ 31 mode |= std::ios::binary; 32 this->path = path; 33 34 if (file.is_open()) 35 { 36 return true; 37 } 38 file.open(filename, mode); 39 return file.good(); 40 } 41 42 void FileHandler::close() 43 { 44 file.close(); 45 } 46 47 bool FileHandler::write(std::uint32_t offset, 48 const std::vector<std::uint8_t>& data) 49 { 50 file.seekp(offset); 51 file.write(reinterpret_cast<const char*>(data.data()), data.size()); 52 return file.good(); 53 } 54 55 std::optional<std::vector<uint8_t>> 56 FileHandler::read(std::uint32_t offset, std::uint32_t size) 57 { 58 uint32_t file_size = getSize(); 59 if (offset > file_size) 60 { 61 return std::nullopt; 62 } 63 std::vector<uint8_t> ret(std::min(file_size - offset, size)); 64 file.seekg(offset); 65 file.read(reinterpret_cast<char*>(ret.data()), ret.size()); 66 if (!file.good()) 67 { 68 return std::nullopt; 69 } 70 return ret; 71 } 72 73 int FileHandler::getSize() 74 { 75 std::error_code ec; 76 auto ret = std::filesystem::file_size(filename, ec); 77 if (ec) 78 { 79 auto error = ec.message(); 80 std::fprintf(stderr, "Failed to get filesize `%s`: %s\n", 81 filename.c_str(), error.c_str()); 82 return 0; 83 } 84 return ret; 85 } 86 87 } // namespace ipmi_flash 88