CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #ifndef _Extractor_hxx_ 00023 #define _Extractor_hxx_ 00024 00025 #include <string> 00026 #include "Pool.hxx" 00027 00028 namespace CLAM 00029 { 00030 00032 template <typename AttributeType> 00033 class Hook 00034 { 00035 public: 00036 virtual ~Hook(){} 00037 void Bind( 00038 const std::string & scope, 00039 const std::string & attribute) 00040 { 00041 _scope = scope; 00042 _attribute = attribute; 00043 } 00044 00045 virtual void Next() = 0; 00046 virtual bool IsInsideScope() const = 0; 00047 00048 protected: 00049 const std::string GetScope() const 00050 { 00051 return _scope; 00052 } 00053 std::string _attribute; 00054 std::string _scope; 00055 }; 00056 00058 template <typename AttributeType> 00059 class ReadHook : public Hook<AttributeType> 00060 { 00061 public: 00062 ReadHook() 00063 { 00064 _chained=0; 00065 } 00066 ~ReadHook() 00067 { 00068 if (_chained) delete _chained; 00069 } 00070 ReadHook & Bind( 00071 const std::string & scope, 00072 const std::string & attribute) 00073 { 00074 Hook<AttributeType>::Bind(scope,attribute); 00075 return *this; 00076 } 00077 ReadHook & Indirect( 00078 const std::string & scope, 00079 const std::string & attribute) 00080 { 00081 if (_chained) 00082 { 00083 _chained->Indirect(scope,attribute); 00084 } 00085 else 00086 { 00087 _chained = new ReadHook<unsigned>; 00088 _chained->Bind(scope,attribute); 00089 } 00090 return *this; 00091 } 00092 00093 const AttributeType & GetForReading() const 00094 { 00095 return _data [GetCurrent()]; 00096 } 00097 00098 void Init(const DescriptionDataPool & pool) 00099 { 00100 _current = 0; 00101 _pool = &pool; 00102 const std::string & scope = Hook<AttributeType>::_scope; 00103 const std::string & attribute = Hook<AttributeType>::_attribute; 00104 _data = _pool->template GetReadPool<AttributeType>(scope,attribute); 00105 if (_chained) _chained->Init(pool); 00106 } 00107 00108 virtual void Next() 00109 { 00110 if (_chained) _chained->Next(); 00111 else _current++; 00112 } 00113 00114 virtual bool IsInsideScope() const 00115 { 00116 if (_chained) return _chained->IsInsideScope(); 00117 const std::string & scope = Hook<AttributeType>::_scope; 00118 return _current < _pool->GetNumberOfContexts(scope); 00119 } 00120 00121 protected: 00122 virtual unsigned GetCurrent() const 00123 { 00124 if (!_chained) return _current; 00125 00126 unsigned indirection = _chained->GetForReading(); 00127 const std::string & scope = Hook<AttributeType>::_scope; 00128 CLAM_ASSERT(indirection<_pool->GetNumberOfContexts(scope), 00129 "Invalid cross-scope reference"); 00130 return indirection; 00131 } 00132 00133 protected: 00134 const DescriptionDataPool * _pool; 00135 const AttributeType * _data; 00136 ReadHook<unsigned> * _chained; 00137 private: 00138 unsigned _current; 00139 }; 00140 00142 template <typename AttributeType> 00143 class ReadRangedHook : public ReadHook<AttributeType> 00144 { 00145 public: 00146 void GetRangeForReading( 00147 const AttributeType*& begin, 00148 const AttributeType*& end) const 00149 { 00150 begin = & (ReadHook<AttributeType>::GetForReading()); 00151 end = begin + _range; 00152 } 00153 00154 ReadHook<AttributeType> & Range(unsigned range) 00155 { 00156 _range = range; 00157 return *this; 00158 } 00159 private: 00160 unsigned _range; 00161 }; 00162 00164 template <typename AttributeType> 00165 class WriteHook : public Hook<AttributeType> 00166 { 00167 public: 00168 void Init(DescriptionDataPool & pool) 00169 { 00170 _pool = &pool; 00171 _current = 0; 00172 const std::string & scope = Hook<AttributeType>::_scope; 00173 const std::string & attribute = Hook<AttributeType>::_attribute; 00174 _data = _pool->template GetWritePool<AttributeType>(scope,attribute); 00175 } 00176 00177 AttributeType & GetForWriting() const 00178 { 00179 return _data [GetCurrent()]; 00180 } 00181 00182 virtual void Next() 00183 { 00184 _current++; 00185 } 00186 00187 virtual bool IsInsideScope() const 00188 { 00189 const std::string & scope = Hook<AttributeType>::_scope; 00190 return _current < _pool->GetNumberOfContexts(scope); 00191 } 00192 00193 protected: 00194 unsigned GetCurrent() const 00195 { 00196 return _current; 00197 } 00198 private: 00199 DescriptionDataPool * _pool; 00200 AttributeType * _data; 00201 unsigned _current; 00202 }; 00203 00204 } 00205 00206 00207 00208 00209 00210 #endif // _Extractor_hxx_ 00211