1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
12 ******************************************************************************/
16 * Created on: 19-Nov-2008
20 #include <libxml/xmlreader.h>
21 #include "XmlReader.hh"
22 #include "static_check.h"
26 XmlReaderWrap::XmlReaderWrap(TTCN_Buffer
& buf
)
29 // compile-time safety checks
30 ENSURE_EQUAL( XML_PARSER_SEVERITY_VALIDITY_WARNING
, \
31 xmlreader_lite::XML_PARSER_SEVERITY_VALIDITY_WARNING
);
32 ENSURE_EQUAL( XML_PARSER_SEVERITY_VALIDITY_ERROR
, \
33 xmlreader_lite::XML_PARSER_SEVERITY_VALIDITY_ERROR
);
34 ENSURE_EQUAL( XML_PARSER_SEVERITY_WARNING
, \
35 xmlreader_lite::XML_PARSER_SEVERITY_WARNING
);
36 ENSURE_EQUAL( XML_PARSER_SEVERITY_ERROR
, \
37 xmlreader_lite::XML_PARSER_SEVERITY_ERROR
);
39 ENSURE_EQUAL( XML_READER_TYPE_NONE
, \
40 xmlreader_lite::XML_READER_TYPE_NONE
);
41 ENSURE_EQUAL( XML_READER_TYPE_ELEMENT
, \
42 xmlreader_lite::XML_READER_TYPE_ELEMENT
);
43 ENSURE_EQUAL( XML_READER_TYPE_ATTRIBUTE
, \
44 xmlreader_lite::XML_READER_TYPE_ATTRIBUTE
);
45 ENSURE_EQUAL( XML_READER_TYPE_TEXT
, \
46 xmlreader_lite::XML_READER_TYPE_TEXT
);
47 ENSURE_EQUAL( XML_READER_TYPE_CDATA
, \
48 xmlreader_lite::XML_READER_TYPE_CDATA
);
49 ENSURE_EQUAL( XML_READER_TYPE_ENTITY_REFERENCE
, \
50 xmlreader_lite::XML_READER_TYPE_ENTITY_REFERENCE
);
51 ENSURE_EQUAL( XML_READER_TYPE_ENTITY
, \
52 xmlreader_lite::XML_READER_TYPE_ENTITY
);
53 ENSURE_EQUAL( XML_READER_TYPE_PROCESSING_INSTRUCTION
, \
54 xmlreader_lite::XML_READER_TYPE_PROCESSING_INSTRUCTION
);
55 ENSURE_EQUAL( XML_READER_TYPE_COMMENT
, \
56 xmlreader_lite::XML_READER_TYPE_COMMENT
);
57 ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT
, \
58 xmlreader_lite::XML_READER_TYPE_DOCUMENT
);
59 ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT_TYPE
, \
60 xmlreader_lite::XML_READER_TYPE_DOCUMENT_TYPE
);
61 ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT_FRAGMENT
, \
62 xmlreader_lite::XML_READER_TYPE_DOCUMENT_FRAGMENT
);
63 ENSURE_EQUAL( XML_READER_TYPE_NOTATION
, \
64 xmlreader_lite::XML_READER_TYPE_NOTATION
);
65 ENSURE_EQUAL( XML_READER_TYPE_WHITESPACE
, \
66 xmlreader_lite::XML_READER_TYPE_WHITESPACE
);
67 ENSURE_EQUAL( XML_READER_TYPE_SIGNIFICANT_WHITESPACE
, \
68 xmlreader_lite::XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
69 ENSURE_EQUAL( XML_READER_TYPE_END_ELEMENT
, \
70 xmlreader_lite::XML_READER_TYPE_END_ELEMENT
);
71 ENSURE_EQUAL( XML_READER_TYPE_END_ENTITY
, \
72 xmlreader_lite::XML_READER_TYPE_END_ENTITY
);
73 ENSURE_EQUAL( XML_READER_TYPE_XML_DECLARATION
, \
74 xmlreader_lite::XML_READER_TYPE_XML_DECLARATION
);
77 const char * encoding
= 0;
78 if (0 == buf
.get_len()) {
79 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
80 "Cannot decode empty XML");
83 my_reader
= xmlReaderForMemory((const char*)buf
.get_data(), buf
.get_len(),
84 "uri:geller", encoding
, 0);
86 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
87 "Failed to create XML reader"); // no further information available
89 else xmlTextReaderSetErrorHandler(my_reader
, errorhandler
, this);
94 XmlReaderWrap::errorhandler(void * arg
, const char * msg
,
95 xmlParserSeverities severity
, xmlTextReaderLocatorPtr locator
)
97 //XmlReaderWrap *self = (XmlReaderWrap*)arg;
100 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNDEF
, // TODO create a new ET_
101 "XML error: %s at line %d", msg
, xmlTextReaderLocatorLineNumber(locator
));
104 XmlReaderWrap::~XmlReaderWrap()
106 xmlFreeTextReader(my_reader
);
112 int XmlReaderWrap::Read()
114 return last_status
= xmlTextReaderRead(my_reader
); // assign and return
117 // Debug version of Read(). Both are present to support linking
118 // non-debug clients to the debug library.
119 int XmlReaderWrap::ReadDbg(const char *where
)
124 static bool d
= !!getenv("DEBUG_XMLREADER");
126 last_status
= xmlTextReaderRead(my_reader
);
127 if (last_status
==1) {
128 int type
= NodeType();
129 const char * name
= (const char * )Name();
130 const char * uri
= (const char * )NamespaceUri();
131 int empty
= IsEmptyElement();
132 char closer
= type
== XML_READER_TYPE_DOCUMENT_TYPE
? '[' : (empty
? '/' : ' ');
133 printf("X%dX type=%2d, @%2d <%c{%s}%s%c>",
134 xmlTextReaderReadState(my_reader
), type
, xmlTextReaderDepth(my_reader
),
135 ((type
!=XML_READER_TYPE_END_ELEMENT
) ? ' ' : '/'),
136 uri
? uri
: "", name
, closer
);
138 else if (last_status
==0) {
139 fputs("XXX eof ", stdout
);
142 fputs("XXX error", stdout
);
144 printf("\t%s\n", where
);
150 return last_status
= xmlTextReaderRead(my_reader
); // assign and return
155 xmlChar
* XmlReaderWrap::ReadInnerXml()
156 { return xmlTextReaderReadInnerXml(my_reader
); }
159 xmlChar
* XmlReaderWrap::ReadOuterXml() // used by Charstring.cc
160 { return xmlTextReaderReadOuterXml(my_reader
); }
162 xmlChar
* XmlReaderWrap::ReadString() // used by Objid.cc
163 { return xmlTextReaderReadString(my_reader
); }
165 int XmlReaderWrap::Depth() // used everywhere
166 { return xmlTextReaderDepth(my_reader
); }
169 int XmlReaderWrap::ReadAttributeValue()
170 { return xmlTextReaderReadAttributeValue(my_reader
); }
172 int XmlReaderWrap::AttributeCount()
173 { return xmlTextReaderAttributeCount(my_reader
); }
175 int XmlReaderWrap::HasAttributes()
176 { return xmlTextReaderHasAttributes(my_reader
); }
178 int XmlReaderWrap::HasValue()
179 { return xmlTextReaderHasValue(my_reader
); }
181 int XmlReaderWrap::IsDefault()
182 { return xmlTextReaderIsDefault(my_reader
); }
185 int XmlReaderWrap::IsEmptyElement() // used often
186 { return xmlTextReaderIsEmptyElement(my_reader
); }
188 int XmlReaderWrap::NodeType()
189 { return xmlTextReaderNodeType(my_reader
); }
192 int XmlReaderWrap::QuoteChar()
193 { return xmlTextReaderQuoteChar(my_reader
); }
195 int XmlReaderWrap::ReadState()
196 { return xmlTextReaderReadState(my_reader
); }
199 int XmlReaderWrap::IsNamespaceDecl() // used while processing attributes
200 { return xmlTextReaderIsNamespaceDecl(my_reader
); }
203 const xmlChar
* XmlReaderWrap::BaseUri()
204 { return xmlTextReaderConstBaseUri(my_reader
); }
207 const xmlChar
* XmlReaderWrap::LocalName()
208 { return xmlTextReaderConstLocalName(my_reader
); }
210 const xmlChar
* XmlReaderWrap::Name()
211 { return xmlTextReaderConstName(my_reader
); }
213 const xmlChar
* XmlReaderWrap::NamespaceUri()
214 { return xmlTextReaderConstNamespaceUri(my_reader
); }
216 const xmlChar
* XmlReaderWrap::Prefix()
217 { return xmlTextReaderConstPrefix(my_reader
); }
220 const xmlChar
* XmlReaderWrap::XmlLang()
221 { return xmlTextReaderConstXmlLang(my_reader
); }
224 const xmlChar
* XmlReaderWrap::Value()
225 { return xmlTextReaderConstValue(my_reader
); }
227 xmlChar
* XmlReaderWrap::NewValue()
228 { return xmlTextReaderValue(my_reader
); }
230 xmlChar
* XmlReaderWrap::LookupNamespace( const xmlChar
*prefix
)
231 { return xmlTextReaderLookupNamespace(my_reader
,prefix
); }
234 int XmlReaderWrap::Close()
235 { return xmlTextReaderClose(my_reader
); }
237 xmlChar
* XmlReaderWrap::GetAttributeNo( int no
)
238 { return xmlTextReaderGetAttributeNo(my_reader
,no
); }
240 xmlChar
* XmlReaderWrap::GetAttribute( const xmlChar
*name
)
241 { return xmlTextReaderGetAttribute(my_reader
,name
); }
243 xmlChar
* XmlReaderWrap::GetAttributeNs( const xmlChar
*localName
, const xmlChar
*namespaceURI
)
244 { return xmlTextReaderGetAttributeNs(my_reader
,localName
,namespaceURI
); }
246 int XmlReaderWrap::MoveToAttributeNo( int no
)
247 { return xmlTextReaderMoveToAttributeNo(my_reader
,no
); }
250 int XmlReaderWrap::MoveToAttribute( const xmlChar
*name
)
251 { return xmlTextReaderMoveToAttribute(my_reader
,name
); }
253 //int XmlReaderWrap::MoveToAttributeNs( const xmlChar *localName, const xmlChar *namespaceURI)
254 //{ return xmlTextReaderMoveToAttributeNs(my_reader,localName,namespaceURI); }
256 #undef AdvanceAttribute
257 int XmlReaderWrap::AdvanceAttribute()
260 for (rez
= MoveToNextAttribute(); rez
==1; rez
= MoveToNextAttribute()) {
261 if (!xmlTextReaderIsNamespaceDecl(my_reader
)) break;
263 if (rez
!= 0) // success(1) or failure (-1)
265 // 0 means no more attributes. Back to the element.
266 rez
= xmlTextReaderMoveToElement(my_reader
);
267 return -(rez
== -1); // if -1, return -1 else return 0
270 int XmlReaderWrap::AdvanceAttributeDbg(const char *where
)
273 for (rez
= MoveToNextAttributeDbg(where
); rez
==1; rez
= MoveToNextAttributeDbg(where
)) {
274 if (!xmlTextReaderIsNamespaceDecl(my_reader
)) break;
276 if (rez
!= 0) // success(1) or failure (-1)
278 // 0 means no more attributes. Back to the element.
279 rez
= xmlTextReaderMoveToElement(my_reader
);
280 return -(rez
== -1); // if -1, return -1 else return 0
284 #undef MoveToFirstAttribute
285 int XmlReaderWrap::MoveToFirstAttribute()
286 { return xmlTextReaderMoveToFirstAttribute(my_reader
); }
288 int XmlReaderWrap::MoveToFirstAttributeDbg(const char *where
)
290 int ret
= xmlTextReaderMoveToFirstAttribute(my_reader
);
294 static bool d
= !!getenv("DEBUG_XMLREADER");
298 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
299 const xmlChar
* val
= xmlTextReaderConstValue(my_reader
);
300 printf("#%dX %s='%s'", xmlTextReaderReadState(my_reader
), name
, val
);
302 case 0: {// not found
303 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
304 printf("#%dX no attribute found in <%s>", xmlTextReaderReadState(my_reader
), name
);
310 printf("\t%s\n", where
);
313 //return xmlTextReaderMoveToFirstAttribute(my_reader);
318 #undef MoveToNextAttribute
319 int XmlReaderWrap::MoveToNextAttribute()
320 { return xmlTextReaderMoveToNextAttribute(my_reader
); }
322 int XmlReaderWrap::MoveToNextAttributeDbg(const char *where
)
324 int ret
= xmlTextReaderMoveToNextAttribute(my_reader
);
328 static bool d
= !!getenv("DEBUG_XMLREADER");
332 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
333 const xmlChar
* val
= xmlTextReaderConstValue(my_reader
);
334 printf("X%dX %s='%s'", xmlTextReaderReadState(my_reader
), name
, val
);
336 case 0: {// not found
337 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
338 printf("X%dX no more attributes found after '%s'", xmlTextReaderReadState(my_reader
), name
);
344 printf("\t%s\n", where
);
347 //return xmlTextReaderMoveToNextAttribute(my_reader);
353 int XmlReaderWrap::MoveToElement()
354 { return xmlTextReaderMoveToElement(my_reader
); }
356 int XmlReaderWrap::MoveToElementDbg(const char *where
)
358 int ret
= xmlTextReaderMoveToElement(my_reader
);
362 static bool d
= !!getenv("DEBUG_XMLREADER");
364 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
365 const xmlChar
* val
= xmlTextReaderConstValue(my_reader
);
366 printf("X%dX <%s='%s'>\n", xmlTextReaderReadState(my_reader
), name
, val
);
369 printf("\t%s\n", where
);
375 //int XmlReaderWrap::GetParserLineNumber()
376 //{ return xmlTextReaderGetParserLineNumber(my_reader); }
378 //int XmlReaderWrap::GetParserColumnNumber()
379 //{ return xmlTextReaderGetParserColumnNumber(my_reader); }
382 int XmlReaderWrap::Next()
383 { return xmlTextReaderNext(my_reader
); }
385 int XmlReaderWrap::NextSibling()
386 { return xmlTextReaderNextSibling(my_reader
); }
388 int XmlReaderWrap::Normalization()
389 { return xmlTextReaderNormalization(my_reader
); }
391 int XmlReaderWrap::SetParserProp( int prop
, int value
)
392 { return xmlTextReaderSetParserProp(my_reader
,prop
,value
); }
394 int XmlReaderWrap::GetParserProp( int prop
)
395 { return xmlTextReaderGetParserProp(my_reader
,prop
); }
397 xmlParserInputBufferPtr
XmlReaderWrap::GetRemainder()
398 { return xmlTextReaderGetRemainder(my_reader
); }
400 xmlNodePtr
XmlReaderWrap::CurrentNode()
401 { return xmlTextReaderCurrentNode(my_reader
); }
403 xmlNodePtr
XmlReaderWrap::Preserve()
404 { return xmlTextReaderPreserve(my_reader
); }
406 int XmlReaderWrap::PreservePattern( const xmlChar
*pattern
, const xmlChar
**namespaces
)
407 { return xmlTextReaderPreservePattern(my_reader
,pattern
,namespaces
); }
409 xmlDocPtr
XmlReaderWrap::CurrentDoc()
410 { return xmlTextReaderCurrentDoc(my_reader
); }
412 xmlNodePtr
XmlReaderWrap::Expand()
413 { return xmlTextReaderExpand(my_reader
); }
415 int XmlReaderWrap::IsValid()
416 { return xmlTextReaderIsValid(my_reader
); }
418 int XmlReaderWrap::RelaxNGValidate( const char *rng
)
419 { return xmlTextReaderRelaxNGValidate(my_reader
,rng
); }
421 int XmlReaderWrap::RelaxNGSetSchema( xmlRelaxNGPtr schema
)
422 { return xmlTextReaderRelaxNGSetSchema(my_reader
,schema
); }
424 int XmlReaderWrap::SchemaValidate( const char *xsd
)
425 { return xmlTextReaderSchemaValidate(my_reader
,xsd
); }
427 int XmlReaderWrap::SchemaValidateCtxt( xmlSchemaValidCtxtPtr ctxt
, int options
)
428 { return xmlTextReaderSchemaValidateCtxt(my_reader
,ctxt
,options
); }
430 int XmlReaderWrap::SetSchema( xmlSchemaPtr schema
)
431 { return xmlTextReaderSetSchema(my_reader
,schema
); }
433 int XmlReaderWrap::Standalone()
434 { return xmlTextReaderStandalone(my_reader
); }
437 long XmlReaderWrap::ByteConsumed()
438 { return xmlTextReaderByteConsumed(my_reader
); }
440 //int XmlReaderWrap::LocatorLineNumber(xmlTextReaderLocatorPtr locator)
441 //{ return xmlTextReaderLocatorLineNumber(locator); }
443 //xmlChar * XmlReaderWrap::LocatorBaseURI(xmlTextReaderLocatorPtr locator)
444 //{ return xmlTextReaderLocatorBaseURI(locator); }
447 void XmlReaderWrap::SetErrorHandler( xmlTextReaderErrorFunc f
, void *arg
)
448 { return xmlTextReaderSetErrorHandler(my_reader
,f
,arg
); }
450 void XmlReaderWrap::SetStructuredErrorHandler( xmlStructuredErrorFunc f
, void *arg
)
451 { return xmlTextReaderSetStructuredErrorHandler(my_reader
,f
,arg
); }
453 void XmlReaderWrap::GetErrorHandler( xmlTextReaderErrorFunc
*f
, void **arg
)
454 { return xmlTextReaderGetErrorHandler(my_reader
,f
,arg
); }
458 void XmlReaderWrap::Status()
460 //const xmlChar *string = xmlTextReaderConstString (my_reader);
461 const xmlChar
*baseuri
= xmlTextReaderConstBaseUri (my_reader
);
462 const xmlChar
*localname
= xmlTextReaderConstLocalName (my_reader
);
463 const xmlChar
*name
= xmlTextReaderConstName (my_reader
);
464 const xmlChar
*ns_uri
= xmlTextReaderConstNamespaceUri(my_reader
);
465 const xmlChar
*prefix
= xmlTextReaderConstPrefix (my_reader
);
466 const xmlChar
*lang
= xmlTextReaderConstXmlLang (my_reader
);
467 const xmlChar
*value
= xmlTextReaderConstValue (my_reader
);
468 const xmlChar
*encoding
= xmlTextReaderConstEncoding (my_reader
);
469 const xmlChar
*version
= xmlTextReaderConstXmlVersion(my_reader
);
471 printf ("XML reader %d deep:\n"
474 "\tlocalname = '%s'\n"
477 "\txml lang = '%s'\n"
479 "\tencoding = '%s'\n"
481 , xmlTextReaderDepth(my_reader
)
485 , name
, (xmlTextReaderIsEmptyElement(my_reader
) ? "/" : "")