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 <cstdint>
20 #include <filesystem>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 namespace ipmi_flash
26 {
27 namespace fs = std::filesystem;
28 
29 bool FileHandler::open(const std::string& path)
30 {
31     this->path = path;
32 
33     if (file.is_open())
34     {
35         /* This wasn't properly closed somehow.
36          * TODO: Throw an error or just reset the state?
37          */
38         return false;
39     }
40 
41     /* using ofstream no need to set out */
42     file.open(filename, std::ios::binary);
43     if (file.bad())
44     {
45         /* TODO: Oh no! Care about this. */
46         return false;
47     }
48 
49     /* We were able to open the file for staging.
50      * TODO: We'll need to do other stuff to eventually.
51      */
52     return true;
53 }
54 
55 void FileHandler::close()
56 {
57     if (file.is_open())
58     {
59         file.close();
60     }
61     return;
62 }
63 
64 bool FileHandler::write(std::uint32_t offset,
65                         const std::vector<std::uint8_t>& data)
66 {
67     if (!file.is_open())
68     {
69         return false;
70     }
71 
72     /* We could track this, but if they write in a scattered method, this is
73      * easier.
74      */
75     file.seekp(offset, std::ios_base::beg);
76     if (!file.good())
77     {
78         /* the documentation wasn't super clear on fail vs bad in these cases,
79          * so let's only be happy with goodness.
80          */
81         return false;
82     }
83 
84     file.write(reinterpret_cast<const char*>(data.data()), data.size());
85     if (!file.good())
86     {
87         return false;
88     }
89 
90     return true;
91 }
92 
93 int FileHandler::getSize()
94 {
95     try
96     {
97         return static_cast<int>(fs::file_size(filename));
98     }
99     catch (const fs::filesystem_error& e)
100     {
101     }
102 
103     return 0;
104 }
105 
106 } // namespace ipmi_flash
107