xref: /haiku/src/apps/cortex/Persistence/Importer.cpp (revision 19ae20e67e91fc09cc9fc5c0e60e21e24e7a53eb)
1*c284bb0fSMatt Madia /*
2*c284bb0fSMatt Madia  * Copyright (c) 1999-2000, Eric Moon.
3*c284bb0fSMatt Madia  * All rights reserved.
4*c284bb0fSMatt Madia  *
5*c284bb0fSMatt Madia  * Redistribution and use in source and binary forms, with or without
6*c284bb0fSMatt Madia  * modification, are permitted provided that the following conditions
7*c284bb0fSMatt Madia  * are met:
8*c284bb0fSMatt Madia  *
9*c284bb0fSMatt Madia  * 1. Redistributions of source code must retain the above copyright
10*c284bb0fSMatt Madia  *    notice, this list of conditions, and the following disclaimer.
11*c284bb0fSMatt Madia  *
12*c284bb0fSMatt Madia  * 2. Redistributions in binary form must reproduce the above copyright
13*c284bb0fSMatt Madia  *    notice, this list of conditions, and the following disclaimer in the
14*c284bb0fSMatt Madia  *    documentation and/or other materials provided with the distribution.
15*c284bb0fSMatt Madia  *
16*c284bb0fSMatt Madia  * 3. The name of the author may not be used to endorse or promote products
17*c284bb0fSMatt Madia  *    derived from this software without specific prior written permission.
18*c284bb0fSMatt Madia  *
19*c284bb0fSMatt Madia  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20*c284bb0fSMatt Madia  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*c284bb0fSMatt Madia  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*c284bb0fSMatt Madia  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23*c284bb0fSMatt Madia  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24*c284bb0fSMatt Madia  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*c284bb0fSMatt Madia  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26*c284bb0fSMatt Madia  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27*c284bb0fSMatt Madia  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28*c284bb0fSMatt Madia  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*c284bb0fSMatt Madia  */
30*c284bb0fSMatt Madia 
31*c284bb0fSMatt Madia 
32a0795c6fSMarcus Overhagen // Importer.cpp
33a0795c6fSMarcus Overhagen // e.moon 28jun99
34a0795c6fSMarcus Overhagen 
35a0795c6fSMarcus Overhagen #include "Importer.h"
36a0795c6fSMarcus Overhagen #include <stdexcept>
37a0795c6fSMarcus Overhagen 
38a0795c6fSMarcus Overhagen #include <Autolock.h>
39a0795c6fSMarcus Overhagen #include <Debug.h>
40a0795c6fSMarcus Overhagen 
4123e67806SIthamar R. Adema using namespace std;
4223e67806SIthamar R. Adema 
43a0795c6fSMarcus Overhagen __USE_CORTEX_NAMESPACE
44a0795c6fSMarcus Overhagen 
45a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
46a0795c6fSMarcus Overhagen // expat hooks
47a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
48a0795c6fSMarcus Overhagen 
_oc_handle_start(void * pUser,const XML_Char * pName,const XML_Char ** ppAtts)49a0795c6fSMarcus Overhagen void _oc_handle_start(
50a0795c6fSMarcus Overhagen 	void* pUser,
51a0795c6fSMarcus Overhagen 	const XML_Char* pName,
52a0795c6fSMarcus Overhagen 	const XML_Char** ppAtts) {
53a0795c6fSMarcus Overhagen 	((Importer*)pUser)->xmlElementStart(pName, ppAtts);
54a0795c6fSMarcus Overhagen }
55a0795c6fSMarcus Overhagen 
_oc_handle_end(void * pUser,const XML_Char * pName)56a0795c6fSMarcus Overhagen void _oc_handle_end(
57a0795c6fSMarcus Overhagen 	void* pUser,
58a0795c6fSMarcus Overhagen 	const XML_Char* pName) {
59a0795c6fSMarcus Overhagen 	((Importer*)pUser)->xmlElementEnd(pName);
60a0795c6fSMarcus Overhagen }
61a0795c6fSMarcus Overhagen 
_oc_handle_pi(void * pUser,const XML_Char * pTarget,const XML_Char * pData)62a0795c6fSMarcus Overhagen void _oc_handle_pi(
63a0795c6fSMarcus Overhagen 	void* pUser,
64a0795c6fSMarcus Overhagen 	const XML_Char* pTarget,
65a0795c6fSMarcus Overhagen 	const XML_Char* pData) {
66a0795c6fSMarcus Overhagen 	((Importer*)pUser)->xmlProcessingInstruction(pTarget, pData);
67a0795c6fSMarcus Overhagen }
68a0795c6fSMarcus Overhagen 
_oc_handle_char(void * pUser,const XML_Char * pData,int length)69a0795c6fSMarcus Overhagen void _oc_handle_char(
70a0795c6fSMarcus Overhagen 	void* pUser,
71a0795c6fSMarcus Overhagen 	const XML_Char* pData,
72a0795c6fSMarcus Overhagen 	int length) {
73a0795c6fSMarcus Overhagen 	((Importer*)pUser)->xmlCharacterData(pData, length);
74a0795c6fSMarcus Overhagen }
75a0795c6fSMarcus Overhagen 
_oc_handle_default(void * pUser,const XML_Char * pData,int length)76a0795c6fSMarcus Overhagen void _oc_handle_default(
77a0795c6fSMarcus Overhagen 	void* pUser,
78a0795c6fSMarcus Overhagen 	const XML_Char* pData,
79a0795c6fSMarcus Overhagen 	int length) {
80a0795c6fSMarcus Overhagen 	((Importer*)pUser)->xmlDefaultData(pData, length);
81a0795c6fSMarcus Overhagen }
82a0795c6fSMarcus Overhagen 
83a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
84a0795c6fSMarcus Overhagen // ctor/dtor
85a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
86a0795c6fSMarcus Overhagen 
~Importer()87a0795c6fSMarcus Overhagen Importer::~Importer() {
88a0795c6fSMarcus Overhagen 	// clean up
89a0795c6fSMarcus Overhagen 	freeParser();
90a0795c6fSMarcus Overhagen 
91a0795c6fSMarcus Overhagen 	delete m_context;
92a0795c6fSMarcus Overhagen }
93a0795c6fSMarcus Overhagen 
94a0795c6fSMarcus Overhagen 
Importer(list<BString> & errors)95a0795c6fSMarcus Overhagen Importer::Importer(
96a0795c6fSMarcus Overhagen 	list<BString>&							errors) :
97a0795c6fSMarcus Overhagen 
98a0795c6fSMarcus Overhagen 	m_parser(0),
99a0795c6fSMarcus Overhagen 	m_docType(0),
100a0795c6fSMarcus Overhagen 	m_identify(false),
101a0795c6fSMarcus Overhagen 	m_context(new ImportContext(errors)),
102a0795c6fSMarcus Overhagen 	m_rootObject(0) {
103a0795c6fSMarcus Overhagen 
104a0795c6fSMarcus Overhagen 	initParser();
105a0795c6fSMarcus Overhagen }
106a0795c6fSMarcus Overhagen 
Importer(ImportContext * context)107a0795c6fSMarcus Overhagen Importer::Importer(
108a0795c6fSMarcus Overhagen 	ImportContext*							context) :
109a0795c6fSMarcus Overhagen 
110a0795c6fSMarcus Overhagen 	m_parser(0),
111a0795c6fSMarcus Overhagen 	m_docType(0),
112a0795c6fSMarcus Overhagen 	m_identify(false),
113a0795c6fSMarcus Overhagen 	m_context(context),
114a0795c6fSMarcus Overhagen 	m_rootObject(0) {
115a0795c6fSMarcus Overhagen 
116a0795c6fSMarcus Overhagen 	ASSERT(m_context);
117a0795c6fSMarcus Overhagen 
118a0795c6fSMarcus Overhagen 	initParser();
119a0795c6fSMarcus Overhagen }
120a0795c6fSMarcus Overhagen 
Importer(list<BString> & errors,IPersistent * rootObject,XML::DocumentType * docType)121a0795c6fSMarcus Overhagen Importer::Importer(
122a0795c6fSMarcus Overhagen 	list<BString>&							errors,
123a0795c6fSMarcus Overhagen 	IPersistent*								rootObject,
124a0795c6fSMarcus Overhagen 	XML::DocumentType*					docType) :
125a0795c6fSMarcus Overhagen 
126a0795c6fSMarcus Overhagen 	m_parser(0),
127a0795c6fSMarcus Overhagen 	m_docType(docType),
128a0795c6fSMarcus Overhagen 	m_identify(false),
129a0795c6fSMarcus Overhagen 	m_context(new ImportContext(errors)),
130a0795c6fSMarcus Overhagen 	m_rootObject(rootObject) {
131a0795c6fSMarcus Overhagen 
132a0795c6fSMarcus Overhagen 	ASSERT(rootObject);
133a0795c6fSMarcus Overhagen 	ASSERT(docType);
134a0795c6fSMarcus Overhagen 
135a0795c6fSMarcus Overhagen 	initParser();
136a0795c6fSMarcus Overhagen }
137a0795c6fSMarcus Overhagen 
Importer(ImportContext * context,IPersistent * rootObject,XML::DocumentType * docType)138a0795c6fSMarcus Overhagen Importer::Importer(
139a0795c6fSMarcus Overhagen 	ImportContext*							context,
140a0795c6fSMarcus Overhagen 	IPersistent*								rootObject,
141a0795c6fSMarcus Overhagen 	XML::DocumentType*					docType) :
142a0795c6fSMarcus Overhagen 
143a0795c6fSMarcus Overhagen 	m_parser(0),
144a0795c6fSMarcus Overhagen 	m_docType(docType),
145a0795c6fSMarcus Overhagen 	m_identify(false),
146a0795c6fSMarcus Overhagen 	m_context(context),
147a0795c6fSMarcus Overhagen 	m_rootObject(rootObject) {
148a0795c6fSMarcus Overhagen 
149a0795c6fSMarcus Overhagen 	ASSERT(m_context);
150a0795c6fSMarcus Overhagen 	ASSERT(rootObject);
151a0795c6fSMarcus Overhagen 	ASSERT(docType);
152a0795c6fSMarcus Overhagen 
153a0795c6fSMarcus Overhagen 	initParser();
154a0795c6fSMarcus Overhagen }
155a0795c6fSMarcus Overhagen 
156a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
157a0795c6fSMarcus Overhagen // accessors
158a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
159a0795c6fSMarcus Overhagen 
160a0795c6fSMarcus Overhagen // the import context
context() const161a0795c6fSMarcus Overhagen const ImportContext& Importer::context() const {
162a0795c6fSMarcus Overhagen 	return *m_context;
163a0795c6fSMarcus Overhagen }
164a0795c6fSMarcus Overhagen 
165a0795c6fSMarcus Overhagen // matched (or provided) document type
docType() const166a0795c6fSMarcus Overhagen XML::DocumentType* Importer::docType() const {
167a0795c6fSMarcus Overhagen 	return m_docType;
168a0795c6fSMarcus Overhagen }
169a0795c6fSMarcus Overhagen 
170a0795c6fSMarcus Overhagen // completed object (available if
171a0795c6fSMarcus Overhagen // context().state() == ImportContext::COMPLETE, or
172a0795c6fSMarcus Overhagen // if a root object was provided to the ctor)
target() const173a0795c6fSMarcus Overhagen IPersistent* Importer::target() const {
174a0795c6fSMarcus Overhagen 	return m_rootObject;
175a0795c6fSMarcus Overhagen }
176a0795c6fSMarcus Overhagen 
177a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
178a0795c6fSMarcus Overhagen // operations
179a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
180a0795c6fSMarcus Overhagen 
181a0795c6fSMarcus Overhagen // put the importer into 'identify mode'
182a0795c6fSMarcus Overhagen // (disengaged once the first element is encountered)
setIdentifyMode()183a0795c6fSMarcus Overhagen void Importer::setIdentifyMode() {
184a0795c6fSMarcus Overhagen 	reset();
185a0795c6fSMarcus Overhagen 	m_docType = 0;
186a0795c6fSMarcus Overhagen 	m_identify = true;
187a0795c6fSMarcus Overhagen }
188a0795c6fSMarcus Overhagen 
reset()189a0795c6fSMarcus Overhagen void Importer::reset() {
190a0795c6fSMarcus Overhagen 	// doesn't forget document type from identify cycle!
191a0795c6fSMarcus Overhagen 
192a0795c6fSMarcus Overhagen 	m_identify = false;
193a0795c6fSMarcus Overhagen 	m_context->reset();
194a0795c6fSMarcus Overhagen 	m_rootObject = 0;
195a0795c6fSMarcus Overhagen }
196a0795c6fSMarcus Overhagen 
197a0795c6fSMarcus Overhagen // handle a buffer; return false if an error occurs
parseBuffer(const char * pBuffer,uint32 length,bool last)198a0795c6fSMarcus Overhagen bool Importer::parseBuffer(
199a0795c6fSMarcus Overhagen 	const char* pBuffer,
200a0795c6fSMarcus Overhagen 	uint32 length,
201a0795c6fSMarcus Overhagen 	bool last) {
202a0795c6fSMarcus Overhagen 
203a0795c6fSMarcus Overhagen 	ASSERT(m_parser);
204a0795c6fSMarcus Overhagen 
205a0795c6fSMarcus Overhagen 	int err = XML_Parse(m_parser, pBuffer, length, last);
206a0795c6fSMarcus Overhagen 
207a0795c6fSMarcus Overhagen 	if(!err) {
208a0795c6fSMarcus Overhagen 		BString str = "Parse Error: ";
209a0795c6fSMarcus Overhagen 		str << XML_ErrorString(XML_GetErrorCode(m_parser));
210a0795c6fSMarcus Overhagen 		m_context->reportError(str.String());
211a0795c6fSMarcus Overhagen 		return false;
212a0795c6fSMarcus Overhagen 
213a0795c6fSMarcus Overhagen 	} else
214a0795c6fSMarcus Overhagen 		return true;
215a0795c6fSMarcus Overhagen }
216a0795c6fSMarcus Overhagen 
217a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
218a0795c6fSMarcus Overhagen // internal operations
219a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
220a0795c6fSMarcus Overhagen 
221a0795c6fSMarcus Overhagen // create & initialize parser
initParser()222a0795c6fSMarcus Overhagen void Importer::initParser() {
223a0795c6fSMarcus Overhagen 	ASSERT(!m_parser);
224a0795c6fSMarcus Overhagen 	m_parser = XML_ParserCreate(0);
225a0795c6fSMarcus Overhagen 	m_context->m_pParser = m_parser;
226a0795c6fSMarcus Overhagen 
227a0795c6fSMarcus Overhagen 	XML_SetElementHandler(
228a0795c6fSMarcus Overhagen 		m_parser,
229a0795c6fSMarcus Overhagen 		&_oc_handle_start,
230a0795c6fSMarcus Overhagen 		&_oc_handle_end);
231a0795c6fSMarcus Overhagen 
232a0795c6fSMarcus Overhagen 	XML_SetProcessingInstructionHandler(
233a0795c6fSMarcus Overhagen 		m_parser,
234a0795c6fSMarcus Overhagen 		&_oc_handle_pi);
235a0795c6fSMarcus Overhagen 
236a0795c6fSMarcus Overhagen 	XML_SetCharacterDataHandler(
237a0795c6fSMarcus Overhagen 		m_parser,
238a0795c6fSMarcus Overhagen 		&_oc_handle_char);
239a0795c6fSMarcus Overhagen 
240a0795c6fSMarcus Overhagen 	XML_SetDefaultHandlerExpand(
241a0795c6fSMarcus Overhagen 		m_parser,
242a0795c6fSMarcus Overhagen 		&_oc_handle_default);
243a0795c6fSMarcus Overhagen 
244a0795c6fSMarcus Overhagen 	XML_SetUserData(
245a0795c6fSMarcus Overhagen 		m_parser,
246a0795c6fSMarcus Overhagen 		(void*)this);
247a0795c6fSMarcus Overhagen }
248a0795c6fSMarcus Overhagen 
249a0795c6fSMarcus Overhagen // clean up the parser
freeParser()250a0795c6fSMarcus Overhagen void Importer::freeParser() {
251a0795c6fSMarcus Overhagen 	ASSERT(m_parser);
252a0795c6fSMarcus Overhagen 	XML_ParserFree(m_parser);
253a0795c6fSMarcus Overhagen 	m_parser = 0;
254a0795c6fSMarcus Overhagen }
255a0795c6fSMarcus Overhagen 
256a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
257a0795c6fSMarcus Overhagen // XML parser event hooks
258a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
259a0795c6fSMarcus Overhagen 
xmlElementStart(const char * pName,const char ** ppAttributes)260a0795c6fSMarcus Overhagen void Importer::xmlElementStart(
261a0795c6fSMarcus Overhagen 	const char*			pName,
262a0795c6fSMarcus Overhagen 	const char**		ppAttributes) {
263a0795c6fSMarcus Overhagen 
264a0795c6fSMarcus Overhagen 	if(m_context->m_state != ImportContext::PARSING)
265a0795c6fSMarcus Overhagen 		return;
266a0795c6fSMarcus Overhagen 
267a0795c6fSMarcus Overhagen 	IPersistent* target = 0;
268a0795c6fSMarcus Overhagen 
269a0795c6fSMarcus Overhagen 	if(!m_context->m_elementStack.size()) {
270a0795c6fSMarcus Overhagen 		// this is the first element; identify or verify document type
271a0795c6fSMarcus Overhagen 
272a0795c6fSMarcus Overhagen 		if(m_rootObject) {
273a0795c6fSMarcus Overhagen 			// test against expected document type
274a0795c6fSMarcus Overhagen 			ASSERT(m_docType);
275a0795c6fSMarcus Overhagen 			if(m_docType->rootElement != pName) {
276a0795c6fSMarcus Overhagen 				BString err("Unexpected document element (should be <");
277a0795c6fSMarcus Overhagen 				err << m_docType->rootElement << "/>";
278a0795c6fSMarcus Overhagen 				m_context->reportError(err.String());
279a0795c6fSMarcus Overhagen 				return;
280a0795c6fSMarcus Overhagen 			}
281a0795c6fSMarcus Overhagen 
282a0795c6fSMarcus Overhagen 			// target the provided root object
283a0795c6fSMarcus Overhagen 			target = m_rootObject;
284a0795c6fSMarcus Overhagen 		}
285a0795c6fSMarcus Overhagen 		else {
286a0795c6fSMarcus Overhagen 			// look up doc type
287a0795c6fSMarcus Overhagen 			BAutolock _l(XML::s_docTypeLock);
288a0795c6fSMarcus Overhagen 			XML::doc_type_map::iterator it = XML::s_docTypeMap.find(
289a0795c6fSMarcus Overhagen 				BString(pName));
290a0795c6fSMarcus Overhagen 
291a0795c6fSMarcus Overhagen 			if(it != XML::s_docTypeMap.end())
292a0795c6fSMarcus Overhagen 				m_docType = (*it).second;
293a0795c6fSMarcus Overhagen 			else {
294a0795c6fSMarcus Overhagen 				// whoops, don't know how to handle this element:
295a0795c6fSMarcus Overhagen 				BString err("No document type registered for element '");
296a0795c6fSMarcus Overhagen 				err << pName << "'.";
297a0795c6fSMarcus Overhagen 				m_context->reportError(err.String());
298a0795c6fSMarcus Overhagen 				return;
299a0795c6fSMarcus Overhagen 			}
300a0795c6fSMarcus Overhagen 
301a0795c6fSMarcus Overhagen 			if(m_identify) {
302a0795c6fSMarcus Overhagen 				// end of identify cycle
303a0795c6fSMarcus Overhagen 				m_context->m_state = ImportContext::COMPLETE;
304a0795c6fSMarcus Overhagen 				return;
305a0795c6fSMarcus Overhagen 			}
306a0795c6fSMarcus Overhagen 		}
307a0795c6fSMarcus Overhagen 	}
308a0795c6fSMarcus Overhagen 	// at this point, there'd better be a valid document type
309a0795c6fSMarcus Overhagen 	ASSERT(m_docType);
310a0795c6fSMarcus Overhagen 
311a0795c6fSMarcus Overhagen 	// push element name onto the stack
312a0795c6fSMarcus Overhagen 	m_context->m_elementStack.push_back(pName);
313a0795c6fSMarcus Overhagen 
314a0795c6fSMarcus Overhagen 	// try to create an object for this element if necessary
315a0795c6fSMarcus Overhagen 	if(!target)
316a0795c6fSMarcus Overhagen 		target = m_docType->objectFor(pName);
317a0795c6fSMarcus Overhagen 
318a0795c6fSMarcus Overhagen 	if(target) {
319a0795c6fSMarcus Overhagen 		// call 'begin import' hook
320a0795c6fSMarcus Overhagen 		m_context->m_objectStack.push_back(
321a0795c6fSMarcus Overhagen 			make_pair(m_context->element(), target));
322a0795c6fSMarcus Overhagen 		target->xmlImportBegin(*m_context);
323a0795c6fSMarcus Overhagen 
324a0795c6fSMarcus Overhagen 		// error? bail
325a0795c6fSMarcus Overhagen 		if(m_context->state() != ImportContext::PARSING)
326a0795c6fSMarcus Overhagen 			return;
327a0795c6fSMarcus Overhagen 
328a0795c6fSMarcus Overhagen 		// walk attributes
329a0795c6fSMarcus Overhagen 		while(*ppAttributes) {
330a0795c6fSMarcus Overhagen 			target->xmlImportAttribute(
331a0795c6fSMarcus Overhagen 				ppAttributes[0],
332a0795c6fSMarcus Overhagen 				ppAttributes[1],
333a0795c6fSMarcus Overhagen 				*m_context);
334a0795c6fSMarcus Overhagen 
335a0795c6fSMarcus Overhagen 			// error? bail
336a0795c6fSMarcus Overhagen 			if(m_context->state() != ImportContext::PARSING)
337a0795c6fSMarcus Overhagen 				return;
338a0795c6fSMarcus Overhagen 
339a0795c6fSMarcus Overhagen 			ppAttributes += 2;
340a0795c6fSMarcus Overhagen 		}
341a0795c6fSMarcus Overhagen 	} else {
342a0795c6fSMarcus Overhagen 		// no object directly maps to this element; hand to
343a0795c6fSMarcus Overhagen 		// the current focus object
344a0795c6fSMarcus Overhagen 
345a0795c6fSMarcus Overhagen 		ASSERT(m_context->m_objectStack.size());
346a0795c6fSMarcus Overhagen 		IPersistent* curObject = m_context->m_objectStack.back().second;
347a0795c6fSMarcus Overhagen 		ASSERT(curObject);
348a0795c6fSMarcus Overhagen 
349a0795c6fSMarcus Overhagen 		curObject->xmlImportChildBegin(
350a0795c6fSMarcus Overhagen 			pName,
351a0795c6fSMarcus Overhagen 			*m_context);
352a0795c6fSMarcus Overhagen 
353a0795c6fSMarcus Overhagen 		// error? bail
354a0795c6fSMarcus Overhagen 		if(m_context->state() != ImportContext::PARSING)
355a0795c6fSMarcus Overhagen 			return;
356a0795c6fSMarcus Overhagen 
357a0795c6fSMarcus Overhagen 		// walk attributes
358a0795c6fSMarcus Overhagen 		while(*ppAttributes) {
359a0795c6fSMarcus Overhagen 			curObject->xmlImportChildAttribute(
360a0795c6fSMarcus Overhagen 				ppAttributes[0],
361a0795c6fSMarcus Overhagen 				ppAttributes[1],
362a0795c6fSMarcus Overhagen 				*m_context);
363a0795c6fSMarcus Overhagen 
364a0795c6fSMarcus Overhagen 			// error? bail
365a0795c6fSMarcus Overhagen 			if(m_context->state() != ImportContext::PARSING)
366a0795c6fSMarcus Overhagen 				return;
367a0795c6fSMarcus Overhagen 
368a0795c6fSMarcus Overhagen 			ppAttributes += 2;
369a0795c6fSMarcus Overhagen 		}
370a0795c6fSMarcus Overhagen 	}
371a0795c6fSMarcus Overhagen }
372a0795c6fSMarcus Overhagen 
xmlElementEnd(const char * pName)373a0795c6fSMarcus Overhagen void Importer::xmlElementEnd(
374a0795c6fSMarcus Overhagen 	const char*			pName) {
375a0795c6fSMarcus Overhagen 
376a0795c6fSMarcus Overhagen 	if(m_context->m_state != ImportContext::PARSING)
377a0795c6fSMarcus Overhagen 		return;
378a0795c6fSMarcus Overhagen 	ASSERT(m_docType);
379a0795c6fSMarcus Overhagen 
380a0795c6fSMarcus Overhagen //	PRINT(("Importer::xmlElementEnd(): %s\n", pName));
381a0795c6fSMarcus Overhagen 
382a0795c6fSMarcus Overhagen 	// compare name to element on top of stack
383a0795c6fSMarcus Overhagen 	if(!m_context->m_elementStack.size() ||
384a0795c6fSMarcus Overhagen 		m_context->m_elementStack.back() != pName) {
385a0795c6fSMarcus Overhagen 		m_context->reportError("Mismatched end tag.");
386a0795c6fSMarcus Overhagen 		return;
387a0795c6fSMarcus Overhagen 	}
388a0795c6fSMarcus Overhagen 
389a0795c6fSMarcus Overhagen 	// see if it matches the topmost object
390a0795c6fSMarcus Overhagen 	IPersistent* pObject = 0;
391a0795c6fSMarcus Overhagen 	if(!m_context->m_objectStack.size()) {
392a0795c6fSMarcus Overhagen 		m_context->reportError("No object being constructed.");
393a0795c6fSMarcus Overhagen 		return;
394a0795c6fSMarcus Overhagen 	}
395a0795c6fSMarcus Overhagen 	if(m_context->m_objectStack.back().first == m_context->element()) {
396a0795c6fSMarcus Overhagen 		// matched; pop it
397a0795c6fSMarcus Overhagen 		pObject = m_context->m_objectStack.back().second;
398a0795c6fSMarcus Overhagen 		m_context->m_objectStack.pop_back();
399a0795c6fSMarcus Overhagen 	}
400a0795c6fSMarcus Overhagen 
401a0795c6fSMarcus Overhagen 	if(pObject) {
402a0795c6fSMarcus Overhagen 		// notify object that import is complete
403a0795c6fSMarcus Overhagen 		pObject->xmlImportComplete(
404a0795c6fSMarcus Overhagen 			*m_context);
405a0795c6fSMarcus Overhagen 
406a0795c6fSMarcus Overhagen 		// error? bail
407a0795c6fSMarcus Overhagen 		if(m_context->state() != ImportContext::PARSING)
408a0795c6fSMarcus Overhagen 			return;
409a0795c6fSMarcus Overhagen 
410a0795c6fSMarcus Overhagen 		if(m_context->m_objectStack.size()) {
411a0795c6fSMarcus Overhagen 			// hand the newly-constructed child to its parent
412a0795c6fSMarcus Overhagen 			m_context->m_objectStack.back().second->xmlImportChild(
413a0795c6fSMarcus Overhagen 				pObject,
414a0795c6fSMarcus Overhagen 				*m_context);
415a0795c6fSMarcus Overhagen 		} else {
416a0795c6fSMarcus Overhagen 			// done
417a0795c6fSMarcus Overhagen 			ASSERT(m_context->m_elementStack.size() == 1);
418a0795c6fSMarcus Overhagen 			m_context->m_state = ImportContext::COMPLETE;
419a0795c6fSMarcus Overhagen 			if(m_rootObject) {
420a0795c6fSMarcus Overhagen 				ASSERT(m_rootObject == pObject);
421a0795c6fSMarcus Overhagen 			} else
422a0795c6fSMarcus Overhagen 				m_rootObject = pObject;
423a0795c6fSMarcus Overhagen 		}
424a0795c6fSMarcus Overhagen 	}
425a0795c6fSMarcus Overhagen 	else {
426a0795c6fSMarcus Overhagen 		// notify current topmost object
427a0795c6fSMarcus Overhagen 		ASSERT(m_context->m_objectStack.size());
428a0795c6fSMarcus Overhagen 		IPersistent* curObject = m_context->m_objectStack.back().second;
429a0795c6fSMarcus Overhagen 		ASSERT(curObject);
430a0795c6fSMarcus Overhagen 
431a0795c6fSMarcus Overhagen 		curObject->xmlImportChildComplete(
432a0795c6fSMarcus Overhagen 			pName,
433a0795c6fSMarcus Overhagen 			*m_context);
434a0795c6fSMarcus Overhagen 	}
435a0795c6fSMarcus Overhagen 
436a0795c6fSMarcus Overhagen 	// remove entry from element stack
437a0795c6fSMarcus Overhagen 	m_context->m_elementStack.pop_back();
438a0795c6fSMarcus Overhagen 	ASSERT(m_context->m_objectStack.size() <= m_context->m_elementStack.size());
439a0795c6fSMarcus Overhagen }
440a0795c6fSMarcus Overhagen 
xmlProcessingInstruction(const char * pTarget,const char * pData)441a0795c6fSMarcus Overhagen void Importer::xmlProcessingInstruction(
442a0795c6fSMarcus Overhagen 	const char*			pTarget,
443a0795c6fSMarcus Overhagen 	const char*			pData) {
444a0795c6fSMarcus Overhagen 
445a0795c6fSMarcus Overhagen 	if(m_context->m_state != ImportContext::PARSING)
446a0795c6fSMarcus Overhagen 		return;
447a0795c6fSMarcus Overhagen //	PRINT(("Importer::xmlProcessingInstruction(): %s, %s\n",
448a0795c6fSMarcus Overhagen //		pTarget, pData));
449a0795c6fSMarcus Overhagen 
450a0795c6fSMarcus Overhagen }
451a0795c6fSMarcus Overhagen 
452a0795c6fSMarcus Overhagen // not 0-terminated
xmlCharacterData(const char * pData,int32 length)453a0795c6fSMarcus Overhagen void Importer::xmlCharacterData(
454a0795c6fSMarcus Overhagen 	const char*			pData,
455a0795c6fSMarcus Overhagen 	int32					length) {
456a0795c6fSMarcus Overhagen 
457a0795c6fSMarcus Overhagen 	if(m_context->m_state != ImportContext::PARSING)
458a0795c6fSMarcus Overhagen 		return;
459a0795c6fSMarcus Overhagen 
460a0795c6fSMarcus Overhagen 	// see if the current element matches the topmost object
461a0795c6fSMarcus Overhagen 	IPersistent* pObject = 0;
462a0795c6fSMarcus Overhagen 	if(!m_context->m_objectStack.size()) {
463a0795c6fSMarcus Overhagen 		m_context->reportError("No object being constructed.");
464a0795c6fSMarcus Overhagen 		return;
465a0795c6fSMarcus Overhagen 	}
466a0795c6fSMarcus Overhagen 
467a0795c6fSMarcus Overhagen 	pObject = m_context->m_objectStack.back().second;
468a0795c6fSMarcus Overhagen 	if(m_context->m_objectStack.back().first == m_context->element()) {
469a0795c6fSMarcus Overhagen 
470a0795c6fSMarcus Overhagen 		pObject->xmlImportContent(
471a0795c6fSMarcus Overhagen 			pData,
472a0795c6fSMarcus Overhagen 			length,
473a0795c6fSMarcus Overhagen 			*m_context);
474a0795c6fSMarcus Overhagen 	}
475a0795c6fSMarcus Overhagen 	else {
476a0795c6fSMarcus Overhagen 		pObject->xmlImportChildContent(
477a0795c6fSMarcus Overhagen 			pData,
478a0795c6fSMarcus Overhagen 			length,
479a0795c6fSMarcus Overhagen 			*m_context);
480a0795c6fSMarcus Overhagen 	}
481a0795c6fSMarcus Overhagen }
482a0795c6fSMarcus Overhagen 
483a0795c6fSMarcus Overhagen // not 0-terminated
xmlDefaultData(const char * pData,int32 length)484a0795c6fSMarcus Overhagen void Importer::xmlDefaultData(
485a0795c6fSMarcus Overhagen 	const char*			pData,
486a0795c6fSMarcus Overhagen 	int32					length) {
487a0795c6fSMarcus Overhagen 
488a0795c6fSMarcus Overhagen 	if(m_context->m_state != ImportContext::PARSING)
489a0795c6fSMarcus Overhagen 		return;
490a0795c6fSMarcus Overhagen //	PRINT(("Importer::xmlDefaultData()\n"));
491a0795c6fSMarcus Overhagen }
492a0795c6fSMarcus Overhagen 
493a0795c6fSMarcus Overhagen // END -- Importer.cpp --
494