xref: /openbmc/phosphor-ipmi-flash/bmc/file_handler.cpp (revision ba90fd7ae0088caa3317d747415213ebb925cc8f)
1f0c71df2SPatrick Venture /*
2f0c71df2SPatrick Venture  * Copyright 2018 Google Inc.
3f0c71df2SPatrick Venture  *
4f0c71df2SPatrick Venture  * Licensed under the Apache License, Version 2.0 (the "License");
5f0c71df2SPatrick Venture  * you may not use this file except in compliance with the License.
6f0c71df2SPatrick Venture  * You may obtain a copy of the License at
7f0c71df2SPatrick Venture  *
8f0c71df2SPatrick Venture  *     http://www.apache.org/licenses/LICENSE-2.0
9f0c71df2SPatrick Venture  *
10f0c71df2SPatrick Venture  * Unless required by applicable law or agreed to in writing, software
11f0c71df2SPatrick Venture  * distributed under the License is distributed on an "AS IS" BASIS,
12f0c71df2SPatrick Venture  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f0c71df2SPatrick Venture  * See the License for the specific language governing permissions and
14f0c71df2SPatrick Venture  * limitations under the License.
15f0c71df2SPatrick Venture  */
16f0c71df2SPatrick Venture 
17f0c71df2SPatrick Venture #include "file_handler.hpp"
18f0c71df2SPatrick Venture 
19f0c71df2SPatrick Venture #include <filesystem>
2056a2273fSJason Ling #include <ios>
21*ba90fd7aSWilliam A. Kennington III #include <optional>
22*ba90fd7aSWilliam A. Kennington III #include <utility>
23f0c71df2SPatrick Venture #include <vector>
24f0c71df2SPatrick Venture 
25f0c71df2SPatrick Venture namespace ipmi_flash
26f0c71df2SPatrick Venture {
27f0c71df2SPatrick Venture 
2856a2273fSJason Ling bool FileHandler::open(const std::string& path, std::ios_base::openmode mode)
29f0c71df2SPatrick Venture {
3056a2273fSJason Ling     /* force binary mode */
3156a2273fSJason Ling     mode |= std::ios::binary;
32f0c71df2SPatrick Venture     this->path = path;
33f0c71df2SPatrick Venture 
34f0c71df2SPatrick Venture     if (file.is_open())
35f0c71df2SPatrick Venture     {
36f0c71df2SPatrick Venture         return true;
37f0c71df2SPatrick Venture     }
38*ba90fd7aSWilliam A. Kennington III     file.open(filename, mode);
39*ba90fd7aSWilliam A. Kennington III     return file.good();
40*ba90fd7aSWilliam A. Kennington III }
41f0c71df2SPatrick Venture 
42f0c71df2SPatrick Venture void FileHandler::close()
43f0c71df2SPatrick Venture {
44f0c71df2SPatrick Venture     file.close();
45f0c71df2SPatrick Venture }
46f0c71df2SPatrick Venture 
47f0c71df2SPatrick Venture bool FileHandler::write(std::uint32_t offset,
48f0c71df2SPatrick Venture                         const std::vector<std::uint8_t>& data)
49f0c71df2SPatrick Venture {
50*ba90fd7aSWilliam A. Kennington III     file.seekp(offset);
51f0c71df2SPatrick Venture     file.write(reinterpret_cast<const char*>(data.data()), data.size());
52*ba90fd7aSWilliam A. Kennington III     return file.good();
53f0c71df2SPatrick Venture }
54f0c71df2SPatrick Venture 
5556a2273fSJason Ling std::optional<std::vector<uint8_t>> FileHandler::read(std::uint32_t offset,
5656a2273fSJason Ling                                                       std::uint32_t size)
5756a2273fSJason Ling {
58*ba90fd7aSWilliam A. Kennington III     uint32_t file_size = getSize();
59*ba90fd7aSWilliam A. Kennington III     if (offset > file_size)
6056a2273fSJason Ling     {
6156a2273fSJason Ling         return std::nullopt;
6256a2273fSJason Ling     }
63*ba90fd7aSWilliam A. Kennington III     std::vector<uint8_t> ret(std::min(file_size - offset, size));
6456a2273fSJason Ling     file.seekg(offset);
65*ba90fd7aSWilliam A. Kennington III     file.read(reinterpret_cast<char*>(ret.data()), ret.size());
6656a2273fSJason Ling     if (!file.good())
6756a2273fSJason Ling     {
6856a2273fSJason Ling         return std::nullopt;
6956a2273fSJason Ling     }
70*ba90fd7aSWilliam A. Kennington III     return std::move(ret);
7156a2273fSJason Ling }
7256a2273fSJason Ling 
73f0c71df2SPatrick Venture int FileHandler::getSize()
74f0c71df2SPatrick Venture {
75*ba90fd7aSWilliam A. Kennington III     std::error_code ec;
76*ba90fd7aSWilliam A. Kennington III     auto ret = std::filesystem::file_size(filename, ec);
77*ba90fd7aSWilliam A. Kennington III     if (ec)
78f0c71df2SPatrick Venture     {
79*ba90fd7aSWilliam A. Kennington III         auto error = ec.message();
80*ba90fd7aSWilliam A. Kennington III         std::fprintf(stderr, "Failed to get filesize `%s`: %s\n",
81*ba90fd7aSWilliam A. Kennington III                      filename.c_str(), error.c_str());
82f0c71df2SPatrick Venture         return 0;
83f0c71df2SPatrick Venture     }
84*ba90fd7aSWilliam A. Kennington III     return ret;
85*ba90fd7aSWilliam A. Kennington III }
86f0c71df2SPatrick Venture 
87f0c71df2SPatrick Venture } // namespace ipmi_flash
88