1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 #include <Inventor/scxml/ScXMLElseIfElt.h>
34
35 /*!
36 \class ScXMLElseIfElt ScXMLElseIfElt.h Inventor/scxml/ScXMLElseIfElt.h
37 \brief implements the <elseif> SCXML element.
38
39 The <elseif> element can have the attribute "cond" and no children.
40 The <elseif> element is a separator element for the enclosing <if>
41 element. It can only be used inside <if> elements.
42
43 \ingroup scxml
44 \since Coin 3.1
45 */
46
47 #include <cassert>
48 #include <cstring>
49
50 #include <Inventor/errors/SoDebugError.h>
51 #include <Inventor/C/XML/element.h>
52 #include <Inventor/scxml/ScXMLIfElt.h>
53
54 #include "scxml/ScXMLCommonP.h"
55 #include "SbBasicP.h"
56
57 #ifndef COIN_WORKAROUND_NO_USING_STD_FUNCS
58 using std::strcmp;
59 #endif // !COIN_WORKAROUND_NO_USING_STD_FUNCS
60
61 // *************************************************************************
62
63 class ScXMLElseIfEltReader : public ScXMLEltReader {
64 public:
65 ScXMLElseIfEltReader(void);
66 virtual ScXMLElt * read(ScXMLElt * container, cc_xml_elt * xmlelt, ScXMLDocument * doc, ScXMLStateMachine * sm);
67 };
68
ScXMLElseIfEltReader(void)69 ScXMLElseIfEltReader::ScXMLElseIfEltReader(void)
70 : ScXMLEltReader("elseif")
71 {
72 }
73
74 ScXMLElt *
read(ScXMLElt * container,cc_xml_elt * xmlelt,ScXMLDocument * COIN_UNUSED_ARG (doc),ScXMLStateMachine * COIN_UNUSED_ARG (sm))75 ScXMLElseIfEltReader::read(ScXMLElt * container, cc_xml_elt * xmlelt, ScXMLDocument * COIN_UNUSED_ARG(doc), ScXMLStateMachine * COIN_UNUSED_ARG(sm))
76 {
77 assert(container && xmlelt);
78 ScXMLElseIfElt * elseifelt = new ScXMLElseIfElt;
79 elseifelt->setContainer(container);
80 this->setXMLAttributes(elseifelt, xmlelt);
81
82 // handle XML attributes
83 if (unlikely(!elseifelt->handleXMLAttributes())) {
84 delete elseifelt;
85 return NULL;
86 }
87
88 const int numchildren = cc_xml_elt_get_num_children(xmlelt);
89 for (int c = 0; c < numchildren; ++c) {
90 cc_xml_elt * element = cc_xml_elt_get_child(xmlelt, c);
91 const char * elementtype = cc_xml_elt_get_type(element);
92 if (strcmp(elementtype, COIN_XML_CDATA_TYPE) == 0) {
93 // ignore CDATA
94 continue;
95 }
96
97 SoDebugError::post("ScXMLElseIfEltReader::read",
98 "<elseif> contains unexpected <%s> element", elementtype);
99 delete elseifelt;
100 return NULL;
101 }
102
103 return elseifelt;
104 }
105
106 // *************************************************************************
107
108 class ScXMLElseIfElt::PImpl {
109 public:
110 };
111
112 #define PRIVATE(obj) ((obj)->pimpl)
113
114 SCXML_ELEMENT_SOURCE(ScXMLElseIfElt);
115
116 void
initClass(void)117 ScXMLElseIfElt::initClass(void)
118 {
119 SCXML_OBJECT_INIT_CLASS(ScXMLElseIfElt, ScXMLExecutableElt, "ScXMLExecutableElt");
120 SCXML_ELEMENT_REGISTER_READER(ScXMLElseIfElt, "elseif", ScXMLElseIfEltReader);
121 }
122
123 void
cleanClass(void)124 ScXMLElseIfElt::cleanClass(void)
125 {
126 SCXML_ELEMENT_UNREGISTER_READER(ScXMLElseIfElt);
127 ScXMLElseIfElt::classTypeId = SoType::badType();
128 }
129
ScXMLElseIfElt(void)130 ScXMLElseIfElt::ScXMLElseIfElt(void)
131 : cond(NULL)
132 {
133 }
134
~ScXMLElseIfElt(void)135 ScXMLElseIfElt::~ScXMLElseIfElt(void)
136 {
137 this->setCondAttribute(NULL);
138 }
139
140 void
setCondAttribute(const char * condstr)141 ScXMLElseIfElt::setCondAttribute(const char * condstr)
142 {
143 SCXML__SET_ATTRIBUTE_VALUE(this->cond, "cond", condstr);
144 }
145
146 // const char * ScXMLElseIfElt::getCondAttribute(void) const
147
148 SbBool
handleXMLAttributes(void)149 ScXMLElseIfElt::handleXMLAttributes(void)
150 {
151 if (!inherited::handleXMLAttributes()) {
152 return FALSE;
153 }
154
155 this->setCondAttribute(this->getXMLAttribute("cond"));
156
157 return TRUE;
158 }
159
160 void
copyContents(const ScXMLElt * rhs)161 ScXMLElseIfElt::copyContents(const ScXMLElt * rhs)
162 {
163 inherited::copyContents(rhs);
164 const ScXMLElseIfElt * orig = coin_assert_cast<const ScXMLElseIfElt *>(rhs);
165 this->setCondAttribute(orig->getCondAttribute());
166 }
167
168 const ScXMLElt *
search(const char * attrname,const char * attrvalue) const169 ScXMLElseIfElt::search(const char * attrname, const char * attrvalue) const
170 {
171 const ScXMLElt * hit = inherited::search(attrname, attrvalue);
172 if (hit) {
173 return hit;
174 }
175 if (strcmp(attrname, "cond") == 0) {
176 if (this->cond && strcmp(attrvalue, this->cond) == 0) {
177 return this;
178 }
179 }
180 return NULL;
181 }
182
183 #undef PRIVATE
184