64 : impl_(std::make_unique<Impl>(filename, schema)) {}
85 for (
const auto &frame : frames) {
86 impl_->write_frame(frame);
94 void flush() { impl_->flush(); }
97 void close() { impl_->close(); }
103 size_t frames_written = 0;
104 static constexpr size_t CHUNK_SIZE = 1000;
107 std::vector<HighFive::DataSet> signal_datasets;
108 HighFive::DataSet time_dataset;
111 : file(filename, HighFive::File::Truncate), schema(sch),
112 time_dataset(setup_file()) {}
114 HighFive::DataSet setup_file() {
116 file.createGroup(
"signals");
117 file.createGroup(
"metadata");
120 HighFive::DataSpace time_space({0},
121 {HighFive::DataSpace::UNLIMITED});
122 HighFive::DataSetCreateProps time_props;
123 time_props.add(HighFive::Chunking({CHUNK_SIZE}));
125 file.createDataSet<
double>(
"time", time_space, time_props);
128 for (
const auto &sig : schema.signals()) {
129 HighFive::DataSpace space({0},
130 {HighFive::DataSpace::UNLIMITED});
131 HighFive::DataSetCreateProps props;
132 props.add(HighFive::Chunking({CHUNK_SIZE}));
134 std::string path =
"signals/" + sig.name;
138 auto ds = file.createDataSet<
double>(path, space, props);
139 if (!sig.unit.empty()) {
140 ds.createAttribute<std::string>(
"unit", sig.unit);
142 if (!sig.semantic.empty()) {
143 ds.createAttribute<std::string>(
"semantic",
146 signal_datasets.push_back(std::move(ds));
150 auto ds = file.createDataSet<int32_t>(path, space, props);
151 if (!sig.unit.empty()) {
152 ds.createAttribute<std::string>(
"unit", sig.unit);
154 if (!sig.semantic.empty()) {
155 ds.createAttribute<std::string>(
"semantic",
158 signal_datasets.push_back(std::move(ds));
162 auto ds = file.createDataSet<int64_t>(path, space, props);
163 if (!sig.unit.empty()) {
164 ds.createAttribute<std::string>(
"unit", sig.unit);
166 if (!sig.semantic.empty()) {
167 ds.createAttribute<std::string>(
"semantic",
170 signal_datasets.push_back(std::move(ds));
177 auto metadata = file.getGroup(
"metadata");
178 metadata.createAttribute<std::string>(
"schema", schema.to_json());
181 auto now = std::time(
nullptr);
183 std::strftime(buf,
sizeof(buf),
"%Y-%m-%dT%H:%M:%SZ",
185 metadata.createAttribute<std::string>(
"created_at",
191 void write_frame(
const Frame &frame) {
193 time_dataset.resize({frames_written + 1});
194 time_dataset.select({frames_written}, {1}).write(frame.time());
197 for (
size_t i = 0; i < schema.signals().size(); ++i) {
198 const auto &sig = schema.signals()[i];
199 auto &ds = signal_datasets[i];
201 ds.resize({frames_written + 1});
205 double val = frame.get_double(sig.name);
206 ds.select({frames_written}, {1}).write(val);
210 int32_t val = frame.get_int32(sig.name);
211 ds.select({frames_written}, {1}).write(val);
215 int64_t val = frame.get_int64(sig.name);
216 ds.select({frames_written}, {1}).write(val);
225 size_t frame_count()
const {
return frames_written; }
227 void flush() { file.flush(); }
235 std::unique_ptr<Impl> impl_;