-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathblob.h
95 lines (65 loc) · 2.07 KB
/
blob.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#pragma once
#include <cstdio>
#include <cerrno>
#include <ios>
#include <memory>
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <stdexcept>
#include <system_error>
#include <type_traits>
struct Blob {
std::uint32_t a;
std::uint32_t b;
};
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<Blob>::value, "not safely memcpyable");
#endif
const constexpr auto kNumBlobs = 1u << 27u;
namespace std {
template <>
struct default_delete<std::FILE> {
void operator()(std::FILE* fp) const {
if (fp)
(void)std::fclose(fp);
}
};
}
using File = std::unique_ptr<std::FILE>;
inline void dump_to_binary(const char* path) {
File out{std::fopen(path, "wb")};
if (not out.get())
throw std::system_error{errno, std::system_category()};
static std::mt19937 mt{0xCAFE};
std::uniform_int_distribution<std::uint32_t> dist;
std::vector<Blob> buffer(kNumBlobs);
std::generate(begin(buffer), end(buffer), [&] { return Blob{dist(mt), dist(mt)}; });
const auto _ = std::fwrite(buffer.data(), sizeof(Blob), buffer.size(), out.get());
(void)_;
if (std::ferror(out.get()) != 0)
throw std::system_error{errno, std::system_category()};
if (std::fflush(out.get()) != 0)
throw std::system_error{errno, std::system_category()};
}
inline auto read_from_binary(const char* path) {
File in{std::fopen(path, "rb")};
if (not in.get())
throw std::system_error{errno, std::system_category()};
std::vector<Blob> buffer(kNumBlobs);
const auto _ = std::fread(buffer.data(), sizeof(Blob), kNumBlobs, in.get());
(void)_;
if (std::ferror(in.get()) != 0)
throw std::system_error{errno, std::system_category()};
return buffer;
}
inline auto read_from_binary_through_stream(const char* path) {
std::ifstream stream{path, std::ios::binary};
if (not stream)
throw std::runtime_error{"open failed"};
std::vector<Blob> buffer(kNumBlobs);
if (not stream.read(reinterpret_cast<char*>(buffer.data()), sizeof(Blob) * kNumBlobs))
throw std::runtime_error{"read failed"};
return buffer;
}