#include "globals.h" #include "proto.h" #include "fluxmap.h" #include "fmt/format.h" #include "lib/fl2.pb.h" #include static void upgradeFluxFile(FluxFileProto& proto) { if (proto.version() == FluxFileVersion::VERSION_1) { /* Change a flux datastream with multiple segments separated by F_DESYNC * into multiple flux segments. */ for (auto& track : *proto.mutable_track()) { if (track.flux_size() != 0) { Fluxmap oldFlux(track.flux(0)); track.clear_flux(); for (const auto& flux : oldFlux.split()) track.add_flux(flux->rawBytes()); } } proto.set_version(FluxFileVersion::VERSION_2); } if (proto.version() > FluxFileVersion::VERSION_2) Error() << fmt::format( "this is a version {} flux file, but this build of the client can " "only handle up to version {} --- please upgrade", proto.version(), FluxFileVersion::VERSION_2); } FluxFileProto loadFl2File(const std::string filename) { std::ifstream ifs(filename, std::ios::in | std::ios::binary); if (!ifs.is_open()) Error() << fmt::format( "cannot open input file '{}': {}", filename, strerror(errno)); char buffer[16]; ifs.read(buffer, sizeof(buffer)); if (strncmp(buffer, "SQLite format 3", 16) == 0) Error() << "this flux file is too old; please use the " "upgrade-flux-file tool to upgrade it"; FluxFileProto proto; ifs.seekg(0); if (!proto.ParseFromIstream(&ifs)) Error() << fmt::format("unable to read input file '{}'", filename); upgradeFluxFile(proto); return proto; } void saveFl2File(const std::string filename, FluxFileProto& proto) { proto.set_magic(FluxMagic::MAGIC); proto.set_version(FluxFileVersion::VERSION_2); std::ofstream of(filename, std::ios::out | std::ios::binary); if (!proto.SerializeToOstream(&of)) Error() << fmt::format("unable to write output file '{}'", filename); of.close(); if (of.fail()) Error() << "FL2 write I/O error: " << strerror(errno); }