28 #include <xercesc/sax2/Attributes.hpp>
29 #include <xercesc/sax2/XMLReaderFactory.hpp>
31 #include <xercesc/util/BinInputStream.hpp>
32 #include <xercesc/util/TransService.hpp>
52 chLatin_m, chLatin_i, chLatin_n, chLatin_i, chLatin_m, chLatin_u, chLatin_m, chNull
55 chLatin_m, chLatin_a, chLatin_x, chLatin_i, chLatin_m, chLatin_u, chLatin_m, chNull
57 static const XMLCh
att_scale[] = { chLatin_s, chLatin_c, chLatin_a, chLatin_l, chLatin_e, chNull };
58 static const XMLCh
att_offset[] = { chLatin_o, chLatin_f, chLatin_f, chLatin_s, chLatin_e, chLatin_t, chNull };
59 static const XMLCh
att_precision[] = { chLatin_p, chLatin_r, chLatin_e, chLatin_c, chLatin_i,
60 chLatin_s, chLatin_i, chLatin_o, chLatin_n, chNull };
62 chLatin_a, chLatin_l, chLatin_l, chLatin_o, chLatin_w, chLatin_H, chLatin_e, chLatin_t, chLatin_e,
63 chLatin_r, chLatin_o, chLatin_g, chLatin_e, chLatin_n, chLatin_e, chLatin_o, chLatin_u, chLatin_s,
64 chLatin_C, chLatin_h, chLatin_i, chLatin_l, chLatin_d, chLatin_r, chLatin_e, chLatin_n, chNull
66 static const XMLCh
att_fileOffset[] = { chLatin_f, chLatin_i, chLatin_l, chLatin_e, chLatin_O, chLatin_f,
67 chLatin_f, chLatin_s, chLatin_e, chLatin_t, chNull };
69 static const XMLCh
att_type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
70 static const XMLCh
att_length[] = { chLatin_l, chLatin_e, chLatin_n, chLatin_g, chLatin_t, chLatin_h, chNull };
71 static const XMLCh
att_recordCount[] = { chLatin_r, chLatin_e, chLatin_c, chLatin_o, chLatin_r, chLatin_d,
72 chLatin_C, chLatin_o, chLatin_u, chLatin_n, chLatin_t, chNull };
76 #if defined( _MSC_VER )
77 return _atoi64( inStr.c_str() );
78 #elif defined( __GNUC__ )
79 return strtoll( inStr.c_str(),
nullptr, 10 );
81 #error "Need to define string to long long conversion for this compiler"
99 return ( logicalPosition_ );
101 XMLSize_t readBytes( XMLByte *
const toFill,
const XMLSize_t maxToRead )
override;
110 uint64_t logicalStart_;
111 uint64_t logicalLength_;
112 uint64_t logicalPosition_;
116 cf_( cf ), logicalStart_( logicalStart ), logicalLength_( logicalLength ), logicalPosition_( logicalStart )
122 if ( logicalPosition_ > logicalStart_ + logicalLength_ )
125 int64_t available = logicalStart_ + logicalLength_ - logicalPosition_;
126 if ( available <= 0 )
133 size_t maxToRead_size = maxToRead;
136 size_t available_size;
137 if (
sizeof(
size_t ) >=
sizeof( int64_t ) )
140 available_size =
static_cast<size_t>( available );
149 if ( size_max < available )
151 available_size =
static_cast<size_t>( size_max );
155 available_size =
static_cast<size_t>( available );
159 size_t readCount =
std::min( maxToRead_size, available_size );
161 cf_->
seek( logicalPosition_ );
162 cf_->
read(
reinterpret_cast<char *
>( toFill ), readCount );
163 logicalPosition_ += readCount;
164 return ( readCount );
170 E57XmlFileInputSource::E57XmlFileInputSource(
CheckedFile *cf, uint64_t logicalStart, uint64_t logicalLength ) :
171 InputSource(
"E57File",
172 XMLPlatformUtils::fgMemoryManager ),
175 cf_( cf ), logicalStart_( logicalStart ), logicalLength_( logicalLength )
187 E57XmlParser::ParseInfo::ParseInfo() :
188 nodeType( static_cast<
NodeType>( 0 ) ), minimum( 0 ), maximum( 0 ), scale( 0 ),
offset( 0 ),
189 precision( static_cast<
FloatPrecision>( 0 ) ), floatMinimum( 0 ), floatMaximum( 0 ), fileOffset( 0 ),
length( 0 ),
190 allowHeterogeneousChildren( false ), recordCount( 0 )
194 void E57XmlParser::ParseInfo::dump(
int indent, std::ostream &os )
const
202 os <<
space( indent ) <<
"floatMinimum: " << floatMinimum <<
std::endl;
203 os <<
space( indent ) <<
"floatMaximum: " << floatMaximum <<
std::endl;
204 os <<
space( indent ) <<
"fileOffset: " << fileOffset <<
std::endl;
206 os <<
space( indent ) <<
"allowHeterogeneousChildren: " << allowHeterogeneousChildren <<
std::endl;
207 os <<
space( indent ) <<
"recordCount: " << recordCount <<
std::endl;
216 os <<
space( indent ) <<
"childText: \"" << childText <<
"\"" <<
std::endl;
232 XMLPlatformUtils::Terminate();
240 XMLPlatformUtils::Initialize();
242 catch (
const XMLException &ex )
246 "parserMessage=" +
ustring( XMLString::transcode( ex.getMessage() ) ) );
249 xmlReader = XMLReaderFactory::createXMLReader();
251 if ( xmlReader ==
nullptr )
257 xmlReader->setFeature( XMLUni::fgSAX2CoreValidation,
true );
258 xmlReader->setFeature( XMLUni::fgXercesDynamic,
true );
259 xmlReader->setFeature( XMLUni::fgSAX2CoreNameSpaces,
true );
260 xmlReader->setFeature( XMLUni::fgXercesSchema,
true );
261 xmlReader->setFeature( XMLUni::fgXercesSchemaFullChecking,
true );
262 xmlReader->setFeature( XMLUni::fgSAX2CoreNameSpacePrefixes,
true );
264 xmlReader->setContentHandler(
this );
265 xmlReader->setErrorHandler(
this );
270 xmlReader->parse( inputSource );
273 void E57XmlParser::startElement(
const XMLCh *
const uri,
const XMLCh *
const localName,
const XMLCh *
const qName,
274 const Attributes &attributes )
276 #ifdef E57_MAX_VERBOSE
277 std::cout <<
"startElement" <<
std::endl;
278 std::cout <<
space( 2 ) <<
"URI: " << toUString( uri ) <<
std::endl;
279 std::cout <<
space( 2 ) <<
"localName: " << toUString( localName ) <<
std::endl;
280 std::cout <<
space( 2 ) <<
"qName: " << toUString( qName ) <<
std::endl;
282 for (
size_t i = 0; i < attributes.getLength(); i++ )
285 std::cout <<
space( 4 ) <<
"URI: " << toUString( attributes.getURI( i ) ) <<
std::endl;
286 std::cout <<
space( 4 ) <<
"localName: " << toUString( attributes.getLocalName( i ) ) <<
std::endl;
287 std::cout <<
space( 4 ) <<
"qName: " << toUString( attributes.getQName( i ) ) <<
std::endl;
288 std::cout <<
space( 4 ) <<
"value: " << toUString( attributes.getValue( i ) ) <<
std::endl;
299 if ( node_type ==
"Integer" )
301 #ifdef E57_MAX_VERBOSE
302 std::cout <<
"got a Integer" <<
std::endl;
307 if ( isAttributeDefined( attributes,
att_minimum ) )
316 pi.minimum = E57_INT64_MIN;
319 if ( isAttributeDefined( attributes,
att_maximum ) )
328 pi.maximum = E57_INT64_MAX;
334 else if ( node_type ==
"ScaledInteger" )
336 #ifdef E57_MAX_VERBOSE
337 std::cout <<
"got a ScaledInteger" <<
std::endl;
342 if ( isAttributeDefined( attributes,
att_minimum ) )
351 pi.minimum = E57_INT64_MIN;
354 if ( isAttributeDefined( attributes,
att_maximum ) )
363 pi.maximum = E57_INT64_MAX;
366 if ( isAttributeDefined( attributes,
att_scale ) )
369 pi.scale = atof( scale_str.c_str() );
377 if ( isAttributeDefined( attributes,
att_offset ) )
380 pi.offset = atof( offset_str.c_str() );
391 else if ( node_type ==
"Float" )
393 #ifdef E57_MAX_VERBOSE
401 if ( precision_str ==
"single" )
403 else if ( precision_str ==
"double" )
410 "precisionString=" + precision_str +
" fileName=" + imf_->fileName() +
411 " uri=" + toUString( uri ) +
" localName=" + toUString( localName ) +
412 " qName=" + toUString( qName ) );
421 if ( isAttributeDefined( attributes,
att_minimum ) )
424 pi.floatMinimum = atof( minimum_str.c_str() );
432 pi.floatMinimum = E57_FLOAT_MIN;
436 pi.floatMinimum = E57_DOUBLE_MIN;
440 if ( isAttributeDefined( attributes,
att_maximum ) )
443 pi.floatMaximum = atof( maximum_str.c_str() );
450 pi.floatMaximum = E57_FLOAT_MAX;
453 pi.floatMaximum = E57_DOUBLE_MAX;
459 else if ( node_type ==
"String" )
461 #ifdef E57_MAX_VERBOSE
462 std::cout <<
"got a String" <<
std::endl;
469 else if ( node_type ==
"Blob" )
471 #ifdef E57_MAX_VERBOSE
491 else if ( node_type ==
"Structure" )
493 #ifdef E57_MAX_VERBOSE
494 std::cout <<
"got a Structure" <<
std::endl;
499 if ( toUString( localName ) ==
"e57Root" )
503 bool gotDefault =
false;
504 for (
size_t i = 0; i < attributes.getLength(); i++ )
507 if ( toUString( attributes.getQName( i ) ) ==
"xmlns" )
510 std::cout <<
"declared default namespace, URI=" << toUString( attributes.getValue( i ) ) <<
std::endl;
512 imf_->extensionsAdd(
"", toUString( attributes.getValue( i ) ) );
517 if ( toUString( attributes.getURI( i ) ) ==
"http://www.w3.org/2000/xmlns/" )
520 cout <<
"declared extension, prefix=" << toUString( attributes.getLocalName( i ) )
521 <<
" URI=" << toUString( attributes.getValue( i ) ) <<
std::endl;
523 imf_->extensionsAdd( toUString( attributes.getLocalName( i ) ), toUString( attributes.getValue( i ) ) );
531 "fileName=" + imf_->fileName() +
" uri=" + toUString( uri ) +
532 " localName=" + toUString( localName ) +
" qName=" + toUString( qName ) );
538 pi.container_ni = s_ni;
542 if ( toUString( localName ) ==
"e57Root" )
544 s_ni->setAttachedRecursive();
550 else if ( node_type ==
"Vector" )
552 #ifdef E57_MAX_VERBOSE
553 std::cout <<
"got a Vector" <<
std::endl;
565 pi.allowHeterogeneousChildren =
false;
569 pi.allowHeterogeneousChildren =
true;
574 "allowHeterogeneousChildren=" +
toString(
i64 ) +
"fileName=" + imf_->fileName() +
575 " uri=" + toUString( uri ) +
" localName=" + toUString( localName ) +
576 " qName=" + toUString( qName ) );
582 pi.allowHeterogeneousChildren =
false;
586 std::shared_ptr<VectorNodeImpl> v_ni(
new VectorNodeImpl( imf_, pi.allowHeterogeneousChildren ) );
587 pi.container_ni = v_ni;
592 else if ( node_type ==
"CompressedVector" )
594 #ifdef E57_MAX_VERBOSE
595 std::cout <<
"got a CompressedVector" <<
std::endl;
611 cv_ni->setRecordCount( pi.recordCount );
612 cv_ni->setBinarySectionLogicalStart(
613 imf_->file_->physicalToLogical( pi.fileOffset ) );
614 pi.container_ni = cv_ni;
622 "nodeType=" + node_type +
" fileName=" + imf_->fileName() +
" uri=" + toUString( uri ) +
623 " localName=" + toUString( localName ) +
" qName=" + toUString( qName ) );
625 #ifdef E57_MAX_VERBOSE
630 void E57XmlParser::endElement(
const XMLCh *
const uri,
const XMLCh *
const localName,
const XMLCh *
const qName )
632 #ifdef E57_MAX_VERBOSE
637 ParseInfo pi = stack_.top();
639 #ifdef E57_MAX_VERBOSE
646 switch ( pi.nodeType )
650 current_ni = pi.container_ni;
656 current_ni = pi.container_ni;
663 if ( pi.childText.length() > 0 )
669 std::shared_ptr<IntegerNodeImpl> i_ni(
new IntegerNodeImpl( imf_, intValue, pi.minimum, pi.maximum ) );
677 if ( pi.childText.length() > 0 )
683 std::shared_ptr<ScaledIntegerNodeImpl> si_ni(
692 if ( pi.childText.length() > 0 )
694 floatValue = atof( pi.childText.c_str() );
700 std::shared_ptr<FloatNodeImpl> f_ni(
701 new FloatNodeImpl( imf_, floatValue, pi.precision, pi.floatMinimum, pi.floatMaximum ) );
707 std::shared_ptr<StringNodeImpl> s_ni(
new StringNodeImpl( imf_, pi.childText ) );
713 std::shared_ptr<BlobNodeImpl> b_ni(
new BlobNodeImpl( imf_, pi.fileOffset, pi.length ) );
719 " fileName=" + imf_->fileName() +
" uri=" + toUString( uri ) +
720 " localName=" + toUString( localName ) +
721 " qName=" + toUString( qName ) );
723 #ifdef E57_MAX_VERBOSE
724 current_ni->dump( 4 );
728 if ( stack_.empty() )
734 "currentType=" +
toString( current_ni->type() ) +
" fileName=" + imf_->fileName() +
735 " uri=" + toUString( uri ) +
" localName=" + toUString( localName ) +
736 " qName=" + toUString( qName ) );
738 imf_->root_ = std::static_pointer_cast<StructureNodeImpl>( current_ni );
749 " localName=" + toUString( localName ) +
750 " qName=" + toUString( qName ) );
754 switch ( parent_ni->type() )
758 std::shared_ptr<StructureNodeImpl> struct_ni = std::static_pointer_cast<StructureNodeImpl>( parent_ni );
761 struct_ni->set( toUString( qName ), current_ni );
766 std::shared_ptr<VectorNodeImpl> vector_ni = std::static_pointer_cast<VectorNodeImpl>( parent_ni );
769 vector_ni->append( current_ni );
774 std::shared_ptr<CompressedVectorNodeImpl> cv_ni =
775 std::static_pointer_cast<CompressedVectorNodeImpl>( parent_ni );
776 ustring uQName = toUString( qName );
779 if ( uQName ==
"prototype" )
781 cv_ni->setPrototype( current_ni );
783 else if ( uQName ==
"codecs" )
788 "currentType=" +
toString( current_ni->type() ) +
" fileName=" + imf_->fileName() +
789 " uri=" + toUString( uri ) +
" localName=" + toUString( localName ) +
790 " qName=" + toUString( qName ) );
792 std::shared_ptr<VectorNodeImpl> vi = std::static_pointer_cast<VectorNodeImpl>( current_ni );
795 if ( !vi->allowHeteroChildren() )
798 "currentType=" +
toString( current_ni->type() ) +
" fileName=" + imf_->fileName() +
799 " uri=" + toUString( uri ) +
" localName=" + toUString( localName ) +
800 " qName=" + toUString( qName ) );
803 cv_ni->setCodecs( vi );
810 +
"fileName=" + imf_->fileName() +
" uri=" + toUString( uri ) +
811 " localName=" + toUString( localName ) +
" qName=" + toUString( qName ) );
818 "parentType=" +
toString( parent_ni->type() ) +
" fileName=" + imf_->fileName() +
819 " uri=" + toUString( uri ) +
" localName=" + toUString( localName ) +
820 " qName=" + toUString( qName ) );
824 void E57XmlParser::characters(
const XMLCh *
const chars,
const XMLSize_t
length )
827 #ifdef E57_MAX_VERBOSE
828 std::cout <<
"characters, chars=\"" << toUString( chars ) <<
"\" length=" <<
length <<
std::endl;
831 ParseInfo &pi = stack_.top();
834 switch ( pi.nodeType )
842 ustring s = toUString( chars );
843 if ( s.find_first_not_of(
" \t\n\r" ) != std::string::npos )
851 pi.childText += toUString( chars );
855 void E57XmlParser::error(
const SAXParseException &ex )
858 " xmlLine=" +
toString( ex.getLineNumber() ) +
859 " xmlColumn=" +
toString( ex.getColumnNumber() ) +
" parserMessage=" +
860 ustring( XMLString::transcode( ex.getMessage() ) ) );
863 void E57XmlParser::fatalError(
const SAXParseException &ex )
866 " xmlLine=" +
toString( ex.getLineNumber() ) +
867 " xmlColumn=" +
toString( ex.getColumnNumber() ) +
" parserMessage=" +
868 ustring( XMLString::transcode( ex.getMessage() ) ) );
871 void E57XmlParser::warning(
const SAXParseException &ex )
874 std::cerr <<
"**** XML parser warning: " <<
ustring( XMLString::transcode( ex.getMessage() ) ) <<
std::endl;
875 std::cerr <<
" Debug info:" <<
std::endl;
876 std::cerr <<
" systemId=" << XMLString::transcode( ex.getSystemId() ) <<
std::endl;
877 std::cerr <<
", xmlLine=" << ex.getLineNumber() <<
std::endl;
878 std::cerr <<
", xmlColumn=" << ex.getColumnNumber() <<
std::endl;
881 ustring E57XmlParser::toUString(
const XMLCh *
const xml_str )
884 if ( xml_str && *xml_str )
886 TranscodeToStr UTF8Transcoder( xml_str,
"UTF-8" );
887 u_str =
ustring(
reinterpret_cast<const char *
>( UTF8Transcoder.str() ) );
892 ustring E57XmlParser::lookupAttribute(
const Attributes &attributes,
const XMLCh *attribute_name )
894 XMLSize_t attr_index;
895 if ( !attributes.getIndex( attribute_name, attr_index ) )
899 return ( toUString( attributes.getValue( attr_index ) ) );
902 bool E57XmlParser::isAttributeDefined(
const Attributes &attributes,
const XMLCh *attribute_name )
904 XMLSize_t attr_index;
905 return ( attributes.getIndex( attribute_name, attr_index ) );
static const XMLCh att_allowHeterogeneousChildren[]
static const XMLCh att_minimum[]
static const XMLCh att_precision[]
static const XMLCh att_scale[]
static const XMLCh att_type[]
static const XMLCh att_offset[]
int64_t convertStrToLL(const std::string &inStr)
static const XMLCh att_recordCount[]
static const XMLCh att_maximum[]
static const XMLCh att_fileOffset[]
static const XMLCh att_length[]
void read(char *buf, size_t nRead, size_t bufSize=0)
void seek(uint64_t offset, OffsetMode omode=Logical)
void parse(InputSource &inputSource)
E57XmlParser(ImageFileImplSharedPtr imf)
__host__ __device__ float length(float2 v)
QTextStream & endl(QTextStream &stream)
std::shared_ptr< class NodeImpl > NodeImplSharedPtr
std::shared_ptr< class ImageFileImpl > ImageFileImplSharedPtr
FloatPrecision
The IEEE floating point number precisions supported.
@ E57_SINGLE
32 bit IEEE floating point number format
@ E57_DOUBLE
64 bit IEEE floating point number format
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
@ E57_ERROR_XML_PARSER_INIT
XML parser failed to initialize.
@ E57_ERROR_BAD_XML_FORMAT
E57 primitive not encoded in XML correctly.
@ E57_ERROR_XML_PARSER
XML not well formed.
std::string ustring
UTF-8 encodeded Unicode string.
NodeType
Identifiers for types of E57 elements.
@ E57_COMPRESSED_VECTOR
CompressedVectorNode class.
@ E57_BLOB
BlobNode class.
@ E57_STRUCTURE
StructureNode class.
@ E57_VECTOR
VectorNode class.
@ E57_INTEGER
IntegerNode class.
@ E57_SCALED_INTEGER
ScaledIntegerNode class.
@ E57_FLOAT
FloatNode class.
@ E57_STRING
StringNode class.
std::string toString(T x)
std::string space(size_t n)