/usr/include/GDF/Writer.h is in libgdf-dev 0.1.2-2build3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | //
// This file is part of libGDF.
//
// libGDF is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// libGDF is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with libGDF. If not, see <http://www.gnu.org/licenses/>.
//
// Copyright 2010 Martin Billinger
#ifndef __WRITER_H_INCLUDED__
#define __WRITER_H_INCLUDED__
#include "GDF/RecordBuffer.h"
#include "GDF/EventHeader.h"
#include "GDF/GDFHeaderAccess.h"
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
namespace gdf
{
enum WriterFlags
{
writer_ev_file = 0,
writer_ev_memory = 1,
writer_overwrite = 2
};
/// Class for writing GDF files to disc.
/** Events are buffered and appended to the file when calling close( ). By default events are buffered
in a separate file named \e filename.events. Thus, information may be recovered after computer
crashes during long online recordings. The user may chose to buffer events in memory instead (see open()).
*/
class Writer : public RecordBuffer::RecordFullHandler
{
public:
/// Constructor
Writer( );
/// Destructor
virtual ~Writer( );
/// Opens file for writing and writes Header
/** Prior to opening the file, GDFHeaderAccess::sanitize() is called. Exceptions thrown by
GDFHeaderAccess::sanitize() are checked if there are errors and/or warnings. In the presence
of errors the exception is forwarded immediately, and in case of warnings the file is opened
but the exception is still forwarded. If the file exists, it is not opened unless the file_overwrite
flag is set.
@param[in] flags Flags...
@throws exception::header_issues
@throws exception::file_exists
*/
void open( const int flags = writer_ev_file );
/// Opens file for writing and writes Header
/** Convenience function. Calls setFilename prior to opening the file
@param[in] filename Full path name to the file.
@param[in] flags Flags...
@throws exception::header_issues
@throws exception::file_exists
*/
void open( const std::string filename, const int flags = writer_ev_file );
/// Close file.
/** File is closed if open. Prior to closing, events are written to the file. */
void close( );
/// Check if file is open
bool isOpen( );
/// set filename for later opening
/** @param[in] filename Full path name to the file
*/
void setFilename( std::string filename );
/// Set number of full records that are kept in memory before the buffer is flushed.
/** @param[in] num number of records */
void setMaxFullRecords( size_t num );
/// Create a signal.
/** Signals have to be created before they can be configured and stored.
@param[in] index index of the signal
@param[in] throwexc if true, exception::signal_exists may be thrown
@returns true on success
*/
bool createSignal( size_t index, bool throwexc = false );
/// Swap to signals
/** Both signals must exist.
@param[in] a index of first signal
@param[in] b index of second signal
*/
void swapSignals( size_t a, size_t b );
/// Change signal index
/** The new index must not exist
@param[in] src old index of first signal
@param[in] dst new index of second signal
*/
void relocateSignal( size_t src, size_t dst );
/// get lowest signal index that can be created
size_t getFirstFreeSignalIndex( );
/// Blit data from a serial buffer
/** Instead of streaming samples as they come, the complete data is provided in an array of type double.
In the buffer channels have to be arranged sequentially. I.e. all samples from channel 1 are
followed by all samles from channel 2, and so on. This function attempts to keep memory overhead low
by filling record by record whenever possible.
@param[in] buf Buffer
@param[in] samples_per_channel A vector containing the number of samples in each channel.
*/
void blitFromSerialBufferPhys( const double *buf, const std::vector<size_t> &samples_per_channel );
/// Add sample in physical units to a channel
/**
The sample value is converted from the channels [physmin,physmax] to the range of [digmin,digmax] and
then cast to the correct data type.
@param[in] channel_idx index of the channel written to
@param[in] value sample value in physical units
*/
void addSamplePhys( const size_t channel_idx, const float64 value );
/// Add a raw sample to channel
/**
The sample value is cast to the correct data type, but no range checking is performed
@param[in] channel_idx index of the channel written to
@param[in] value raw sample value in physical units
*/
template<typename T> void addSampleRaw( const size_t channel_idx, const T value )
{
m_recbuf.addSampleRaw<T>( channel_idx, value );
}
/// Blit a number of samples in physical units to channel
/**
The sample values are converted from the channels [physmin,physmax] to the range of [digmin,digmax] and
then cast to the correct data type.
@param[in] channel_idx index of the channel written to
@param[in] values array of sample values in physical units
@param[in] num number of samples to blit
*/
void blitSamplesPhys( const size_t channel_idx, const float64 *values, size_t num );
/// Blit a number of samples in physical units to channel
/**
The sample values are converted from the channels [physmin,physmax] to the range of [digmin,digmax] and
then cast to the correct data type.
@param[in] channel_idx index of the channel written to
@param[in] values vector of sample values in physical units
*/
void blitSamplesPhys( const size_t channel_idx, const std::vector<float64> &values );
/// Blit a number of raw samples to channel
/**
The sample values are cast to the correct data type, but no range checking is performed
@param[in] channel_idx index of the channel written to
@param[in] values array of raw sample value
@param[in] num number of samples to blit
*/
template<typename T> void blitSamplesRaw( const size_t channel_idx, const T *values, size_t num )
{
m_recbuf.blitSamplesRaw<T>( channel_idx, values, num );
}
/// Blit a number of raw samples to channel
/**
The sample values are cast to the correct data type, but no range checking is performed
@param[in] channel_idx index of the channel written to
@param[in] values vector of raw sample value
*/
template<typename T> void blitSamplesRaw( const size_t channel_idx, const std::vector<T> &values )
{
m_recbuf.blitSamplesRaw<T>( channel_idx, &values[0], values.size() );
}
/// Add a complete Record
void addRecord( Record *r );
/// Get pointer to a fresh Record
Record *acquireRecord( );
/// writes record to disc
void writeRecordDirect( Record *r );
/// writes all full records from buffer to disc
void flush( );
/// Set Event Mode
/** mode can be 1 or 3
1: (default) Events are stored as position,type pairs
3: Events are stored with position and type, associated to a channel and have a duration
or value.
@param[in] mode event mode
*/
void setEventMode( uint8 mode );
/// Set Sampling Rate associated with event positions
/** Events are not actually sampled, but their position is stored in samples rather than seconds.
In order to convert event positions between time and sample, this sampling rate is used.
If Sampling rate is not set (or set to <= 0 ), fs is set to the highest signal sampling rate.
@param[in] fs sampling rate
*/
void setEventSamplingRate( float32 fs = -1 );
/// Add a Mode 1 Event
void addEvent( const Mode1Event &ev );
/// Add a Mode 1 Event
void addEvent( uint32 position, uint16 type );
/// Add a Mode 3 Event
void addEvent( const Mode3Event &ev );
/// Add a Mode 3 Event
void addEvent( uint32 position, uint16 type, uint16 channel, uint32 duration );
/// Add a Mode 3 Event
void addEvent( uint32 position, uint16 type, uint16 channel, float32 value );
/// get Constant reference to header access
const GDFHeaderAccess &getHeaderAccess_readonly( ) const { return m_header; }
/// get reference to main header
GDFHeaderAccess &getHeaderAccess( ) { return m_header; }
/// get Constant reference to main header
const MainHeader &getMainHeader_readonly( ) const { return m_header.getMainHeader_readonly( ); }
/// get reference to main header
MainHeader &getMainHeader( ) { return m_header.getMainHeader( ); }
/// get constant reference to a signal's header
const SignalHeader &getSignalHeader_readonly( size_t idx ) const { return m_header.getSignalHeader_readonly(idx); }
inline size_t getNumSignals( ) const { return m_header.getNumSignals( ); }
/// get reference to a signal's header
SignalHeader &getSignalHeader( size_t idx ) { return m_header.getSignalHeader(idx); }
private:
/// write first full record from record buffer to disk
void writeRecord( );
/// write events from buffer to file
void writeEvents( );
/// record full handler
virtual void triggerRecordFull( Record *rec );
RecordBuffer m_recbuf;
GDFHeaderAccess m_header;
std::fstream m_file;
std::iostream m_eventbuffer;
std::fstream m_evbuf_file;
std::stringstream m_evbuf_memory;
int m_eventbuffermemory;
std::string m_filename;
int64 m_num_datarecords;
size_t max_full_records;
};
}
#endif // __WRITER_H_INCLUDED__
|