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