Skip to content

Commit fddc8eb

Browse files
committed
Separate template specializations for G3Timestreams
1 parent a699c51 commit fddc8eb

File tree

1 file changed

+111
-44
lines changed

1 file changed

+111
-44
lines changed

core/src/G3Timestream.cxx

Lines changed: 111 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,43 +36,6 @@ static FLAC__StreamEncoderWriteStatus flac_encoder_write_cb(
3636
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
3737
}
3838

39-
40-
// Generic version of loadBinary for all archive types
41-
template <typename A>
42-
static void load_binary_fn(A * inbuf, void * buffer, size_t size)
43-
{
44-
inbuf->template loadBinary<1>(buffer,size);
45-
}
46-
47-
#ifdef SPT3G_ENABLE_JSON_OUTPUT
48-
49-
// SpecializedloadBinary version for JSONInputArchive
50-
//
51-
// This is only needed because cereal will generate code for loading json due
52-
// to the nature of serialize, even though this will never actually be called.
53-
//
54-
// I don't know if it works or not, but since it's never called, who cares? (I
55-
// guess in the future we can have a fromJSON method in G3Frame as well if we
56-
// wanted to support round-tripping through JSON for some reason).
57-
58-
template <>
59-
void load_binary_fn<cereal::JSONInputArchive>(cereal::JSONInputArchive * inbuf, void * buffer, size_t size)
60-
{
61-
inbuf->loadBinaryValue(buffer,size);
62-
}
63-
64-
// Need a specialized FLAC variable too
65-
template <>
66-
struct FlacDecoderCallbackArgs<cereal::JSONInputArchive> {
67-
cereal::JSONInputArchive *inbuf;
68-
std::vector<int32_t> *outbuf;
69-
size_t pos;
70-
CEREAL_SIZE_TYPE nbytes;
71-
};
72-
#endif
73-
74-
75-
7639
template<typename A>
7740
static FLAC__StreamDecoderReadStatus flac_decoder_read_cb(
7841
const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes,
@@ -88,16 +51,16 @@ static FLAC__StreamDecoderReadStatus flac_decoder_read_cb(
8851
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
8952
} else if (*bytes >= size_t(bytes_left)) {
9053
*bytes = bytes_left;
91-
load_binary_fn(args->inbuf, buffer, bytes_left);
54+
args->inbuf->template loadBinary<1>(buffer, bytes_left);
9255
args->pos += bytes_left;
9356
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
9457
} else {
95-
load_binary_fn(args->inbuf, buffer, *bytes);
58+
args->inbuf->template loadBinary<1>(buffer, *bytes);
9659
args->pos += *bytes;
9760
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
9861
}
9962
}
100-
63+
10164
template<typename A>
10265
static FLAC__StreamDecoderWriteStatus flac_decoder_write_cb(
10366
const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
@@ -112,7 +75,7 @@ static FLAC__StreamDecoderWriteStatus flac_decoder_write_cb(
11275
(*args->outbuf)[oldsize + i] = buffer[0][i];
11376
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
11477
}
115-
78+
11679
static void flac_decoder_error_cb(const FLAC__StreamDecoder *decoder,
11780
FLAC__StreamDecoderErrorStatus status, void *client_data)
11881
{
@@ -149,8 +112,7 @@ template <class A> void G3Timestream::save(A &ar, unsigned v) const
149112
ar & cereal::make_nvp("flac", use_flac_);
150113

151114
#ifdef G3_HAS_FLAC
152-
//Don't try to use FLAC when outputing to JSON, even if flac is enabled.
153-
if (use_flac_ && typeid(A) == typeid(cereal::PortableBinaryOutputArchive)) {
115+
if (use_flac_) {
154116
std::vector<int32_t> inbuf;
155117
std::vector<uint8_t> outbuf;
156118
const int32_t *chanmap[1];
@@ -397,6 +359,111 @@ template <class A> void G3Timestream::load(A &ar, unsigned v)
397359
}
398360
}
399361

362+
#ifdef SPT3G_ENABLE_JSON_OUTPUT
363+
template <> void G3Timestream::save(cereal::JSONOutputArchive &ar, unsigned v) const
364+
{
365+
ar & cereal::make_nvp("G3FrameObject",
366+
cereal::base_class<G3FrameObject>(this));
367+
ar & cereal::make_nvp("units", units);
368+
ar & cereal::make_nvp("start", start);
369+
ar & cereal::make_nvp("stop", stop);
370+
371+
ar & cereal::make_nvp("data_type", data_type_);
372+
if (buffer_) {
373+
ar & cereal::make_nvp("data", *buffer_);
374+
} else {
375+
switch (data_type_) {
376+
case TS_DOUBLE: {
377+
std::vector<double> data((double *)data_,
378+
(double *)data_ + len_);
379+
ar & cereal::make_nvp("data", data);
380+
break;
381+
}
382+
case TS_FLOAT: {
383+
std::vector<float> data((float *)data_,
384+
(float *)data_ + len_);
385+
ar & cereal::make_nvp("data", data);
386+
break;
387+
}
388+
case TS_INT32: {
389+
std::vector<int32_t> data((int32_t *)data_,
390+
(int32_t *)data_ + len_);
391+
ar & cereal::make_nvp("data", data);
392+
break;
393+
}
394+
case TS_INT64: {
395+
std::vector<int64_t> data((int64_t *)data_,
396+
(int64_t *)data_ + len_);
397+
ar & cereal::make_nvp("data", data);
398+
break;
399+
}
400+
default:
401+
log_fatal("Unknown timestream datatype %d", data_type_);
402+
}
403+
}
404+
}
405+
406+
template <> void G3Timestream::load(cereal::JSONInputArchive &ar, unsigned v)
407+
{
408+
G3_CHECK_VERSION(v);
409+
410+
ar & cereal::make_nvp("G3FrameObject",
411+
cereal::base_class<G3FrameObject>(this));
412+
ar & cereal::make_nvp("units", units);
413+
if (v >= 2) {
414+
ar & cereal::make_nvp("start", start);
415+
ar & cereal::make_nvp("stop", stop);
416+
}
417+
418+
if (buffer_)
419+
delete buffer_;
420+
buffer_ = NULL;
421+
root_data_ref_.reset();
422+
423+
if (v >= 3)
424+
ar & cereal::make_nvp("data_type", data_type_);
425+
else
426+
data_type_ = TS_DOUBLE;
427+
switch (data_type_) {
428+
case TS_DOUBLE:
429+
buffer_ = new std::vector<double>();
430+
ar & cereal::make_nvp("data", *buffer_);
431+
len_ = buffer_->size();
432+
data_ = &(*buffer_)[0];
433+
break;
434+
case TS_FLOAT: {
435+
std::vector<float> *data = new std::vector<float>();
436+
ar & cereal::make_nvp("data", *data);
437+
root_data_ref_ = std::shared_ptr<std::vector<float> >(
438+
data);
439+
len_ = data->size();
440+
data_ = &(*data)[0];
441+
break;
442+
}
443+
case TS_INT32: {
444+
std::vector<int32_t> *data = new std::vector<int32_t>();
445+
ar & cereal::make_nvp("data", *data);
446+
root_data_ref_ = std::shared_ptr<
447+
std::vector<int32_t> >(data);
448+
len_ = data->size();
449+
data_ = &(*data)[0];
450+
break;
451+
}
452+
case TS_INT64: {
453+
std::vector<int64_t> *data = new std::vector<int64_t>();
454+
ar & cereal::make_nvp("data", *data);
455+
root_data_ref_ = std::shared_ptr<
456+
std::vector<int64_t> >(data);
457+
len_ = data->size();
458+
data_ = &(*data)[0];
459+
break;
460+
}
461+
default:
462+
log_fatal("Unknown timestream datatype %d", data_type_);
463+
}
464+
}
465+
#endif
466+
400467
G3Timestream::G3Timestream(const G3Timestream &r) :
401468
units(r.units), start(r.start), stop(r.stop), use_flac_(r.use_flac_),
402469
len_(r.len_), data_type_(r.data_type_)
@@ -911,7 +978,7 @@ void G3TimestreamMap::Compactify()
911978
}
912979
}
913980

914-
G3_SPLIT_SERIALIZABLE_CODE(G3Timestream);
981+
G3_SPLIT_SERIALIZABLE_CODE_BINARY(G3Timestream);
915982
G3_SERIALIZABLE_CODE(G3TimestreamMap);
916983

917984
class G3Timestream::G3TimestreamPythonHelpers

0 commit comments

Comments
 (0)