1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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
7 ///////////////////////////////////////////////////////////////////////////////
11 * Created on: 19-Nov-2008
15 #include <libxml/xmlreader.h>
16 #include "XmlReader.hh"
17 #include "static_check.h"
21 XmlReaderWrap::XmlReaderWrap(TTCN_Buffer
& buf
)
24 // compile-time safety checks
25 ENSURE_EQUAL( XML_PARSER_SEVERITY_VALIDITY_WARNING
, \
26 xmlreader_lite::XML_PARSER_SEVERITY_VALIDITY_WARNING
);
27 ENSURE_EQUAL( XML_PARSER_SEVERITY_VALIDITY_ERROR
, \
28 xmlreader_lite::XML_PARSER_SEVERITY_VALIDITY_ERROR
);
29 ENSURE_EQUAL( XML_PARSER_SEVERITY_WARNING
, \
30 xmlreader_lite::XML_PARSER_SEVERITY_WARNING
);
31 ENSURE_EQUAL( XML_PARSER_SEVERITY_ERROR
, \
32 xmlreader_lite::XML_PARSER_SEVERITY_ERROR
);
34 ENSURE_EQUAL( XML_READER_TYPE_NONE
, \
35 xmlreader_lite::XML_READER_TYPE_NONE
);
36 ENSURE_EQUAL( XML_READER_TYPE_ELEMENT
, \
37 xmlreader_lite::XML_READER_TYPE_ELEMENT
);
38 ENSURE_EQUAL( XML_READER_TYPE_ATTRIBUTE
, \
39 xmlreader_lite::XML_READER_TYPE_ATTRIBUTE
);
40 ENSURE_EQUAL( XML_READER_TYPE_TEXT
, \
41 xmlreader_lite::XML_READER_TYPE_TEXT
);
42 ENSURE_EQUAL( XML_READER_TYPE_CDATA
, \
43 xmlreader_lite::XML_READER_TYPE_CDATA
);
44 ENSURE_EQUAL( XML_READER_TYPE_ENTITY_REFERENCE
, \
45 xmlreader_lite::XML_READER_TYPE_ENTITY_REFERENCE
);
46 ENSURE_EQUAL( XML_READER_TYPE_ENTITY
, \
47 xmlreader_lite::XML_READER_TYPE_ENTITY
);
48 ENSURE_EQUAL( XML_READER_TYPE_PROCESSING_INSTRUCTION
, \
49 xmlreader_lite::XML_READER_TYPE_PROCESSING_INSTRUCTION
);
50 ENSURE_EQUAL( XML_READER_TYPE_COMMENT
, \
51 xmlreader_lite::XML_READER_TYPE_COMMENT
);
52 ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT
, \
53 xmlreader_lite::XML_READER_TYPE_DOCUMENT
);
54 ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT_TYPE
, \
55 xmlreader_lite::XML_READER_TYPE_DOCUMENT_TYPE
);
56 ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT_FRAGMENT
, \
57 xmlreader_lite::XML_READER_TYPE_DOCUMENT_FRAGMENT
);
58 ENSURE_EQUAL( XML_READER_TYPE_NOTATION
, \
59 xmlreader_lite::XML_READER_TYPE_NOTATION
);
60 ENSURE_EQUAL( XML_READER_TYPE_WHITESPACE
, \
61 xmlreader_lite::XML_READER_TYPE_WHITESPACE
);
62 ENSURE_EQUAL( XML_READER_TYPE_SIGNIFICANT_WHITESPACE
, \
63 xmlreader_lite::XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
64 ENSURE_EQUAL( XML_READER_TYPE_END_ELEMENT
, \
65 xmlreader_lite::XML_READER_TYPE_END_ELEMENT
);
66 ENSURE_EQUAL( XML_READER_TYPE_END_ENTITY
, \
67 xmlreader_lite::XML_READER_TYPE_END_ENTITY
);
68 ENSURE_EQUAL( XML_READER_TYPE_XML_DECLARATION
, \
69 xmlreader_lite::XML_READER_TYPE_XML_DECLARATION
);
72 const char * encoding
= 0;
73 if (0 == buf
.get_len()) {
74 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
75 "Cannot decode empty XML");
78 my_reader
= xmlReaderForMemory((const char*)buf
.get_data(), buf
.get_len(),
79 "uri:geller", encoding
, 0);
81 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
82 "Failed to create XML reader"); // no further information available
84 else xmlTextReaderSetErrorHandler(my_reader
, errorhandler
, this);
89 XmlReaderWrap::errorhandler(void * arg
, const char * msg
,
90 xmlParserSeverities severity
, xmlTextReaderLocatorPtr locator
)
92 //XmlReaderWrap *self = (XmlReaderWrap*)arg;
95 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNDEF
, // TODO create a new ET_
96 "XML error: %s at line %d", msg
, xmlTextReaderLocatorLineNumber(locator
));
99 XmlReaderWrap::~XmlReaderWrap()
101 xmlFreeTextReader(my_reader
);
107 int XmlReaderWrap::Read()
109 return last_status
= xmlTextReaderRead(my_reader
); // assign and return
112 // Debug version of Read(). Both are present to support linking
113 // non-debug clients to the debug library.
114 int XmlReaderWrap::ReadDbg(const char *where
)
119 static bool d
= !!getenv("DEBUG_XMLREADER");
121 last_status
= xmlTextReaderRead(my_reader
);
122 if (last_status
==1) {
123 int type
= NodeType();
124 const char * name
= (const char * )Name();
125 const char * uri
= (const char * )NamespaceUri();
126 int empty
= IsEmptyElement();
127 char closer
= type
== XML_READER_TYPE_DOCUMENT_TYPE
? '[' : (empty
? '/' : ' ');
128 printf("X%dX type=%2d, @%2d <%c{%s}%s%c>",
129 xmlTextReaderReadState(my_reader
), type
, xmlTextReaderDepth(my_reader
),
130 ((type
!=XML_READER_TYPE_END_ELEMENT
) ? ' ' : '/'),
131 uri
? uri
: "", name
, closer
);
133 else if (last_status
==0) {
134 fputs("XXX eof ", stdout
);
137 fputs("XXX error", stdout
);
139 printf("\t%s\n", where
);
145 return last_status
= xmlTextReaderRead(my_reader
); // assign and return
150 xmlChar
* XmlReaderWrap::ReadInnerXml()
151 { return xmlTextReaderReadInnerXml(my_reader
); }
154 xmlChar
* XmlReaderWrap::ReadOuterXml() // used by Charstring.cc
155 { return xmlTextReaderReadOuterXml(my_reader
); }
157 xmlChar
* XmlReaderWrap::ReadString() // used by Objid.cc
158 { return xmlTextReaderReadString(my_reader
); }
160 int XmlReaderWrap::Depth() // used everywhere
161 { return xmlTextReaderDepth(my_reader
); }
164 int XmlReaderWrap::ReadAttributeValue()
165 { return xmlTextReaderReadAttributeValue(my_reader
); }
167 int XmlReaderWrap::AttributeCount()
168 { return xmlTextReaderAttributeCount(my_reader
); }
170 int XmlReaderWrap::HasAttributes()
171 { return xmlTextReaderHasAttributes(my_reader
); }
173 int XmlReaderWrap::HasValue()
174 { return xmlTextReaderHasValue(my_reader
); }
176 int XmlReaderWrap::IsDefault()
177 { return xmlTextReaderIsDefault(my_reader
); }
180 int XmlReaderWrap::IsEmptyElement() // used often
181 { return xmlTextReaderIsEmptyElement(my_reader
); }
183 int XmlReaderWrap::NodeType()
184 { return xmlTextReaderNodeType(my_reader
); }
187 int XmlReaderWrap::QuoteChar()
188 { return xmlTextReaderQuoteChar(my_reader
); }
190 int XmlReaderWrap::ReadState()
191 { return xmlTextReaderReadState(my_reader
); }
194 int XmlReaderWrap::IsNamespaceDecl() // used while processing attributes
195 { return xmlTextReaderIsNamespaceDecl(my_reader
); }
198 const xmlChar
* XmlReaderWrap::BaseUri()
199 { return xmlTextReaderConstBaseUri(my_reader
); }
202 const xmlChar
* XmlReaderWrap::LocalName()
203 { return xmlTextReaderConstLocalName(my_reader
); }
205 const xmlChar
* XmlReaderWrap::Name()
206 { return xmlTextReaderConstName(my_reader
); }
208 const xmlChar
* XmlReaderWrap::NamespaceUri()
209 { return xmlTextReaderConstNamespaceUri(my_reader
); }
211 const xmlChar
* XmlReaderWrap::Prefix()
212 { return xmlTextReaderConstPrefix(my_reader
); }
215 const xmlChar
* XmlReaderWrap::XmlLang()
216 { return xmlTextReaderConstXmlLang(my_reader
); }
219 const xmlChar
* XmlReaderWrap::Value()
220 { return xmlTextReaderConstValue(my_reader
); }
222 xmlChar
* XmlReaderWrap::NewValue()
223 { return xmlTextReaderValue(my_reader
); }
225 xmlChar
* XmlReaderWrap::LookupNamespace( const xmlChar
*prefix
)
226 { return xmlTextReaderLookupNamespace(my_reader
,prefix
); }
229 int XmlReaderWrap::Close()
230 { return xmlTextReaderClose(my_reader
); }
232 xmlChar
* XmlReaderWrap::GetAttributeNo( int no
)
233 { return xmlTextReaderGetAttributeNo(my_reader
,no
); }
235 xmlChar
* XmlReaderWrap::GetAttribute( const xmlChar
*name
)
236 { return xmlTextReaderGetAttribute(my_reader
,name
); }
238 xmlChar
* XmlReaderWrap::GetAttributeNs( const xmlChar
*localName
, const xmlChar
*namespaceURI
)
239 { return xmlTextReaderGetAttributeNs(my_reader
,localName
,namespaceURI
); }
241 int XmlReaderWrap::MoveToAttributeNo( int no
)
242 { return xmlTextReaderMoveToAttributeNo(my_reader
,no
); }
245 int XmlReaderWrap::MoveToAttribute( const xmlChar
*name
)
246 { return xmlTextReaderMoveToAttribute(my_reader
,name
); }
248 //int XmlReaderWrap::MoveToAttributeNs( const xmlChar *localName, const xmlChar *namespaceURI)
249 //{ return xmlTextReaderMoveToAttributeNs(my_reader,localName,namespaceURI); }
251 #undef AdvanceAttribute
252 int XmlReaderWrap::AdvanceAttribute()
255 for (rez
= MoveToNextAttribute(); rez
==1; rez
= MoveToNextAttribute()) {
256 if (!xmlTextReaderIsNamespaceDecl(my_reader
)) break;
258 if (rez
!= 0) // success(1) or failure (-1)
260 // 0 means no more attributes. Back to the element.
261 rez
= xmlTextReaderMoveToElement(my_reader
);
262 return -(rez
== -1); // if -1, return -1 else return 0
265 int XmlReaderWrap::AdvanceAttributeDbg(const char *where
)
268 for (rez
= MoveToNextAttributeDbg(where
); rez
==1; rez
= MoveToNextAttributeDbg(where
)) {
269 if (!xmlTextReaderIsNamespaceDecl(my_reader
)) break;
271 if (rez
!= 0) // success(1) or failure (-1)
273 // 0 means no more attributes. Back to the element.
274 rez
= xmlTextReaderMoveToElement(my_reader
);
275 return -(rez
== -1); // if -1, return -1 else return 0
279 #undef MoveToFirstAttribute
280 int XmlReaderWrap::MoveToFirstAttribute()
281 { return xmlTextReaderMoveToFirstAttribute(my_reader
); }
283 int XmlReaderWrap::MoveToFirstAttributeDbg(const char *where
)
285 int ret
= xmlTextReaderMoveToFirstAttribute(my_reader
);
289 static bool d
= !!getenv("DEBUG_XMLREADER");
293 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
294 const xmlChar
* val
= xmlTextReaderConstValue(my_reader
);
295 printf("#%dX %s='%s'", xmlTextReaderReadState(my_reader
), name
, val
);
297 case 0: {// not found
298 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
299 printf("#%dX no attribute found in <%s>", xmlTextReaderReadState(my_reader
), name
);
305 printf("\t%s\n", where
);
308 //return xmlTextReaderMoveToFirstAttribute(my_reader);
313 #undef MoveToNextAttribute
314 int XmlReaderWrap::MoveToNextAttribute()
315 { return xmlTextReaderMoveToNextAttribute(my_reader
); }
317 int XmlReaderWrap::MoveToNextAttributeDbg(const char *where
)
319 int ret
= xmlTextReaderMoveToNextAttribute(my_reader
);
323 static bool d
= !!getenv("DEBUG_XMLREADER");
327 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
328 const xmlChar
* val
= xmlTextReaderConstValue(my_reader
);
329 printf("X%dX %s='%s'", xmlTextReaderReadState(my_reader
), name
, val
);
331 case 0: {// not found
332 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
333 printf("X%dX no more attributes found after '%s'", xmlTextReaderReadState(my_reader
), name
);
339 printf("\t%s\n", where
);
342 //return xmlTextReaderMoveToNextAttribute(my_reader);
348 int XmlReaderWrap::MoveToElement()
349 { return xmlTextReaderMoveToElement(my_reader
); }
351 int XmlReaderWrap::MoveToElementDbg(const char *where
)
353 int ret
= xmlTextReaderMoveToElement(my_reader
);
357 static bool d
= !!getenv("DEBUG_XMLREADER");
359 const xmlChar
* name
= xmlTextReaderConstLocalName(my_reader
);
360 const xmlChar
* val
= xmlTextReaderConstValue(my_reader
);
361 printf("X%dX <%s='%s'>\n", xmlTextReaderReadState(my_reader
), name
, val
);
364 printf("\t%s\n", where
);
370 //int XmlReaderWrap::GetParserLineNumber()
371 //{ return xmlTextReaderGetParserLineNumber(my_reader); }
373 //int XmlReaderWrap::GetParserColumnNumber()
374 //{ return xmlTextReaderGetParserColumnNumber(my_reader); }
377 int XmlReaderWrap::Next()
378 { return xmlTextReaderNext(my_reader
); }
380 int XmlReaderWrap::NextSibling()
381 { return xmlTextReaderNextSibling(my_reader
); }
383 int XmlReaderWrap::Normalization()
384 { return xmlTextReaderNormalization(my_reader
); }
386 int XmlReaderWrap::SetParserProp( int prop
, int value
)
387 { return xmlTextReaderSetParserProp(my_reader
,prop
,value
); }
389 int XmlReaderWrap::GetParserProp( int prop
)
390 { return xmlTextReaderGetParserProp(my_reader
,prop
); }
392 xmlParserInputBufferPtr
XmlReaderWrap::GetRemainder()
393 { return xmlTextReaderGetRemainder(my_reader
); }
395 xmlNodePtr
XmlReaderWrap::CurrentNode()
396 { return xmlTextReaderCurrentNode(my_reader
); }
398 xmlNodePtr
XmlReaderWrap::Preserve()
399 { return xmlTextReaderPreserve(my_reader
); }
401 int XmlReaderWrap::PreservePattern( const xmlChar
*pattern
, const xmlChar
**namespaces
)
402 { return xmlTextReaderPreservePattern(my_reader
,pattern
,namespaces
); }
404 xmlDocPtr
XmlReaderWrap::CurrentDoc()
405 { return xmlTextReaderCurrentDoc(my_reader
); }
407 xmlNodePtr
XmlReaderWrap::Expand()
408 { return xmlTextReaderExpand(my_reader
); }
410 int XmlReaderWrap::IsValid()
411 { return xmlTextReaderIsValid(my_reader
); }
413 int XmlReaderWrap::RelaxNGValidate( const char *rng
)
414 { return xmlTextReaderRelaxNGValidate(my_reader
,rng
); }
416 int XmlReaderWrap::RelaxNGSetSchema( xmlRelaxNGPtr schema
)
417 { return xmlTextReaderRelaxNGSetSchema(my_reader
,schema
); }
419 int XmlReaderWrap::SchemaValidate( const char *xsd
)
420 { return xmlTextReaderSchemaValidate(my_reader
,xsd
); }
422 int XmlReaderWrap::SchemaValidateCtxt( xmlSchemaValidCtxtPtr ctxt
, int options
)
423 { return xmlTextReaderSchemaValidateCtxt(my_reader
,ctxt
,options
); }
425 int XmlReaderWrap::SetSchema( xmlSchemaPtr schema
)
426 { return xmlTextReaderSetSchema(my_reader
,schema
); }
428 int XmlReaderWrap::Standalone()
429 { return xmlTextReaderStandalone(my_reader
); }
432 long XmlReaderWrap::ByteConsumed()
433 { return xmlTextReaderByteConsumed(my_reader
); }
435 //int XmlReaderWrap::LocatorLineNumber(xmlTextReaderLocatorPtr locator)
436 //{ return xmlTextReaderLocatorLineNumber(locator); }
438 //xmlChar * XmlReaderWrap::LocatorBaseURI(xmlTextReaderLocatorPtr locator)
439 //{ return xmlTextReaderLocatorBaseURI(locator); }
442 void XmlReaderWrap::SetErrorHandler( xmlTextReaderErrorFunc f
, void *arg
)
443 { return xmlTextReaderSetErrorHandler(my_reader
,f
,arg
); }
445 void XmlReaderWrap::SetStructuredErrorHandler( xmlStructuredErrorFunc f
, void *arg
)
446 { return xmlTextReaderSetStructuredErrorHandler(my_reader
,f
,arg
); }
448 void XmlReaderWrap::GetErrorHandler( xmlTextReaderErrorFunc
*f
, void **arg
)
449 { return xmlTextReaderGetErrorHandler(my_reader
,f
,arg
); }
453 void XmlReaderWrap::Status()
455 //const xmlChar *string = xmlTextReaderConstString (my_reader);
456 const xmlChar
*baseuri
= xmlTextReaderConstBaseUri (my_reader
);
457 const xmlChar
*localname
= xmlTextReaderConstLocalName (my_reader
);
458 const xmlChar
*name
= xmlTextReaderConstName (my_reader
);
459 const xmlChar
*ns_uri
= xmlTextReaderConstNamespaceUri(my_reader
);
460 const xmlChar
*prefix
= xmlTextReaderConstPrefix (my_reader
);
461 const xmlChar
*lang
= xmlTextReaderConstXmlLang (my_reader
);
462 const xmlChar
*value
= xmlTextReaderConstValue (my_reader
);
463 const xmlChar
*encoding
= xmlTextReaderConstEncoding (my_reader
);
464 const xmlChar
*version
= xmlTextReaderConstXmlVersion(my_reader
);
466 printf ("XML reader %d deep:\n"
469 "\tlocalname = '%s'\n"
472 "\txml lang = '%s'\n"
474 "\tencoding = '%s'\n"
476 , xmlTextReaderDepth(my_reader
)
480 , name
, (xmlTextReaderIsEmptyElement(my_reader
) ? "/" : "")