NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
binary_content.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
27 
28 #include <cstdio>
29 
30 #include <doca_error.h>
31 
34 
35 namespace storage {
36 
37 namespace {
38 
39 uint64_t constexpr sbc_magic_value = 0xDEADF00D1337FADE;
40 
41 auto constexpr max_sbc_content_size = uint32_t{2} * 1024 * 1024 * 1024; /* 2 GB */
42 
43 struct file_handle {
44  ~file_handle()
45  {
46  if (m_f != nullptr) {
47  fclose(m_f);
48  m_f = nullptr;
49  }
50  }
51 
52  file_handle() = delete;
53 
54  explicit file_handle(FILE *f) : m_f{f}
55  {
56  }
57 
58  file_handle(file_handle const &) = delete;
59  file_handle(file_handle &&) noexcept = delete;
60  file_handle &operator=(file_handle const &) = delete;
61  file_handle &operator=(file_handle &&) noexcept = delete;
62 
63  operator FILE *()
64  {
65  return m_f;
66  }
67 
68 private:
69  FILE *m_f;
70 };
71 
72 } // namespace
73 
74 bool file_has_binary_content_header(std::string const &file_name)
75 {
76  auto fh = file_handle{[&file_name]() {
77  auto *f = fopen(file_name.c_str(), "rb");
78  if (f == nullptr) {
79  throw storage::runtime_error{DOCA_ERROR_NOT_FOUND, "Unable to open file: " + file_name};
80  }
81  return f;
82  }()};
83 
84  uint64_t magic;
85  if (fread(&magic, 1, sizeof(magic), fh) != sizeof(magic)) {
86  return false;
87  }
88 
89  magic = be64toh(magic);
90 
91  return magic == sbc_magic_value;
92 }
93 
95 {
96  auto fh = file_handle{[&file_name]() {
97  auto *f = fopen(file_name.c_str(), "rb");
98  if (f == nullptr) {
99  throw storage::runtime_error{DOCA_ERROR_NOT_FOUND, "Unable to open sbc file: " + file_name};
100  }
101  return f;
102  }()};
104 
105  uint64_t magic;
106  if (fread(&magic, 1, sizeof(magic), fh) != sizeof(magic)) {
107  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to read magic from sbc file"};
108  }
109 
110  magic = be64toh(magic);
111  if (magic != sbc_magic_value) {
112  throw storage::runtime_error{DOCA_ERROR_INVALID_VALUE, "Expected magic value did not match"};
113  }
114 
115  if (fread(&sbc.block_size, 1, sizeof(sbc.block_size), fh) != sizeof(sbc.block_size)) {
116  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to read block size from sbc file"};
117  }
118 
119  if (fread(&sbc.block_count, 1, sizeof(sbc.block_count), fh) != sizeof(sbc.block_count)) {
120  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to read block count from sbc file"};
121  }
122 
123  sbc.block_size = be32toh(sbc.block_size);
124  sbc.block_count = be32toh(sbc.block_count);
125 
126  auto const content_size = size_t{sbc.block_size} * sbc.block_count;
127  if (content_size > max_sbc_content_size) {
129  "Failed to read content from sbc file. Exceeded limit: " +
130  std::to_string(max_sbc_content_size)};
131  }
132 
133  sbc.content.resize(content_size);
134  if (fread(sbc.content.data(), 1, sbc.content.size(), fh) != sbc.content.size()) {
135  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to read content from sbc file"};
136  }
137 
138  return sbc;
139 }
140 
141 void write_binary_content_to_file(std::string const &file_name, storage::binary_content const &sbc)
142 {
143  auto fh = file_handle{[&file_name]() {
144  auto *f = fopen(file_name.c_str(), "wb");
145  if (f == nullptr) {
146  throw storage::runtime_error{DOCA_ERROR_NOT_FOUND, "Unable to open sbc file: " + file_name};
147  }
148  return f;
149  }()};
150 
151  auto const sbc_size = size_t{sbc.block_count} * sbc.block_size;
152  if (sbc_size > max_sbc_content_size) {
154  "Failed to write content to sbc file. Exceeded limit: " +
155  std::to_string(max_sbc_content_size)};
156  }
157 
158  uint32_t const block_size = htobe32(sbc.block_size);
159  uint32_t const block_count = htobe32(sbc.block_count);
160 
161  uint64_t const magic = htobe64(sbc_magic_value);
162  if (fwrite(&magic, 1, sizeof(magic), fh) != sizeof(magic)) {
163  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to write magic to sbc file"};
164  }
165 
166  if (fwrite(&block_size, 1, sizeof(block_size), fh) != sizeof(block_size)) {
167  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to write block size to sbc file"};
168  }
169 
170  if (fwrite(&block_count, 1, sizeof(block_count), fh) != sizeof(block_count)) {
171  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to write block count to sbc file"};
172  }
173 
174  if (fwrite(sbc.content.data(), 1, sbc.content.size(), fh) != sbc.content.size()) {
175  throw storage::runtime_error{DOCA_ERROR_IO_FAILED, "Failed to write content to sbc file"};
176  }
177 }
178 
179 } // namespace storage
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_ERROR_NOT_FOUND
Definition: doca_error.h:54
@ DOCA_ERROR_IO_FAILED
Definition: doca_error.h:55
std::string to_string(storage::control::message_type type)
void write_binary_content_to_file(std::string const &file_name, storage::binary_content const &sbc)
bool file_has_binary_content_header(std::string const &file_name)
storage::binary_content load_binary_content_from_file(std::string const &file_name)
#define htobe64
Definition: os_utils.hpp:41
#define htobe32
Definition: os_utils.hpp:40
std::vector< uint8_t > content