1313#include " databento/enums.hpp"
1414#include " databento/exceptions.hpp"
1515#include " databento/record.hpp"
16+ #include " databento/with_ts_out.hpp"
1617
1718using databento::DbnDecoder;
1819
@@ -188,23 +189,47 @@ databento::Metadata DbnDecoder::DecodeMetadata() {
188189 read_buffer_.resize (version_and_size.second );
189190 input_->ReadExact (read_buffer_.data (), read_buffer_.size ());
190191 buffer_idx_ = read_buffer_.size ();
191- return DbnDecoder::DecodeMetadataFields (version_, read_buffer_);
192+ auto metadata = DbnDecoder::DecodeMetadataFields (version_, read_buffer_);
193+ ts_out_ = metadata.ts_out ;
194+ return metadata;
192195}
193196
197+ namespace {
198+ template <typename T, typename U>
199+ databento::Record UpgradeRecord (
200+ bool ts_out,
201+ std::array<std::uint8_t , databento::kMaxRecordLen >* compat_buffer,
202+ databento::Record rec) {
203+ if (ts_out) {
204+ const auto orig = rec.Get <databento::WithTsOut<T>>();
205+ const databento::WithTsOut<U> v2{orig.rec .ToV2 (), orig.ts_out };
206+ const auto v2_ptr = reinterpret_cast <const std::uint8_t *>(&v2);
207+ std::copy (v2_ptr, v2_ptr + v2.rec .hd .Size (), compat_buffer->data ());
208+ } else {
209+ const auto v2 = rec.Get <T>().ToV2 ();
210+ const auto v2_ptr = reinterpret_cast <const std::uint8_t *>(&v2);
211+ std::copy (v2_ptr, v2_ptr + v2.hd .Size (), compat_buffer->data ());
212+ }
213+ return databento::Record{
214+ reinterpret_cast <databento::RecordHeader*>(compat_buffer->data ())};
215+ }
216+ } // namespace
217+
194218databento::Record DbnDecoder::DecodeRecordCompat (
195- std::uint8_t version, VersionUpgradePolicy upgrade_policy,
219+ std::uint8_t version, VersionUpgradePolicy upgrade_policy, bool ts_out,
196220 std::array<std::uint8_t , kMaxRecordLen >* compat_buffer, Record rec) {
197221 if (version == 1 && upgrade_policy == VersionUpgradePolicy::Upgrade) {
198222 if (rec.RType () == RType::InstrumentDef) {
199- auto v2 = rec.Get <InstrumentDefMsgV1>().ToV2 ();
200- auto v2_ptr = reinterpret_cast <std::uint8_t *>(&v2);
201- std::copy (v2_ptr, v2_ptr + v2.hd .Size (), compat_buffer->data ());
202- return Record{reinterpret_cast <RecordHeader*>(compat_buffer->data ())};
223+ return UpgradeRecord<InstrumentDefMsgV1, InstrumentDefMsgV2>(
224+ ts_out, compat_buffer, rec);
203225 } else if (rec.RType () == RType::SymbolMapping) {
204- auto v2 = rec.Get <SymbolMappingMsgV1>().ToV2 ();
205- auto v2_ptr = reinterpret_cast <std::uint8_t *>(&v2);
206- std::copy (v2_ptr, v2_ptr + v2.hd .Size (), compat_buffer->data ());
207- return Record{reinterpret_cast <RecordHeader*>(compat_buffer->data ())};
226+ return UpgradeRecord<SymbolMappingMsgV1, SymbolMappingMsgV2>(
227+ ts_out, compat_buffer, rec);
228+ } else if (rec.RType () == RType::Error) {
229+ return UpgradeRecord<ErrorMsgV1, ErrorMsgV2>(ts_out, compat_buffer, rec);
230+ } else if (rec.RType () == RType::System) {
231+ return UpgradeRecord<SystemMsgV1, SystemMsgV2>(ts_out, compat_buffer,
232+ rec);
208233 }
209234 }
210235 return rec;
@@ -228,7 +253,7 @@ const databento::Record* DbnDecoder::DecodeRecord() {
228253 current_record_ = Record{BufferRecordHeader ()};
229254 buffer_idx_ += current_record_.Size ();
230255 current_record_ = DbnDecoder::DecodeRecordCompat (
231- version_, upgrade_policy_, &compat_buffer_, current_record_);
256+ version_, upgrade_policy_, ts_out_, &compat_buffer_, current_record_);
232257 return ¤t_record_;
233258}
234259
0 commit comments