1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef ADC_CPP_CALLF_HXX 29 #define ADC_CPP_CALLF_HXX 30 31 // USED SERVICES 32 33 34 35 36 /** This represents a function to be called, if a specific kind of token 37 arrives in the semantic parser. 38 39 @descr This class is only to be used as member of PeStatus<PE>. 40 @template PE 41 The owning ParseEnvironment. 42 @see PeStatus, ParseEnvironment 43 */ 44 template <class PE> 45 class CallFunction 46 { 47 public: 48 typedef void (PE::*F_Tok)(const char *); 49 50 CallFunction( 51 F_Tok i_f2Call, 52 INT16 i_nTokType ); 53 54 F_Tok GetF() const; 55 INT16 TokType() const; 56 57 private: 58 // DATA 59 F_Tok f2Call; 60 INT16 nTokType; 61 }; 62 63 64 /** One state within a ParseEnvironment. 65 66 @template PE 67 The owning ParseEnvironment. 68 */ 69 template <class PE> 70 class PeStatus 71 { 72 public: 73 typedef typename CallFunction<PE>::F_Tok F_Tok; 74 75 PeStatus( 76 PE & i_rMyPE, 77 uintt i_nSize, 78 F_Tok * i_pFuncArray, 79 INT16 * i_pTokTypeArray, 80 F_Tok i_pDefault ); 81 virtual ~PeStatus(); 82 83 virtual void Call_Handler( 84 INT16 i_nTokTypeId, 85 const char * i_sTokenText ) const; 86 87 private: 88 bool CheckForCall( 89 uintt i_nPos, 90 INT16 i_nTokTypeId, 91 const char * i_sTokenText ) const; 92 93 PE * pMyPE; 94 std::vector< CallFunction<PE> > 95 aBranches; 96 F_Tok fDefault; 97 }; 98 99 100 template <class PE> 101 class PeStatusArray 102 { 103 public: 104 typedef typename PE::E_State State; 105 106 PeStatusArray(); 107 void InsertState( 108 State i_ePosition, 109 DYN PeStatus<PE> & let_drState ); 110 ~PeStatusArray(); 111 112 const PeStatus<PE> & 113 operator[]( 114 State i_ePosition ) const; 115 116 void SetCur( 117 State i_eCurState ); 118 const PeStatus<PE> & 119 Cur() const; 120 121 private: 122 DYN PeStatus<PE> * aStati[PE::size_of_states]; 123 State eState; 124 }; 125 126 127 128 // IMPLEMENTATION 129 130 131 // CallFunction 132 133 template <class PE> 134 CallFunction<PE>::CallFunction( F_Tok i_f2Call, 135 INT16 i_nTokType ) 136 : f2Call(i_f2Call), 137 nTokType(i_nTokType) 138 { 139 } 140 141 template <class PE> 142 inline typename CallFunction<PE>::F_Tok 143 CallFunction<PE>::GetF() const 144 { 145 return f2Call; 146 } 147 148 template <class PE> 149 inline INT16 150 CallFunction<PE>::TokType() const 151 { 152 return nTokType; 153 } 154 155 156 157 // PeStatus 158 159 template <class PE> 160 PeStatus<PE>::PeStatus( PE & i_rMyPE, 161 uintt i_nSize, 162 F_Tok * i_pFuncArray, 163 INT16 * i_pTokTypeArray, 164 F_Tok i_fDefault ) 165 : pMyPE(&i_rMyPE), 166 fDefault(i_fDefault) 167 { 168 aBranches.reserve(i_nSize); 169 for ( uintt i = 0; i < i_nSize; ++i ) 170 { 171 // csv_assert(i > 0 ? i_pTokTypeArray[i] > i_pTokTypeArray[i-1] : true); 172 aBranches.push_back( CallFunction<PE>( i_pFuncArray[i], i_pTokTypeArray[i]) ); 173 } // end for 174 } 175 176 template <class PE> 177 PeStatus<PE>::~PeStatus() 178 { 179 180 } 181 182 template <class PE> 183 void 184 PeStatus<PE>::Call_Handler( INT16 i_nTokTypeId, 185 const char * i_sTokenText ) const 186 { 187 uintt nSize = aBranches.size(); 188 uintt nPos = nSize / 2; 189 190 if ( i_nTokTypeId < aBranches[nPos].TokType() ) 191 { 192 for ( --nPos; intt(nPos) >= 0; --nPos ) 193 { 194 if (CheckForCall(nPos, i_nTokTypeId, i_sTokenText)) 195 return; 196 } 197 } 198 else 199 { 200 for ( ; nPos < nSize; ++nPos ) 201 { 202 if (CheckForCall(nPos, i_nTokTypeId, i_sTokenText)) 203 return; 204 } 205 } 206 207 (pMyPE->*fDefault)(i_sTokenText); 208 } 209 210 template <class PE> 211 bool 212 PeStatus<PE>::CheckForCall( uintt i_nPos, 213 INT16 i_nTokTypeId, 214 const char * i_sTokenText ) const 215 { 216 if ( aBranches[i_nPos].TokType() == i_nTokTypeId ) 217 { 218 (pMyPE->*aBranches[i_nPos].GetF())(i_sTokenText); 219 return true; 220 } 221 return false; 222 } 223 224 // PeStatusArray 225 226 template <class PE> 227 PeStatusArray<PE>::PeStatusArray() 228 : eState(PE::size_of_states) 229 { 230 memset(aStati, 0, sizeof aStati); 231 } 232 233 template <class PE> 234 void 235 PeStatusArray<PE>::InsertState( State i_ePosition, 236 DYN PeStatus<PE> & let_drState ) 237 { 238 csv_assert(aStati[i_ePosition] == 0); 239 aStati[i_ePosition] = &let_drState; 240 } 241 242 template <class PE> 243 PeStatusArray<PE>::~PeStatusArray() 244 { 245 int i_max = PE::size_of_states; 246 for (int i = 0; i < i_max; i++) 247 { 248 delete aStati[i]; 249 } // end for 250 } 251 252 template <class PE> 253 inline const PeStatus<PE> & 254 PeStatusArray<PE>::operator[]( State i_ePosition ) const 255 { 256 csv_assert( uintt(i_ePosition) < PE::size_of_states ); 257 csv_assert( aStati[i_ePosition] != 0 ); 258 return *aStati[i_ePosition]; 259 } 260 261 template <class PE> 262 inline void 263 PeStatusArray<PE>::SetCur( State i_eCurState ) 264 { 265 eState = i_eCurState; 266 } 267 268 269 template <class PE> 270 const PeStatus<PE> & 271 PeStatusArray<PE>::Cur() const 272 { 273 return (*this)[eState]; 274 } 275 276 #define SEMPARSE_CREATE_STATUS(penv, state, default_function) \ 277 pStati->InsertState( state, \ 278 *new PeStatus<penv>( \ 279 *this, \ 280 sizeof( stateT_##state ) / sizeof (INT16), \ 281 stateF_##state, \ 282 stateT_##state, \ 283 &penv::default_function ) ) 284 285 286 #endif 287 288