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