1*8a106958SDamjan Jovanovic /**************************************************************
2*8a106958SDamjan Jovanovic *
3*8a106958SDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one
4*8a106958SDamjan Jovanovic * or more contributor license agreements. See the NOTICE file
5*8a106958SDamjan Jovanovic * distributed with this work for additional information
6*8a106958SDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file
7*8a106958SDamjan Jovanovic * to you under the Apache License, Version 2.0 (the
8*8a106958SDamjan Jovanovic * "License"); you may not use this file except in compliance
9*8a106958SDamjan Jovanovic * with the License. You may obtain a copy of the License at
10*8a106958SDamjan Jovanovic *
11*8a106958SDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0
12*8a106958SDamjan Jovanovic *
13*8a106958SDamjan Jovanovic * Unless required by applicable law or agreed to in writing,
14*8a106958SDamjan Jovanovic * software distributed under the License is distributed on an
15*8a106958SDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*8a106958SDamjan Jovanovic * KIND, either express or implied. See the License for the
17*8a106958SDamjan Jovanovic * specific language governing permissions and limitations
18*8a106958SDamjan Jovanovic * under the License.
19*8a106958SDamjan Jovanovic *
20*8a106958SDamjan Jovanovic *************************************************************/
21*8a106958SDamjan Jovanovic
22*8a106958SDamjan Jovanovic
23*8a106958SDamjan Jovanovic
24*8a106958SDamjan Jovanovic #ifndef CSI_XML_XMLITEM_HXX
25*8a106958SDamjan Jovanovic #define CSI_XML_XMLITEM_HXX
26*8a106958SDamjan Jovanovic
27*8a106958SDamjan Jovanovic // USED SERVICES
28*8a106958SDamjan Jovanovic // BASE CLASSES
29*8a106958SDamjan Jovanovic // COMPONENTS
30*8a106958SDamjan Jovanovic #include <cosv/tpl/swelist.hxx>
31*8a106958SDamjan Jovanovic #include <cosv/tpl/dyn.hxx>
32*8a106958SDamjan Jovanovic // PARAMETERS
33*8a106958SDamjan Jovanovic
34*8a106958SDamjan Jovanovic namespace csv
35*8a106958SDamjan Jovanovic {
36*8a106958SDamjan Jovanovic class bostream;
37*8a106958SDamjan Jovanovic }
38*8a106958SDamjan Jovanovic
39*8a106958SDamjan Jovanovic
40*8a106958SDamjan Jovanovic namespace csi
41*8a106958SDamjan Jovanovic {
42*8a106958SDamjan Jovanovic namespace xml
43*8a106958SDamjan Jovanovic {
44*8a106958SDamjan Jovanovic
45*8a106958SDamjan Jovanovic
46*8a106958SDamjan Jovanovic /* Basics:
47*8a106958SDamjan Jovanovic Item, Attribute, Element, TextContext
48*8a106958SDamjan Jovanovic */
49*8a106958SDamjan Jovanovic
50*8a106958SDamjan Jovanovic class Item
51*8a106958SDamjan Jovanovic {
52*8a106958SDamjan Jovanovic public:
~Item()53*8a106958SDamjan Jovanovic virtual ~Item() {}
54*8a106958SDamjan Jovanovic void WriteOut(
55*8a106958SDamjan Jovanovic csv::bostream & io_aFile ) const;
56*8a106958SDamjan Jovanovic private:
57*8a106958SDamjan Jovanovic virtual void do_WriteOut(
58*8a106958SDamjan Jovanovic csv::bostream & io_aFile ) const = 0;
59*8a106958SDamjan Jovanovic };
60*8a106958SDamjan Jovanovic
61*8a106958SDamjan Jovanovic typedef csv::SweList_dyn< Item > ItemList;
62*8a106958SDamjan Jovanovic
63*8a106958SDamjan Jovanovic class Attribute
64*8a106958SDamjan Jovanovic {
65*8a106958SDamjan Jovanovic public:
~Attribute()66*8a106958SDamjan Jovanovic virtual ~Attribute() {}
67*8a106958SDamjan Jovanovic
68*8a106958SDamjan Jovanovic void WriteOut(
69*8a106958SDamjan Jovanovic csv::bostream & io_aFile ) const;
70*8a106958SDamjan Jovanovic
71*8a106958SDamjan Jovanovic const ::csv::String& Name() const;
72*8a106958SDamjan Jovanovic const ::csv::String& Value() const;
73*8a106958SDamjan Jovanovic
74*8a106958SDamjan Jovanovic private:
75*8a106958SDamjan Jovanovic virtual const ::csv::String &
76*8a106958SDamjan Jovanovic inq_Name() const = 0;
77*8a106958SDamjan Jovanovic virtual const ::csv::String &
78*8a106958SDamjan Jovanovic inq_Value() const = 0;
79*8a106958SDamjan Jovanovic };
80*8a106958SDamjan Jovanovic
81*8a106958SDamjan Jovanovic typedef csv::SweList_dyn< Attribute > AttrList;
82*8a106958SDamjan Jovanovic
83*8a106958SDamjan Jovanovic
84*8a106958SDamjan Jovanovic class Element : public Item
85*8a106958SDamjan Jovanovic {
86*8a106958SDamjan Jovanovic public:
87*8a106958SDamjan Jovanovic Element & operator<<( /// For multiple content items.
88*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
89*8a106958SDamjan Jovanovic Element & operator<<( /// For multiple content items.
90*8a106958SDamjan Jovanovic const ::csv::String& let_drText );
91*8a106958SDamjan Jovanovic Element & operator<<( /// For multiple content items.
92*8a106958SDamjan Jovanovic const char * let_dpText );
93*8a106958SDamjan Jovanovic Element & operator<<(
94*8a106958SDamjan Jovanovic DYN Attribute * let_dpAttr );
95*8a106958SDamjan Jovanovic
96*8a106958SDamjan Jovanovic Element & operator>>( /// For multiple content items. @return the child Element.
97*8a106958SDamjan Jovanovic DYN Element & let_drElement );
98*8a106958SDamjan Jovanovic
99*8a106958SDamjan Jovanovic
100*8a106958SDamjan Jovanovic Item * SetContent( /// For only one content item.
101*8a106958SDamjan Jovanovic DYN Item * let_dpItem ); /// Replaces previous content. May be 0, then all content is deleted.
102*8a106958SDamjan Jovanovic private:
103*8a106958SDamjan Jovanovic // Interface Item:
104*8a106958SDamjan Jovanovic virtual void do_WriteOut(
105*8a106958SDamjan Jovanovic csv::bostream & io_aFile ) const;
106*8a106958SDamjan Jovanovic // Local
107*8a106958SDamjan Jovanovic virtual void op_streamout(
108*8a106958SDamjan Jovanovic DYN Item * let_dpItem ) = 0;
109*8a106958SDamjan Jovanovic virtual void op_streamout(
110*8a106958SDamjan Jovanovic DYN Attribute * let_dpAttr ) = 0;
111*8a106958SDamjan Jovanovic
112*8a106958SDamjan Jovanovic virtual void do_SetContent(
113*8a106958SDamjan Jovanovic DYN Item * let_dpItem ) = 0;
114*8a106958SDamjan Jovanovic // Helpers
115*8a106958SDamjan Jovanovic virtual const ::csv::String &
116*8a106958SDamjan Jovanovic inq_TagName() const = 0;
117*8a106958SDamjan Jovanovic virtual const Item *
118*8a106958SDamjan Jovanovic inq_Content() const = 0;
119*8a106958SDamjan Jovanovic virtual const AttrList *
120*8a106958SDamjan Jovanovic inq_Attrs() const = 0;
121*8a106958SDamjan Jovanovic
122*8a106958SDamjan Jovanovic virtual bool FinishEmptyTag_XmlStyle() const; /// Defaulted to: true
123*8a106958SDamjan Jovanovic
124*8a106958SDamjan Jovanovic virtual bool LineBreakAfterBeginTag() const; /// Defaulted to: false
125*8a106958SDamjan Jovanovic virtual bool LineBreakAfterEndTag() const; /// Defaulted to: true, if LineBreakAfterBeginTag()
126*8a106958SDamjan Jovanovic };
127*8a106958SDamjan Jovanovic
128*8a106958SDamjan Jovanovic class TextContent : public Item
129*8a106958SDamjan Jovanovic {
130*8a106958SDamjan Jovanovic };
131*8a106958SDamjan Jovanovic
132*8a106958SDamjan Jovanovic
133*8a106958SDamjan Jovanovic /* Implementation simplifiers:
134*8a106958SDamjan Jovanovic EmptyElement, PureElement, SglTag
135*8a106958SDamjan Jovanovic */
136*8a106958SDamjan Jovanovic
137*8a106958SDamjan Jovanovic class EmptyElement : public Element
138*8a106958SDamjan Jovanovic {
139*8a106958SDamjan Jovanovic private:
140*8a106958SDamjan Jovanovic // Interface Element:
141*8a106958SDamjan Jovanovic virtual void op_streamout( /// does nothing
142*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
143*8a106958SDamjan Jovanovic virtual void op_streamout(
144*8a106958SDamjan Jovanovic DYN Attribute * let_dpAttr );
145*8a106958SDamjan Jovanovic virtual void do_SetContent( /// does nothing
146*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
147*8a106958SDamjan Jovanovic virtual const Item *
148*8a106958SDamjan Jovanovic inq_Content() const; /// @return 0
149*8a106958SDamjan Jovanovic virtual const AttrList *
150*8a106958SDamjan Jovanovic inq_Attrs() const;
151*8a106958SDamjan Jovanovic
152*8a106958SDamjan Jovanovic // Local
153*8a106958SDamjan Jovanovic virtual AttrList & inq_RefAttrs() = 0;
154*8a106958SDamjan Jovanovic };
155*8a106958SDamjan Jovanovic
156*8a106958SDamjan Jovanovic class PureElement : public Element
157*8a106958SDamjan Jovanovic {
158*8a106958SDamjan Jovanovic private:
159*8a106958SDamjan Jovanovic // Interface Element:
160*8a106958SDamjan Jovanovic virtual void op_streamout(
161*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
162*8a106958SDamjan Jovanovic virtual void op_streamout( /// does nothing
163*8a106958SDamjan Jovanovic DYN Attribute * let_dpAttr );
164*8a106958SDamjan Jovanovic virtual void do_SetContent(
165*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
166*8a106958SDamjan Jovanovic virtual const Item *
167*8a106958SDamjan Jovanovic inq_Content() const;
168*8a106958SDamjan Jovanovic virtual const AttrList *
169*8a106958SDamjan Jovanovic inq_Attrs() const; /// @return 0
170*8a106958SDamjan Jovanovic // Local
171*8a106958SDamjan Jovanovic virtual Dyn< Item > &
172*8a106958SDamjan Jovanovic inq_RefContent() = 0;
173*8a106958SDamjan Jovanovic };
174*8a106958SDamjan Jovanovic
175*8a106958SDamjan Jovanovic class SglTag : public Element
176*8a106958SDamjan Jovanovic {
177*8a106958SDamjan Jovanovic private:
178*8a106958SDamjan Jovanovic // Interface Element:
179*8a106958SDamjan Jovanovic virtual void op_streamout( /// does nothing
180*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
181*8a106958SDamjan Jovanovic virtual void op_streamout( /// does nothing
182*8a106958SDamjan Jovanovic DYN Attribute * let_dpAttr );
183*8a106958SDamjan Jovanovic virtual void do_SetContent( /// does nothing
184*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
185*8a106958SDamjan Jovanovic virtual const Item *
186*8a106958SDamjan Jovanovic inq_Content() const; /// @return 0
187*8a106958SDamjan Jovanovic virtual const AttrList *
188*8a106958SDamjan Jovanovic inq_Attrs() const; /// @return 0
189*8a106958SDamjan Jovanovic };
190*8a106958SDamjan Jovanovic
191*8a106958SDamjan Jovanovic
192*8a106958SDamjan Jovanovic
193*8a106958SDamjan Jovanovic /* Standard Element implementations, if there are not any
194*8a106958SDamjan Jovanovic specialized ones.
195*8a106958SDamjan Jovanovic */
196*8a106958SDamjan Jovanovic
197*8a106958SDamjan Jovanovic class AnElement : public Element
198*8a106958SDamjan Jovanovic {
199*8a106958SDamjan Jovanovic public:
200*8a106958SDamjan Jovanovic AnElement(
201*8a106958SDamjan Jovanovic const ::csv::String& i_sTagName );
202*8a106958SDamjan Jovanovic AnElement(
203*8a106958SDamjan Jovanovic const char * i_sTagName );
204*8a106958SDamjan Jovanovic ~AnElement();
205*8a106958SDamjan Jovanovic private:
206*8a106958SDamjan Jovanovic // Interface Element
207*8a106958SDamjan Jovanovic virtual void op_streamout(
208*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
209*8a106958SDamjan Jovanovic virtual void op_streamout(
210*8a106958SDamjan Jovanovic DYN Attribute * let_dpAttr );
211*8a106958SDamjan Jovanovic virtual void do_SetContent(
212*8a106958SDamjan Jovanovic DYN Item * let_dpItem );
213*8a106958SDamjan Jovanovic virtual const ::csv::String &
214*8a106958SDamjan Jovanovic inq_TagName() const;
215*8a106958SDamjan Jovanovic virtual const Item *
216*8a106958SDamjan Jovanovic inq_Content() const;
217*8a106958SDamjan Jovanovic virtual const AttrList *
218*8a106958SDamjan Jovanovic inq_Attrs() const;
219*8a106958SDamjan Jovanovic // DATA
220*8a106958SDamjan Jovanovic ::csv::String sTagName;
221*8a106958SDamjan Jovanovic Dyn< Item > pContent;
222*8a106958SDamjan Jovanovic AttrList aAttrs;
223*8a106958SDamjan Jovanovic };
224*8a106958SDamjan Jovanovic
225*8a106958SDamjan Jovanovic
226*8a106958SDamjan Jovanovic class AnEmptyElement : public EmptyElement
227*8a106958SDamjan Jovanovic {
228*8a106958SDamjan Jovanovic public:
229*8a106958SDamjan Jovanovic AnEmptyElement(
230*8a106958SDamjan Jovanovic const ::csv::String & i_sTagName );
231*8a106958SDamjan Jovanovic AnEmptyElement(
232*8a106958SDamjan Jovanovic const char * i_sTagName );
233*8a106958SDamjan Jovanovic ~AnEmptyElement();
234*8a106958SDamjan Jovanovic private:
235*8a106958SDamjan Jovanovic // Interface Element:
236*8a106958SDamjan Jovanovic virtual const ::csv::String &
237*8a106958SDamjan Jovanovic inq_TagName() const;
238*8a106958SDamjan Jovanovic // Interface EmptyElement:
239*8a106958SDamjan Jovanovic virtual AttrList & inq_RefAttrs();
240*8a106958SDamjan Jovanovic
241*8a106958SDamjan Jovanovic // DATA
242*8a106958SDamjan Jovanovic ::csv::String sTagName;
243*8a106958SDamjan Jovanovic AttrList aAttrs;
244*8a106958SDamjan Jovanovic };
245*8a106958SDamjan Jovanovic
246*8a106958SDamjan Jovanovic class APureElement : public PureElement
247*8a106958SDamjan Jovanovic {
248*8a106958SDamjan Jovanovic public:
249*8a106958SDamjan Jovanovic APureElement(
250*8a106958SDamjan Jovanovic const ::csv::String & i_sTagName );
251*8a106958SDamjan Jovanovic APureElement(
252*8a106958SDamjan Jovanovic const char * i_sTagName );
253*8a106958SDamjan Jovanovic ~APureElement();
254*8a106958SDamjan Jovanovic private:
255*8a106958SDamjan Jovanovic // Interface Element:
256*8a106958SDamjan Jovanovic virtual const ::csv::String &
257*8a106958SDamjan Jovanovic inq_TagName() const;
258*8a106958SDamjan Jovanovic // Interface PureElement:
259*8a106958SDamjan Jovanovic virtual Dyn< Item > &
260*8a106958SDamjan Jovanovic inq_RefContent();
261*8a106958SDamjan Jovanovic // DATA
262*8a106958SDamjan Jovanovic ::csv::String sTagName;
263*8a106958SDamjan Jovanovic Dyn< Item > pContent;
264*8a106958SDamjan Jovanovic };
265*8a106958SDamjan Jovanovic
266*8a106958SDamjan Jovanovic class ASglTag : public SglTag
267*8a106958SDamjan Jovanovic {
268*8a106958SDamjan Jovanovic public:
269*8a106958SDamjan Jovanovic ASglTag(
270*8a106958SDamjan Jovanovic const ::csv::String & i_sTagName );
271*8a106958SDamjan Jovanovic ASglTag(
272*8a106958SDamjan Jovanovic const char * i_sTagName );
273*8a106958SDamjan Jovanovic ~ASglTag();
274*8a106958SDamjan Jovanovic private:
275*8a106958SDamjan Jovanovic // Interface Element:
276*8a106958SDamjan Jovanovic virtual const ::csv::String &
277*8a106958SDamjan Jovanovic inq_TagName() const;
278*8a106958SDamjan Jovanovic // DATA
279*8a106958SDamjan Jovanovic ::csv::String sTagName;
280*8a106958SDamjan Jovanovic };
281*8a106958SDamjan Jovanovic
282*8a106958SDamjan Jovanovic
283*8a106958SDamjan Jovanovic /* Standard Attribute implementation
284*8a106958SDamjan Jovanovic */
285*8a106958SDamjan Jovanovic class AnAttribute : public Attribute
286*8a106958SDamjan Jovanovic {
287*8a106958SDamjan Jovanovic public:
288*8a106958SDamjan Jovanovic AnAttribute(
289*8a106958SDamjan Jovanovic const ::csv::String & i_sName,
290*8a106958SDamjan Jovanovic const ::csv::String & i_sValue );
291*8a106958SDamjan Jovanovic AnAttribute(
292*8a106958SDamjan Jovanovic const char * i_sName,
293*8a106958SDamjan Jovanovic const char * i_sValue );
294*8a106958SDamjan Jovanovic ~AnAttribute();
295*8a106958SDamjan Jovanovic private:
296*8a106958SDamjan Jovanovic // Interface Attribute:
297*8a106958SDamjan Jovanovic virtual const ::csv::String &
298*8a106958SDamjan Jovanovic inq_Name() const;
299*8a106958SDamjan Jovanovic virtual const ::csv::String &
300*8a106958SDamjan Jovanovic inq_Value() const;
301*8a106958SDamjan Jovanovic // DATA
302*8a106958SDamjan Jovanovic ::csv::String sName;
303*8a106958SDamjan Jovanovic ::csv::String sValue;
304*8a106958SDamjan Jovanovic };
305*8a106958SDamjan Jovanovic
306*8a106958SDamjan Jovanovic
307*8a106958SDamjan Jovanovic
308*8a106958SDamjan Jovanovic /* Implementations of TextContent:
309*8a106958SDamjan Jovanovic
310*8a106958SDamjan Jovanovic Text ( reserved characters will be replaced and appear unchanged )
311*8a106958SDamjan Jovanovic XmlCode ( reserved characters stay and are interpreted
312*8a106958SDamjan Jovanovic by the XML-viewer )
313*8a106958SDamjan Jovanovic */
314*8a106958SDamjan Jovanovic class Text : public TextContent
315*8a106958SDamjan Jovanovic {
316*8a106958SDamjan Jovanovic public:
317*8a106958SDamjan Jovanovic Text(
318*8a106958SDamjan Jovanovic const ::csv::String & i_sText );
319*8a106958SDamjan Jovanovic Text(
320*8a106958SDamjan Jovanovic const char * i_sText );
321*8a106958SDamjan Jovanovic ~Text();
322*8a106958SDamjan Jovanovic private:
323*8a106958SDamjan Jovanovic virtual void do_WriteOut(
324*8a106958SDamjan Jovanovic csv::bostream & io_aFile ) const;
325*8a106958SDamjan Jovanovic // DATA
326*8a106958SDamjan Jovanovic ::csv::String sText;
327*8a106958SDamjan Jovanovic };
328*8a106958SDamjan Jovanovic
329*8a106958SDamjan Jovanovic
330*8a106958SDamjan Jovanovic class XmlCode : public TextContent
331*8a106958SDamjan Jovanovic {
332*8a106958SDamjan Jovanovic public:
333*8a106958SDamjan Jovanovic XmlCode(
334*8a106958SDamjan Jovanovic const ::csv::String & i_sText );
335*8a106958SDamjan Jovanovic XmlCode(
336*8a106958SDamjan Jovanovic const char * i_sText );
337*8a106958SDamjan Jovanovic ~XmlCode();
338*8a106958SDamjan Jovanovic private:
339*8a106958SDamjan Jovanovic virtual void do_WriteOut(
340*8a106958SDamjan Jovanovic csv::bostream & io_aFile ) const;
341*8a106958SDamjan Jovanovic // DATA
342*8a106958SDamjan Jovanovic ::csv::String sText;
343*8a106958SDamjan Jovanovic };
344*8a106958SDamjan Jovanovic
345*8a106958SDamjan Jovanovic
346*8a106958SDamjan Jovanovic
347*8a106958SDamjan Jovanovic // IMPLEMENTATION
348*8a106958SDamjan Jovanovic
349*8a106958SDamjan Jovanovic inline void
WriteOut(csv::bostream & io_aFile) const350*8a106958SDamjan Jovanovic Item::WriteOut( csv::bostream & io_aFile ) const
351*8a106958SDamjan Jovanovic { do_WriteOut(io_aFile); }
352*8a106958SDamjan Jovanovic
353*8a106958SDamjan Jovanovic inline const ::csv::String &
Name() const354*8a106958SDamjan Jovanovic Attribute::Name() const
355*8a106958SDamjan Jovanovic { return inq_Name(); }
356*8a106958SDamjan Jovanovic inline const ::csv::String &
Value() const357*8a106958SDamjan Jovanovic Attribute::Value() const
358*8a106958SDamjan Jovanovic { return inq_Value(); }
359*8a106958SDamjan Jovanovic
360*8a106958SDamjan Jovanovic inline Element &
operator <<(DYN Item * let_dpItem)361*8a106958SDamjan Jovanovic Element::operator<<( DYN Item * let_dpItem )
362*8a106958SDamjan Jovanovic { op_streamout(let_dpItem); return *this; }
363*8a106958SDamjan Jovanovic inline Element &
operator <<(const::csv::String & let_drText)364*8a106958SDamjan Jovanovic Element::operator<<( const ::csv::String & let_drText )
365*8a106958SDamjan Jovanovic { op_streamout( new Text(let_drText) ); return *this; }
366*8a106958SDamjan Jovanovic inline Element &
operator <<(const char * let_drText)367*8a106958SDamjan Jovanovic Element::operator<<( const char * let_drText )
368*8a106958SDamjan Jovanovic { op_streamout( new Text(let_drText) ); return *this; }
369*8a106958SDamjan Jovanovic inline Element &
operator <<(DYN Attribute * let_dpAttr)370*8a106958SDamjan Jovanovic Element::operator<<( DYN Attribute * let_dpAttr )
371*8a106958SDamjan Jovanovic { op_streamout(let_dpAttr); return *this; }
372*8a106958SDamjan Jovanovic inline Element &
operator >>(DYN Element & let_drElement)373*8a106958SDamjan Jovanovic Element::operator>>( DYN Element & let_drElement )
374*8a106958SDamjan Jovanovic { op_streamout(&let_drElement); return let_drElement; }
375*8a106958SDamjan Jovanovic inline Item *
SetContent(DYN Item * let_dpItem)376*8a106958SDamjan Jovanovic Element::SetContent( DYN Item * let_dpItem )
377*8a106958SDamjan Jovanovic { do_SetContent(let_dpItem); return let_dpItem; }
378*8a106958SDamjan Jovanovic
379*8a106958SDamjan Jovanovic
380*8a106958SDamjan Jovanovic } // namespace xml
381*8a106958SDamjan Jovanovic } // namespace csi
382*8a106958SDamjan Jovanovic
383*8a106958SDamjan Jovanovic #endif
384