|
libGDF
|
00001 // 00002 // This file is part of libGDF. 00003 // 00004 // libGDF is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation, either version 3 of 00007 // the License, or (at your option) any later version. 00008 // 00009 // libGDF is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with libGDF. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // Copyright 2010 Martin Billinger 00018 00019 #include "GDF/Modifier.h" 00020 #include "GDF/Record.h" 00021 #include "GDF/tools.h" 00022 #include <boost/numeric/conversion/cast.hpp> 00023 #include <fstream> 00024 #include <iostream> 00025 00026 namespace gdf 00027 { 00028 Modifier::Modifier( ) 00029 { 00030 m_cache_enabled = true; 00031 m_events_changed = false; 00032 } 00033 00034 //=================================================================================================== 00035 //=================================================================================================== 00036 00037 Modifier::~Modifier( ) 00038 { 00039 } 00040 00041 //=================================================================================================== 00042 //=================================================================================================== 00043 00044 void Modifier::open( std::string filename ) 00045 { 00046 Reader::open( filename ); 00047 00048 initCache( ); 00049 } 00050 00051 //=================================================================================================== 00052 //=================================================================================================== 00053 00054 void Modifier::close( ) 00055 { 00056 m_file.close( ); 00057 } 00058 00059 //=================================================================================================== 00060 //=================================================================================================== 00061 00062 void Modifier::saveChanges( ) 00063 { 00064 std::fstream ofile( m_filename.c_str(), std::ios_base::out | std::ios_base::in | std::ios::binary ); 00065 00066 size_t R = boost::numeric_cast<size_t>( m_header.getMainHeader_readonly().get_num_datarecords( ) ); 00067 00068 for( size_t i=0; i<R; i++ ) 00069 { 00070 if( m_record_changed[i] ) 00071 { 00072 ofile.seekp( m_record_offset + m_record_length * i ); 00073 ofile << *m_record_cache[i]; 00074 } 00075 } 00076 00077 if( m_events_changed ) 00078 { 00079 ofile.seekp( m_event_offset ); 00080 m_events->toStream( ofile ); 00081 } 00082 00083 ofile.close( ); 00084 } 00085 00086 //=================================================================================================== 00087 //=================================================================================================== 00088 00089 void Modifier::initCache( ) 00090 { 00091 Reader::initCache( ); 00092 m_record_changed.resize( boost::numeric_cast<size_t>( m_header.getMainHeader_readonly().get_num_datarecords() ), false ); 00093 } 00094 00095 //=================================================================================================== 00096 //=================================================================================================== 00097 00098 void Modifier::resetCache( ) 00099 { 00100 00101 for( size_t i=0; i<m_record_cache.size(); i++ ) 00102 { 00103 if( m_record_cache[i] != NULL ) 00104 { 00105 delete m_record_cache[i]; 00106 m_record_cache[i] = NULL; 00107 m_record_changed[i] = NULL; 00108 } 00109 } 00110 } 00111 00112 //=================================================================================================== 00113 //=================================================================================================== 00114 00115 double Modifier::getSample( uint16 channel_idx, size_t sample_idx ) 00116 { 00117 Record *r = getRecordPtr( findRecord( channel_idx, sample_idx ) ); 00118 size_t spr = m_header.getSignalHeader_readonly( channel_idx ).get_samples_per_record( ); 00119 return r->getChannel( channel_idx )->getSamplePhys( sample_idx % spr ); 00120 } 00121 00122 //=================================================================================================== 00123 //=================================================================================================== 00124 00125 void Modifier::setSample( uint16 channel_idx, size_t sample_idx, double value ) 00126 { 00127 size_t record = findRecord( channel_idx, sample_idx ); 00128 Record *r = getRecordPtr( record ); 00129 size_t spr = m_header.getSignalHeader_readonly( channel_idx ).get_samples_per_record( ); 00130 r->getChannel( channel_idx )->setSamplePhys( sample_idx % spr, value ); 00131 m_record_changed[record] = true; 00132 } 00133 00134 //=================================================================================================== 00135 //=================================================================================================== 00136 00137 EventHeader *Modifier::getEventHeader( ) 00138 { 00139 if( m_events == NULL ) 00140 { 00141 if( m_file.is_open() ) 00142 { 00143 m_events = new EventHeader( ); 00144 m_file.seekg( m_event_offset ); 00145 readEvents( ); 00146 } 00147 else 00148 throw exception::file_not_open( "when attempting to read events" ); 00149 } 00150 m_events_changed = true; 00151 return m_events; 00152 } 00153 00154 //=================================================================================================== 00155 //=================================================================================================== 00156 00157 const EventHeader *Modifier::getEventHeader_readonly( ) 00158 { 00159 if( m_events == NULL ) 00160 { 00161 if( m_file.is_open() ) 00162 { 00163 m_events = new EventHeader( ); 00164 m_file.seekg( m_event_offset ); 00165 readEvents( ); 00166 } 00167 else 00168 throw exception::file_not_open( "when attempting to read events" ); 00169 } 00170 return m_events; 00171 } 00172 }