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 #include <precomp.h>
29 #include <s2_luidl/pe_struc.hxx>
30 
31 
32 // NOT FULLY DECLARED SERVICES
33 #include <ary/idl/i_gate.hxx>
34 #include <ary/idl/i_struct.hxx>
35 #include <ary/idl/ip_ce.hxx>
36 #include <ary/doc/d_oldidldocu.hxx>
37 #include <s2_luidl/tk_ident.hxx>
38 #include <s2_luidl/tk_punct.hxx>
39 #include <s2_luidl/tk_keyw.hxx>
40 #include <s2_luidl/pe_type2.hxx>
41 #include <s2_luidl/pe_selem.hxx>
42 
43 
44 
45 namespace csi
46 {
47 namespace uidl
48 {
49 
50 
51 PE_Struct::PE_Struct()
52     // :    aWork,
53     //      pStati
54 {
55     pStati = new S_Stati(*this);
56 }
57 
58 void
59 PE_Struct::EstablishContacts( UnoIDL_PE *               io_pParentPE,
60                               ary::Repository &			io_rRepository,
61                               TokenProcessing_Result & 	o_rResult )
62 {
63     UnoIDL_PE::EstablishContacts(io_pParentPE,io_rRepository,o_rResult);
64     Work().pPE_Element->EstablishContacts(this,io_rRepository,o_rResult);
65     Work().pPE_Type->EstablishContacts(this,io_rRepository,o_rResult);
66 }
67 
68 PE_Struct::~PE_Struct()
69 {
70 }
71 
72 void
73 PE_Struct::ProcessToken( const Token & i_rToken )
74 {
75     i_rToken.Trigger(*Stati().pCurStatus);
76 }
77 
78 
79 void
80 PE_Struct::InitData()
81 {
82     Work().InitData();
83     Stati().pCurStatus = &Stati().aWaitForName;
84 }
85 
86 void
87 PE_Struct::TransferData()
88 {
89     if (NOT Work().bIsPreDeclaration)
90     {
91         csv_assert(Work().sData_Name.size() > 0);
92         csv_assert(Work().nCurStruct.IsValid());
93     }
94     Stati().pCurStatus = &Stati().aNone;
95 }
96 
97 void
98 PE_Struct::ReceiveData()
99 {
100     Stati().pCurStatus->On_SubPE_Left();
101 }
102 
103 PE_Struct::S_Work::S_Work()
104     :   sData_Name(),
105         sData_TemplateParam(),
106         bIsPreDeclaration(false),
107         nCurStruct(0),
108         pPE_Element(0),
109         nCurParsed_ElementRef(0),
110         pPE_Type(0),
111         nCurParsed_Base(0)
112 
113 {
114     pPE_Element = new PE_StructElement(nCurParsed_ElementRef,nCurStruct,sData_TemplateParam);
115     pPE_Type = new PE_Type(nCurParsed_Base);
116 }
117 
118 void
119 PE_Struct::S_Work::InitData()
120 {
121     sData_Name.clear();
122     sData_TemplateParam.clear();
123     bIsPreDeclaration = false;
124     nCurStruct = 0;
125     nCurParsed_ElementRef = 0;
126     nCurParsed_Base = 0;
127 }
128 
129 void
130 PE_Struct::S_Work::Prepare_PE_QualifiedName()
131 {
132     nCurParsed_ElementRef = 0;
133 }
134 
135 void
136 PE_Struct::S_Work::Prepare_PE_Element()
137 {
138     nCurParsed_Base = 0;
139 }
140 
141 void
142 PE_Struct::S_Work::Data_Set_Name( const char * i_sName )
143 {
144     sData_Name = i_sName;
145 }
146 
147 void
148 PE_Struct::S_Work::Data_Set_TemplateParam( const char * i_sTemplateParam )
149 {
150     sData_TemplateParam = i_sTemplateParam;
151 }
152 
153 PE_Struct::S_Stati::S_Stati(PE_Struct & io_rStruct)
154     :   aNone(io_rStruct),
155         aWaitForName(io_rStruct),
156         aGotName(io_rStruct),
157         aWaitForTemplateParam(io_rStruct),
158         aWaitForTemplateEnd(io_rStruct),
159         aWaitForBase(io_rStruct),
160         aGotBase(io_rStruct),
161         aWaitForElement(io_rStruct),
162         aWaitForFinish(io_rStruct),
163         pCurStatus(0)
164 {
165     pCurStatus = &aNone;
166 }
167 
168 
169 //***********************       Stati       ***************************//
170 
171 
172 UnoIDL_PE &
173 PE_Struct::PE_StructState::MyPE()
174 {
175     return rStruct;
176 }
177 
178 
179 void
180 PE_Struct::State_WaitForName::Process_Identifier( const TokIdentifier & i_rToken )
181 {
182     Work().Data_Set_Name(i_rToken.Text());
183     MoveState( Stati().aGotName );
184     SetResult(done,stay);
185 }
186 
187 void
188 PE_Struct::State_GotName::Process_Punctuation( const TokPunctuation & i_rToken )
189 {
190     if ( i_rToken.Id() != TokPunctuation::Semicolon )
191     {
192         switch (i_rToken.Id())
193     	{
194             case TokPunctuation::Colon:
195                 MoveState( Stati().aWaitForBase );
196                 SetResult(done,push_sure,Work().pPE_Type.Ptr());
197                 Work().Prepare_PE_QualifiedName();
198             	break;
199             case TokPunctuation::CurledBracketOpen:
200                 PE().store_Struct();
201                 MoveState( Stati().aWaitForElement );
202                 SetResult(done,stay);
203             	break;
204             case TokPunctuation::Lesser:
205                 MoveState( Stati().aWaitForTemplateParam );
206                 SetResult(done,stay);
207             	break;
208             default:
209                 SetResult(not_done,pop_failure);
210         }   // end switch
211     }
212     else
213     {
214         Work().sData_Name.clear();
215         SetResult(done,pop_success);
216     }
217 }
218 
219 void
220 PE_Struct::State_WaitForTemplateParam::Process_Identifier( const TokIdentifier & i_rToken )
221 {
222     Work().Data_Set_TemplateParam(i_rToken.Text());
223     MoveState( Stati().aWaitForTemplateEnd );
224     SetResult(done,stay);
225 }
226 
227 void
228 PE_Struct::State_WaitForTemplateEnd::Process_Punctuation( const TokPunctuation & )
229 {
230     // Assume:  TokPunctuation::Greater
231     MoveState( Stati().aGotName );
232     SetResult(done,stay);
233 }
234 
235 void
236 PE_Struct::State_WaitForBase::On_SubPE_Left()
237 {
238     MoveState(Stati().aGotBase);
239 }
240 
241 void
242 PE_Struct::State_GotBase::Process_Punctuation( const TokPunctuation & i_rToken )
243 {
244     if ( i_rToken.Id() == TokPunctuation::CurledBracketOpen )
245     {
246         PE().store_Struct();
247         MoveState( Stati().aWaitForElement );
248         SetResult(done,stay);
249     }
250     else
251     {
252         SetResult(not_done,pop_failure);
253     }
254 }
255 
256 void
257 PE_Struct::State_WaitForElement::Process_Identifier( const TokIdentifier & )
258 {
259     SetResult( not_done, push_sure, Work().pPE_Element.Ptr() );
260     Work().Prepare_PE_Element();
261 }
262 
263 void
264 PE_Struct::State_WaitForElement::Process_NameSeparator()
265 {
266     SetResult( not_done, push_sure, Work().pPE_Element.Ptr());
267     Work().Prepare_PE_Element();
268 }
269 
270 void
271 PE_Struct::State_WaitForElement::Process_BuiltInType( const TokBuiltInType & )
272 {
273     SetResult( not_done, push_sure, Work().pPE_Element.Ptr());
274     Work().Prepare_PE_Element();
275 }
276 
277 void
278 PE_Struct::State_WaitForElement::Process_TypeModifier(const TokTypeModifier & )
279 {
280     SetResult( not_done, push_sure, Work().pPE_Element.Ptr());
281     Work().Prepare_PE_Element();
282 }
283 
284 void
285 PE_Struct::State_WaitForElement::Process_Punctuation( const TokPunctuation & i_rToken )
286 {
287     if ( i_rToken.Id() == TokPunctuation::CurledBracketClose )
288     {
289         MoveState( Stati().aWaitForFinish );
290         SetResult( done, stay );
291     }
292     else
293     {
294         SetResult( not_done, pop_failure );
295     }
296 }
297 
298 void
299 PE_Struct::State_WaitForFinish::Process_Punctuation( const TokPunctuation & i_rToken )
300 {
301     if (i_rToken.Id() == TokPunctuation::Semicolon)
302     {
303         MoveState( Stati().aNone );
304         SetResult( done, pop_success );
305     }
306     else
307     {
308         SetResult( not_done, pop_failure );
309     }
310 }
311 
312 void
313 PE_Struct::store_Struct()
314 {
315     ary::idl::Struct &
316         rCe = Gate().Ces().Store_Struct(
317                         CurNamespace().CeId(),
318                         Work().sData_Name,
319                         Work().nCurParsed_Base,
320                         Work().sData_TemplateParam );
321     PassDocuAt(rCe);
322     Work().nCurStruct = rCe.CeId();
323 }
324 
325 
326 }   // namespace uidl
327 }   // namespace csi
328