You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.1 KiB
C++

/***************************************************************************
* 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 <gempa/caps/datetime.h>
#include <boost/shared_ptr.hpp>
#include <vector>
namespace Gempa {
namespace CAPS {
template<typename T> 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<T> data;
void *userData;
};
typedef boost::shared_ptr<Record> RecordPtr;
typedef boost::function<void (Record *rec, void*)> 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