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++
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
|