/*************************************************************************** * Copyright (C) 2013 by gempa GmbH * * * * All Rights Reserved. * * * * NOTICE: All information contained herein is, and remains * * the property of gempa GmbH and its suppliers, if any. The intellectual * * and technical concepts contained herein are proprietary to gempa GmbH * * and its suppliers. * * Dissemination of this information or reproduction of this material * * is strictly forbidden unless prior written permission is obtained * * from gempa GmbH. * ***************************************************************************/ #ifndef GEMPA_CAPS_RECORD_SAMPLER_H #define GEMPA_CAPS_RECORD_SAMPLER_H #include #include #include namespace Gempa { namespace CAPS { template class RecordBuilder { public: struct Record { Record() : samplingInterval(0.0), sampleCount(0), userData(NULL) {} std::string netcode; std::string stacode; std::string loccode; std::string chacode; Time startTime; double samplingInterval; size_t sampleCount; std::vector data; void *userData; }; typedef boost::shared_ptr RecordPtr; typedef boost::function FlushCallback; public: RecordBuilder() : _bufSize(64) {} RecordBuilder(const std::string &netcode, const std::string &stacode, const std::string &loccode, const std::string &chacode, void *userData = NULL, size_t bufSize = 64) { _networkCode = netcode; _stationCode = stacode; _locationCode = loccode; _channelCode = chacode; _userData = userData; _bufSize = bufSize > 0? bufSize:1; _record = NULL; } void flush(bool lastSample = false) { if ( _record != 0 ) { if ( lastSample ) push(); _flushCallback(_record, _userData); _record = NULL; } } void push(T value, const Time &time) { if ( _time.valid() ) { double interval = time - _time; if ( interval <= 0.0 ) { _time = Time(); flush(true); return; } else { if ( _record == NULL) { _record = new Record; if ( _record ) { _record->netcode = _networkCode; _record->stacode = _stationCode; _record->loccode = _locationCode; _record->chacode = _channelCode; _record->startTime = _time; _record->samplingInterval = interval; _record->data.reserve(_bufSize); _record->data[_record->sampleCount] = _value; ++_record->sampleCount; } } else if ( interval != _record->samplingInterval ) { flush(true); } else { push(); } } } _time = time; _value = value; } void setFlushCallback(const FlushCallback &cb) { _flushCallback = cb; } void setNetworkCode(const std::string &netcode) { _networkCode = netcode; } void setStationCode(const std::string &stacode) { _stationCode = stacode; } void setLocationCode(const std::string &loccode) { _locationCode = loccode; } void setChannelCode(const std::string &chacode) { _channelCode = chacode; } void setUserData(void *userData) { _userData = userData; } private: void push() { if ( _record->sampleCount % _bufSize == 0 ) _record->data.reserve(_record->sampleCount + _bufSize); _record->data[_record->sampleCount] = _value; ++_record->sampleCount; } private: T _value; Time _time; Record *_record; FlushCallback _flushCallback; size_t _bufSize; std::string _networkCode; std::string _stationCode; std::string _locationCode; std::string _channelCode; void *_userData; }; } } #endif