FreeWRL / FreeX3D 4.3.0
ColladaParser.c
1/*
2
3
4???
5
6*/
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27#if defined (INCLUDE_NON_WEB3D_FORMATS)
28#include <config.h>
29
30#include <system.h>
31#include <display.h>
32#include <internal.h>
33
34#include <libFreeWRL.h>
35
36#include "../vrml_parser/Structs.h"
37#include "../main/headers.h"
38#include "../vrml_parser/CParseGeneral.h"
39#include "../scenegraph/Vector.h"
40#include "../vrml_parser/CFieldDecls.h"
41#include "../world_script/JScript.h"
42#include "../world_script/CScripts.h"
43#include "../world_script/fieldSet.h"
44#include "../vrml_parser/CParseParser.h"
45#include "../vrml_parser/CParseLexer.h"
46#include "../vrml_parser/CParse.h"
47#include "../input/EAIHeaders.h" /* resolving implicit declarations */
48#include "../input/EAIHelpers.h" /* resolving implicit declarations */
49
50
51#include "ColladaParser.h"
52
53
54#define INCREMENT_PARENTINDEXC \
55 if (p->parentIndex < (PARENTSTACKSIZE-2)) { \
56 p->parentIndex++; \
57 p->colladaParentStack[p->parentIndex] = NULL; /* make sure we know the state of the new Top of Stack */ \
58 } else ConsoleMessage ("ColladaParser, line %d stack overflow",LINE);
59
60#include <libxml/parser.h>
61typedef xmlSAXHandler* XML_Parser;
62
63/* for now - fill this in later */
64#define XML_GetCurrentLineNumber(aaa) -1L
65#define XML_ParserFree(aaa) FREE_IF_NZ(aaa)
66#define XML_SetUserData(aaa,bbb)
67#define XML_STATUS_ERROR -1
68#define XML_GetErrorCode(aaa)
69#define XML_ErrorString(aaa) "errors not currently being reported by libxml port"
70
71
72static int XML_ParseFile(xmlSAXHandler *me, const char *myinput, int myinputlen, int recovery) {
73 int notUsed;
74
75 if (xmlSAXUserParseMemory(me, &notUsed, myinput,myinputlen) == 0) return 0;
76 return XML_STATUS_ERROR;
77}
78
79
80/* basic parser stuff */
81#define XML_CreateParserLevel(aaa) \
82 aaa = MALLOC(xmlSAXHandler *, sizeof (xmlSAXHandler)); \
83 bzero (aaa,sizeof(xmlSAXHandler));
84
85/* elements */
86#define XML_SetElementHandler(aaa,bbb,ccc) \
87 aaa->startElement = bbb; \
88 aaa->endElement = ccc;
89
90/* CDATA handling */
91#define XML_SetDefaultHandler(aaa,bbb) /* this is CDATA related too */
92#define XML_SetCdataSectionHandler(aaa,bbb,ccc) \
93 aaa->cdataBlock = endCDATA;
94
95//#define PROTOINSTANCE_MAX_LEVELS 10
96//static XML_Parser colladaParser[PROTOINSTANCE_MAX_LEVELS];
97//static XML_Parser currentColladaParser = NULL;
99//static int ColladaParserRecurseLevel = 0;
100//static int inCDATA = FALSE;
101//struct X3D_Node *colladaParentStack[PARENTSTACKSIZE];
102//static int indentLevel = 0;
103
104typedef struct pColladaParser{
105 XML_Parser colladaParser[PROTOINSTANCE_MAX_LEVELS];
106 XML_Parser currentColladaParser;// = NULL;
107 int parentIndex;// = 0;
108 int ColladaParserRecurseLevel;// = 0;
109 int inCDATA;// = FALSE;
110 struct X3D_Node *colladaParentStack[PARENTSTACKSIZE];
111 int indentLevel;// = 0;
112
113}* ppColladaParser;
114void *ColladaParser_constructor(){
115 void *v = MALLOCV(sizeof(struct pColladaParser));
116 memset(v,0,sizeof(struct pColladaParser));
117 return v;
118}
119void ColladaParser_init(struct tColladaParser *t){
120 //public
121 //private
122 t->prv = ColladaParser_constructor();
123 {
124 ppColladaParser p = (ppColladaParser)t->prv;
125 //p->colladaParser[PROTOINSTANCE_MAX_LEVELS];
126 p->currentColladaParser = NULL;
127 //static int parentIndex = 0;
128 p->ColladaParserRecurseLevel = 0;
129 p->inCDATA = FALSE;
130 //p->colladaParentStack[PARENTSTACKSIZE];
131 p->indentLevel = 0;
132 p->parentIndex = 0;
133 }
134}
135
136static void XMLCALL startCDATA (void *userData) {
137 ttglobal tg = gglobal();
138 if (tg->X3DParser.CDATA_Text_curlen != 0) {
139/*
140 ConsoleMessage ("X3DParser - hmmm, expected CDATA_Text_curlen to be 0, is not");
141 printf ("CDATA_TEXT_CURLEN is %d\n",CDATA_Text_curlen);
142printf ("CADAT_Text:%s:\n",CDATA_Text);
143*/
144 tg->X3DParser.CDATA_Text_curlen = 0;
145 }
146
147 #ifdef COLLADAPARSERVERBOSE
148 printf ("startCDATA -parentIndex %d parserMode %s\n",parentIndex,parserModeStrings[getMode(ud,TOP)]);
149 #endif
150 ((ppColladaParser)(gglobal()->ColladaParser.prv))->inCDATA = TRUE;
151}
152
153static void XMLCALL endCDATA (void *userData, const xmlChar *value, int len) {
154 #ifdef COLLADAPARSERVERBOSE
155 printf ("endCDATA, cur index %d\n",CDATA_Text_curlen);
156 printf ("endCDATA -parentIndex %d parserMode %s\n",parentIndex,parserModeStrings[getMode(ud,TOP)]);
157 #endif
158 ((ppColladaParser)(gglobal()->ColladaParser.prv))->inCDATA = FALSE;
159
160 /* x3d specific dumpCDATAtoProtoBody (CDATA_Text); */
161
162 #ifdef COLLADAPARSERVERBOSE
163 printf ("returning from EndCData\n");
164 #endif
165
166
167}
168
169static void XMLCALL handleCDATA (void *userData, const char *string, int len) {
170/*
171 printf ("handleCDATA...(%d)...",len);
172if (inCDATA) printf ("inCDATA..."); else printf ("not inCDATA...");
173printf ("\n");
174*/
175}
176
177static void XMLCALL ColladaStartElement(void *unused, const xmlChar *name, const xmlChar **atts) {
178
179#ifdef COLLADAVERBOSE
180{int i,j; for (j=0; j< indentLevel; j++) printf (" ");
181 printf ("startElement: %s : level %d\n",name,indentLevel);
182 for (i = 0; atts[i]; i += 2) {
183 for (j=0; j< indentLevel; j++) printf (" ");
184 printf(" field:%s=%s\n", atts[i], atts[i + 1]);
185 }
186}
187#endif
188
189 ((ppColladaParser)(gglobal()->ColladaParser.prv))->indentLevel++;
190}
191
192static void XMLCALL ColladaEndElement(void *unused, const xmlChar *name) {
193 ((ppColladaParser)(gglobal()->ColladaParser.prv))->indentLevel--;
194
195#ifdef COLLADAVERBOSE
196{int i; for (i=0; i< indentLevel; i++) printf (" ");
197 printf ("endElement: %s : level %d\n",name,indentLevel);
198}
199#endif
200
201}
202
203
204static XML_Parser initializeColladaParser () {
205 ppColladaParser p = (ppColladaParser)gglobal()->ColladaParser.prv;
206 p->ColladaParserRecurseLevel++;
207
208 if (p->ColladaParserRecurseLevel >= PROTOINSTANCE_MAX_LEVELS) {
209 ConsoleMessage ("XML_PARSER init: XML file PROTO nested too deep\n");
210 p->ColladaParserRecurseLevel--;
211 } else {
212 XML_CreateParserLevel(p->colladaParser[p->ColladaParserRecurseLevel]);
213 XML_SetElementHandler(p->colladaParser[p->ColladaParserRecurseLevel], ColladaStartElement, ColladaEndElement);
214 XML_SetCdataSectionHandler (p->colladaParser[p->ColladaParserRecurseLevel], startCDATA, endCDATA);
215 XML_SetDefaultHandler (p->colladaParser[p->ColladaParserRecurseLevel],handleCDATA);
216 XML_SetUserData(p->colladaParser[p->ColladaParserRecurseLevel], &p->parentIndex);
217 }
218 /* printf ("initializeColladaParser, level %d, parser %u\n",colladaParser[ColladaParserRecurseLevel]); */
219
220 return p->colladaParser[p->ColladaParserRecurseLevel];
221}
222
223static void shutdownColladaParser () {
224 ttglobal tg = gglobal();
225 ppColladaParser p = (ppColladaParser)tg->ColladaParser.prv;
226 /* printf ("shutdownColladaParser, recurseLevel %d\n",ColladaParserRecurseLevel); */
227 XML_ParserFree(p->colladaParser[p->ColladaParserRecurseLevel]);
228 p->ColladaParserRecurseLevel--;
229
230 /* lets free up memory here for possible PROTO variables */
231 if (p->ColladaParserRecurseLevel == INT_ID_UNDEFINED) {
232 /* if we are at the bottom of the parser call nesting, lets reset parentIndex */
233 p->parentIndex = 0;
234 /* x3d specific freeProtoMemory (); */
235 }
236
237 if (p->ColladaParserRecurseLevel < INT_ID_UNDEFINED) {
238 ConsoleMessage ("XML_PARSER close underflow");
239 p->ColladaParserRecurseLevel = INT_ID_UNDEFINED;
240 }
241
242 /* CDATA text space, free it up */
243 FREE_IF_NZ(tg->X3DParser.CDATA_Text);
244 if (p->ColladaParserRecurseLevel > INT_ID_UNDEFINED)
245 p->currentColladaParser = p->colladaParser[p->ColladaParserRecurseLevel];
246
247 /* printf ("shutdownColladaParser, current ColladaParser %u\n",currentColladaParser); */
248}
249
250int ColladaParse (struct X3D_Group* myParent, const char *inputstring) {
251 ppColladaParser p = (ppColladaParser)gglobal()->ColladaParser.prv;
252 p->currentColladaParser = initializeColladaParser();
253
254 /* printf ("X3DParse, current ColladaParser is %u\n",currentColladaParser); */
255
256
257 INCREMENT_PARENTINDEXC
258 p->colladaParentStack[p->parentIndex] = X3D_NODE(myParent);
259
260 if (XML_ParseFile(p->currentColladaParser, inputstring, (int) strlen(inputstring), TRUE) == XML_STATUS_ERROR) {
261 fprintf(stderr,
262 "%s at line %" XML_FMT_INT_MOD "u\n",
263 XML_ErrorString(XML_GetErrorCode(currentColladaParser)),
264 XML_GetCurrentLineNumber(currentColladaParser));
265 shutdownColladaParser();
266 return FALSE;
267 }
268 shutdownColladaParser();
269 return TRUE;
270}
271#endif //INCLUDE_NON_WEB3D_FORMATS