1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 #include <precomp.h>
23 #include <s2_luidl/pe_type2.hxx>
24
25
26 // NOT FULLY DEFINED SERVICES
27 #include <ary/idl/i_gate.hxx>
28 #include <ary/idl/i_type.hxx>
29 #include <ary/idl/ip_type.hxx>
30 #include <ary/doc/d_oldidldocu.hxx>
31 #include <s2_luidl/uidl_tok.hxx>
32 #include <s2_luidl/tk_ident.hxx>
33 #include <s2_luidl/tk_keyw.hxx>
34 #include <s2_luidl/tk_punct.hxx>
35
36
37
38 /** Implementation Concept for Parsing a Type
39
40 Example Type:
41 sequence < ::abc::TName< TplType > > AnyName;
42
43 Status Changes:
44
45 expect_type:
46 sequence -> expect_type
47 < -> expect_type
48 :: -> expect_quname_part
49 abc -> expect_quname_separator
50 :: -> expect_quname_part
51 TName -> expect_quname_separator
52 < -> in_template_type (process in nested PE_Type instance)
53
54 expect_type:
55 TplType ->expect_quname_separator
56 > -> e_none (finish, '>' not handled)
57
58 > -> expect_quname_separator
59 > -> expect_quname_separator (not finish, because sequencecounter > 0)
60 AnyName -> e_none (finish)
61 */
62
63
64 namespace csi
65 {
66 namespace uidl
67 {
68
69
PE_Type(ary::idl::Type_id & o_rResult)70 PE_Type::PE_Type( ary::idl::Type_id & o_rResult )
71 : pResult(&o_rResult),
72 nIsSequenceCounter(0),
73 nSequenceDownCounter(0),
74 bIsUnsigned(false),
75 sFullType(),
76 eState(e_none),
77 sLastPart(),
78 pPE_TemplateType(0), // @attention Recursion, only initiate, if needed!
79 nTemplateType(0),
80 aTemplateParameters()
81 {
82 }
83
~PE_Type()84 PE_Type::~PE_Type()
85 {
86 }
87
88 void
ProcessToken(const Token & i_rToken)89 PE_Type::ProcessToken( const Token & i_rToken )
90 {
91 i_rToken.Trigger(*this);
92 }
93
94 void
Process_Identifier(const TokIdentifier & i_rToken)95 PE_Type::Process_Identifier( const TokIdentifier & i_rToken )
96 {
97 if (eState == expect_type)
98 {
99 sLastPart = i_rToken.Text();
100 eState = expect_quname_separator;
101 SetResult(done, stay);
102 }
103 else if (eState == expect_quname_part)
104 {
105 sLastPart = i_rToken.Text();
106 eState = expect_quname_separator;
107 SetResult(done, stay);
108 }
109 else if (eState == expect_quname_separator)
110 {
111 Finish();
112 }
113 }
114
115 void
Process_NameSeparator()116 PE_Type::Process_NameSeparator()
117 {
118 if (eState == expect_type)
119 {
120 sFullType.Init(true);
121 eState = expect_quname_part;
122 SetResult(done, stay);
123 }
124 else if (eState == expect_quname_separator)
125 {
126 sFullType += sLastPart;
127 eState = expect_quname_part;
128 SetResult(done, stay);
129 }
130 }
131
132 void
Process_Punctuation(const TokPunctuation & i_rToken)133 PE_Type::Process_Punctuation( const TokPunctuation & i_rToken )
134 {
135 if (eState == expect_type)
136 {
137 csv_assert(i_rToken.Id() == TokPunctuation::Lesser);
138 SetResult(done, stay);
139 }
140 else if (eState == expect_quname_separator)
141 {
142 switch (i_rToken.Id())
143 {
144 case TokPunctuation::Lesser:
145 eState = in_template_type;
146 SetResult( done, push_sure, &MyTemplateType() );
147 break;
148
149 case TokPunctuation::Greater:
150 if (nSequenceDownCounter > 0)
151 {
152 nSequenceDownCounter--;
153 SetResult(done, stay);
154 }
155 else
156 {
157 Finish();
158 }
159 break;
160
161 default:
162 Finish();
163 } // end switch
164 }
165 else if (eState == in_template_type)
166 {
167 aTemplateParameters.push_back(nTemplateType);
168 nTemplateType = 0;
169
170 if (i_rToken.Id() == TokPunctuation::Greater)
171 {
172 eState = expect_quname_separator;
173 SetResult(done, stay);
174 }
175 else if (i_rToken.Id() == TokPunctuation::Comma)
176 {
177 SetResult(done, push_sure, &MyTemplateType());
178 }
179 else
180 {
181 csv_assert(false);
182 Finish();
183 }
184 }
185 }
186
187 void
Process_BuiltInType(const TokBuiltInType & i_rToken)188 PE_Type::Process_BuiltInType( const TokBuiltInType & i_rToken )
189 {
190 if (eState == expect_type)
191 {
192 sLastPart = i_rToken.Text();
193 eState = expect_quname_separator;
194 SetResult(done, stay);
195 }
196 else if (eState == expect_quname_part)
197 {
198 // Can this happen?
199
200 sLastPart = i_rToken.Text();
201 eState = expect_quname_separator;
202 SetResult(done, stay);
203 }
204 else if (eState == expect_quname_separator)
205 {
206 // Can this happen?
207
208 Finish();
209 }
210 }
211
212 void
Process_TypeModifier(const TokTypeModifier & i_rToken)213 PE_Type::Process_TypeModifier( const TokTypeModifier & i_rToken )
214 {
215 if (eState == expect_type)
216 {
217 switch ( i_rToken.Id() )
218 {
219 case TokTypeModifier::tmod_unsigned:
220 bIsUnsigned = true;
221 break;
222 case TokTypeModifier::tmod_sequence:
223 nIsSequenceCounter++;
224 nSequenceDownCounter++;
225 break;
226 default:
227 csv_assert(false);
228 }
229 SetResult(done, stay);
230 }
231 else if (eState == expect_quname_separator)
232 {
233 // Can this happen?
234
235 Finish();
236 }
237 }
238
239 void
Process_Default()240 PE_Type::Process_Default()
241 {
242 Finish();
243 }
244
245 void
Finish()246 PE_Type::Finish()
247 {
248 csv_assert(nSequenceDownCounter == 0);
249
250 sFullType.SetLocalName(sLastPart);
251 SetResult(not_done, pop_success);
252 }
253
254 PE_Type &
MyTemplateType()255 PE_Type::MyTemplateType()
256 {
257 if (NOT pPE_TemplateType)
258 {
259 pPE_TemplateType = new PE_Type(nTemplateType);
260 pPE_TemplateType->EstablishContacts( this,
261 MyRepository(),
262 TokenResult() );
263 }
264 return *pPE_TemplateType;
265 }
266
267 void
InitData()268 PE_Type::InitData()
269 {
270 eState = expect_type;
271
272 nIsSequenceCounter = 0;
273 nSequenceDownCounter = 0;
274 bIsUnsigned = false;
275 sFullType.Empty();
276 sLastPart.clear();
277 nTemplateType = 0;
278 csv::erase_container(aTemplateParameters);
279 }
280
281 void
TransferData()282 PE_Type::TransferData()
283 {
284 if (bIsUnsigned)
285 {
286 StreamLock sl(40);
287 String sName( sl() << "unsigned " << sFullType.LocalName() << c_str );
288 sFullType.SetLocalName(sName);
289 }
290
291 const ary::idl::Type &
292 result = Gate().Types().CheckIn_Type( sFullType,
293 nIsSequenceCounter,
294 CurNamespace().CeId(),
295 &aTemplateParameters );
296 *pResult = result.TypeId();
297 eState = e_none;
298 }
299
300 UnoIDL_PE &
MyPE()301 PE_Type::MyPE()
302 {
303 return *this;
304 }
305
306
307 } // namespace uidl
308 } // namespace csi
309