From: <br...@us...> - 2008-09-08 22:49:21
|
Revision: 3588 http://openvrml.svn.sourceforge.net/openvrml/?rev=3588&view=rev Author: braden Date: 2008-09-08 22:49:31 +0000 (Mon, 08 Sep 2008) Log Message: ----------- Use XmlLite on Windows rather than libxml. Modified Paths: -------------- trunk/ChangeLog trunk/ide-projects/Windows/VisualC9_0/OpenVRML/openvrml/openvrml.vcproj trunk/src/libopenvrml/openvrml/browser.cpp Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-07 22:31:56 UTC (rev 3587) +++ trunk/ChangeLog 2008-09-08 22:49:31 UTC (rev 3588) @@ -1,3 +1,40 @@ +2008-09-08 Braden McDaniel <br...@en...> + + Use XmlLite on Windows rather than libxml. + + * ide-projects/Windows/VisualC9_0/OpenVRML/openvrml/openvrml.vcproj + Added dependencies shlwapi.lib and XmlLite.lib; removed + dependencies libxml2_a_dll.lib, iconv_a.lib, and WS2_32.lib. + * src/libopenvrml/openvrml/browser.cpp + (openvrml_::xml_reader): Added a wrapper that abstracts XmlLite on + Windows and libxml's XmlTextReader interface everywhere else. + (openvrml_::xml_reader::xml_reader(const std::string &)): + Construct using a file name. On Windows, create an IStream from a + file and an IXmlReader. Everywhere else, create a libxml + XmlTextReader. + (openvrml_::xml_reader::~xml_reader()): Clean up. + (openvrml_::xml_reader::read()): Delegate to IXmlReader::Read on + Windows; xmlTextReaderRead everywhere else. + (openvrml_::xml_reader::node_type() const): Get the node type + identifier. Conveniently, these IDs have parity between the + XmlLite and XmlTextReader APIs. + (openvrml_::xml_reader::local_name() const): The local name of the + current node. + (openvrml_::xml_reader::value() const): The value, if any, of the + current node. + (openvrml_::xml_reader::move_to_first_attribute()): Move to the + first attribute of the current node. + (openvrml_::xml_reader::move_to_next_attribute()): Move to the + next attribute of the current node. + (component::xml_reader::read(const std::string &)): Use + openvrml_::xml_reader. + (component::xml_reader::process_node(openvrml_::xml_reader &)): + Use openvrml_::xml_reader. + (component::xml_reader::start_element(openvrml_::xml_reader &)): + Use openvrml_::xml_reader. + (component::xml_reader::end_element(openvrml_::xml_reader &)): Use + openvrml_::xml_reader. + 2008-09-07 Braden McDaniel <br...@en...> Use libxml's XmlTextReader interface rather than its SAX one. The Modified: trunk/ide-projects/Windows/VisualC9_0/OpenVRML/openvrml/openvrml.vcproj =================================================================== --- trunk/ide-projects/Windows/VisualC9_0/OpenVRML/openvrml/openvrml.vcproj 2008-09-07 22:31:56 UTC (rev 3587) +++ trunk/ide-projects/Windows/VisualC9_0/OpenVRML/openvrml/openvrml.vcproj 2008-09-08 22:49:31 UTC (rev 3588) @@ -60,14 +60,14 @@ /> <Tool Name="VCResourceCompilerTool" - AdditionalIncludeDirectories="C:\cygwin\home\bmcdaniel\src\openvrml\openvrml\src\openvrml" + AdditionalIncludeDirectories="" /> <Tool Name="VCPreLinkEventTool" /> <Tool Name="VCLinkerTool" - AdditionalDependencies="gdi32.lib advapi32.lib shell32.lib libpngd.lib zlibd.lib freetype236MT_D.lib libxml2_a_dll.lib iconv_a.lib WS2_32.lib" + AdditionalDependencies="gdi32.lib advapi32.lib shell32.lib shlwapi.lib XmlLite.lib libpngd.lib zlibd.lib freetype236MT_D.lib" OutputFile="$(SolutionDir)..\bin\$(ProjectName)d.dll" IgnoreDefaultLibraryNames="libcmtd;msvcrt" GenerateDebugInformation="true" @@ -126,7 +126,6 @@ Optimization="3" InlineFunctionExpansion="1" OmitFramePointers="true" - AdditionalIncludeDirectories=".;..\..\..\..\..\src\libopenvrml" PreprocessorDefinitions="NOMINMAX;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;BOOST_SPIRIT_THREADSAFE;PACKAGE_VERSION=\"0.17.8\";BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS;BOOST_MPL_LIMIT_VECTOR_SIZE=30;BOOST_SPIRIT_CLOSURE_LIMIT=6;PHOENIX_LIMIT=6;OPENVRML_BUILD_DLL;OPENVRML_ENABLE_PNG_TEXTURES;OPENVRML_ENABLE_RENDER_TEXT_NODE;OPENVRML_FT_CONST="const";OPENVRML_PKGDATADIR_=\"\";OPENVRML_PKGLIBDIR_=\"\";NDEBUG" StringPooling="true" @@ -145,14 +144,14 @@ /> <Tool Name="VCResourceCompilerTool" - AdditionalIncludeDirectories="C:\cygwin\home\bmcdaniel\src\openvrml\openvrml\src\openvrml" + AdditionalIncludeDirectories="" /> <Tool Name="VCPreLinkEventTool" /> <Tool Name="VCLinkerTool" - AdditionalDependencies="gdi32.lib advapi32.lib shell32.lib libpng.lib zlib.lib freetype236MT.lib libxml2_a_dll.lib iconv_a.lib WS2_32.lib" + AdditionalDependencies="gdi32.lib advapi32.lib shell32.lib shlwapi.lib XmlLite.lib libpng.lib zlib.lib freetype236MT.lib" OutputFile="$(SolutionDir)..\bin\$(ProjectName).dll" IgnoreDefaultLibraryNames="libcmt" GenerateDebugInformation="true" Modified: trunk/src/libopenvrml/openvrml/browser.cpp =================================================================== --- trunk/src/libopenvrml/openvrml/browser.cpp 2008-09-07 22:31:56 UTC (rev 3587) +++ trunk/src/libopenvrml/openvrml/browser.cpp 2008-09-08 22:49:31 UTC (rev 3588) @@ -30,9 +30,12 @@ # include <sys/timeb.h> # include <direct.h> # include <time.h> +# include <shlwapi.h> +# include <XmlLite.h> # else # include <sys/time.h> # include <ltdl.h> +# include <libxml/xmlreader.h> # endif # include <boost/algorithm/string/predicate.hpp> # include <boost/array.hpp> @@ -47,7 +50,6 @@ # include <boost/thread/thread.hpp> # include <boost/tokenizer.hpp> # include <boost/utility.hpp> -# include <libxml/xmlreader.h> # include <private.h> # include "browser.h" # include "vrml97_grammar.h" @@ -6377,6 +6379,181 @@ namespace { + namespace openvrml_ { + + class OPENVRML_LOCAL xml_reader { +# ifdef _WIN32 + IStream * input; + IXmlReader * reader; +# else + XmlTextReaderPtr reader; +# endif + public: + // + // Conveniently, these values are consistent between libxml and + // XmlLite. + // + enum node_type_id { + none_id = 0, + element_id = 1, + attribute_id = 2, + text_id = 3, + cdata_id = 4, + processing_instruction_id = 7, + comment_id = 8, + document_type_id = 10, + whitespace_id = 13, + end_element_id = 15, + xml_declaration_id = 17 + }; + + explicit xml_reader(const std::string & filename); + ~xml_reader(); + + int read(); + node_type_id node_type() const; + const std::string local_name() const; + const std::string value() const; + int move_to_first_attribute(); + int move_to_next_attribute(); + }; + } + + openvrml_::xml_reader::xml_reader(const std::string & filename): +# ifdef _WIN32 + input(0), +# endif + reader(0) + { +# ifdef _WIN32 + HRESULT hr; + + hr = SHCreateStreamOnFile(filename.c_str(), STGM_READ, &this->input); + if (FAILED(hr)) { + throw std::runtime_error("failed to open file \"" + filename + + '\"'); + } + scope_guard input_guard = + make_obj_guard(*this->input, &IStream::Release); + + hr = CreateXmlReader(__uuidof(IXmlReader), + reinterpret_cast<void **>(&this->reader), + 0); + if (FAILED(hr)) { + throw std::runtime_error("failed to create XML reader"); + } + scope_guard reader_guard = + make_obj_guard(*this->reader, &IXmlReader::Release); + + hr = this->reader->SetInput(this->input); + if (FAILED(hr)) { + throw std::runtime_error("failed to set input for XML reader"); + } + + input_guard.dismiss(); + reader_guard.dismiss(); +# else + static const char * const encoding = 0; + static const int options = 0; + this->reader = xmlReaderForFile(filename.c_str(), encoding, options); +# endif + } + + openvrml_::xml_reader::~xml_reader() + { +# ifdef _WIN32 + this->reader->Release(); + this->input->Release(); +# else + xmlFreeTextReader(this->reader); +# endif + } + + int openvrml_::xml_reader::read() + { +# ifdef _WIN32 + HRESULT hr = this->reader->Read(0); + return (hr == S_OK) + ? 1 + : (hr == S_FALSE) + ? 0 + : -1; +# else + return xmlTextReaderRead(this->reader); +# endif + } + + openvrml_::xml_reader::node_type_id + openvrml_::xml_reader::node_type() const + { +# ifdef _WIN32 + XmlNodeType type; + this->reader->GetNodeType(&type); + return node_type_id(type); +# else + return node_type_id(xmlTextReaderNodeType(this->reader)); +# endif + } + + const std::string openvrml_::xml_reader::local_name() const + { +# ifdef _WIN32 + const WCHAR * name; + HRESULT hr = this->reader->GetLocalName(&name, 0); + if (FAILED(hr)) { + throw std::runtime_error("failed to get element name"); + } + return std::string(name, name + wcslen(name)); +# else + const xmlChar * name = xmlTextReaderConstLocalName(this->reader); + return std::string(name, name + xmlStrlen(name)); +# endif + } + + const std::string openvrml_::xml_reader::value() const + { +# ifdef _WIN32 + const WCHAR * val; + HRESULT hr = this->reader->GetValue(&val, 0); + if (FAILED(hr)) { + throw std::runtime_error("failed to get a value"); + } + return std::string(val, val + wcslen(val)); +# else + const xmlChar * val = xmlTextReaderConstValue(this->reader); + return std::string(val, val + xmlStrlen(val)); +# endif + } + + int openvrml_::xml_reader::move_to_first_attribute() + { +# ifdef _WIN32 + HRESULT hr = this->reader->MoveToFirstAttribute(); + return (hr == S_OK) + ? 1 + : (hr == S_FALSE) + ? 0 + : -1; +# else + return xmlTextReaderMoveToFirstAttribute(this->reader); +# endif + } + + int openvrml_::xml_reader::move_to_next_attribute() + { +# ifdef _WIN32 + HRESULT hr = this->reader->MoveToNextAttribute(); + return (hr == S_OK) + ? 1 + : (hr == S_FALSE) + ? 0 + : -1; +# else + return xmlTextReaderMoveToNextAttribute(this->reader); +# endif + } + + class OPENVRML_LOCAL component { struct node_type_decl { openvrml::node_interface_set interfaces; @@ -6429,9 +6606,9 @@ OPENVRML_THROW1(std::runtime_error); private: - void process_node(xmlTextReader & reader); - void start_element(xmlTextReader & reader); - void end_element(xmlTextReader & reader); + void process_node(openvrml_::xml_reader & reader); + void start_element(openvrml_::xml_reader & reader); + void end_element(openvrml_::xml_reader & reader); }; std::string id_; @@ -12089,20 +12266,10 @@ void component::xml_reader::read(const std::string & filename) OPENVRML_THROW1(std::runtime_error) { - static const char * const encoding = 0; - static const int options = 0; - const xmlTextReaderPtr reader = - xmlReaderForFile(filename.c_str(), encoding, options); - if (!reader) { - throw std::runtime_error("could not open \"" + filename - + "\" for reading"); - } - scope_guard reader_guard = make_guard(xmlFreeTextReader, reader); - boost::ignore_unused_variable_warning(reader_guard); - + openvrml_::xml_reader reader(filename); int result; - while ((result = xmlTextReaderRead(reader)) == 1) { - this->process_node(*reader); + while ((result = reader.read()) == 1) { + this->process_node(reader); } if (result != 0) { @@ -12110,14 +12277,14 @@ } } - void component::xml_reader::process_node(xmlTextReader & reader) + void component::xml_reader::process_node(openvrml_::xml_reader & reader) { - const int node_type = xmlTextReaderNodeType(&reader); + const int node_type = reader.node_type(); switch (node_type) { - case XML_READER_TYPE_ELEMENT: + case openvrml_::xml_reader::element_id: this->start_element(reader); break; - case XML_READER_TYPE_END_ELEMENT: + case openvrml_::xml_reader::end_element_id: this->end_element(reader); break; default: @@ -12125,21 +12292,22 @@ } } - void component::xml_reader::start_element(xmlTextReader & reader) + void component::xml_reader::start_element(openvrml_::xml_reader & reader) { using std::pair; using std::strcmp; using std::string; + using openvrml::node_interface; + int move_to_attr_result; + node_interface interface_; + switch (this->state_) { case component::xml_reader::none: this->state_ = component::xml_reader::component; - { - xmlChar * id = xmlTextReaderGetAttribute(&reader, - BAD_CAST("id")); - scope_guard id_guard = make_guard(free, id); - boost::ignore_unused_variable_warning(id_guard); - this->component_.id_.assign(id, id + xmlStrlen(id)); + move_to_attr_result = reader.move_to_first_attribute(); + if (move_to_attr_result > 0) { + this->component_.id_ = reader.value(); } break; case component::xml_reader::component: @@ -12148,115 +12316,86 @@ this->current_level_ = &this->component_.levels_.back(); break; case component::xml_reader::level: - if (xmlStrcmp(xmlTextReaderName(&reader), BAD_CAST("requires")) - == 0) { - using boost::lexical_cast; + if (reader.local_name() == "requires") { + string id; + size_t level; + move_to_attr_result = reader.move_to_first_attribute(); + while (move_to_attr_result > 0) { + using boost::lexical_cast; + if (reader.local_name() == "id") { + id = reader.value(); + } else if (reader.local_name() == "level") { + level = lexical_cast<size_t>(reader.value()); + } + move_to_attr_result = reader.move_to_next_attribute(); + } - xmlChar * id_chars = xmlTextReaderGetAttribute(&reader, - BAD_CAST("id")); - scope_guard id_chars_guard = make_guard(free, id_chars); - boost::ignore_unused_variable_warning(id_chars_guard); - const string id(id_chars, id_chars + xmlStrlen(id_chars)); - - xmlChar * level_chars = - xmlTextReaderGetAttribute(&reader, BAD_CAST("level")); - scope_guard level_chars_guard = make_guard(free, level_chars); - boost::ignore_unused_variable_warning(level_chars_guard); - const size_t level = - lexical_cast<size_t>( - string(level_chars, - level_chars + xmlStrlen(level_chars))); - this->current_level_->dependencies_.insert( make_pair(id, level)); - } else if (xmlStrcmp(xmlTextReaderName(&reader), BAD_CAST("node")) - == 0) { + } else if (reader.local_name() == "node") { this->state_ = component::xml_reader::node; - xmlChar * id_chars = xmlTextReaderGetAttribute(&reader, - BAD_CAST("id")); - scope_guard id_chars_guard = make_guard(free, id_chars); - boost::ignore_unused_variable_warning(id_chars_guard); - const string id(id_chars, id_chars + xmlStrlen(id_chars)); - + string id; component::node_type_decl node_type; - xmlChar * metatype_id_chars = - xmlTextReaderGetAttribute(&reader, BAD_CAST("metatype-id")); - scope_guard metatype_id_chars_guard = - make_guard(free, metatype_id_chars); - boost::ignore_unused_variable_warning(metatype_id_chars_guard); - node_type.metatype_id.assign( - metatype_id_chars, - metatype_id_chars + xmlStrlen(metatype_id_chars)); - + move_to_attr_result = reader.move_to_first_attribute(); + while (move_to_attr_result > 0) { + if (reader.local_name() == "id") { + id = reader.value(); + } else if (reader.local_name() == "metatype-id") { + node_type.metatype_id = reader.value(); + } + move_to_attr_result = reader.move_to_next_attribute(); + } pair<component::level::iterator, bool> result = this->current_level_->insert(std::make_pair(id, node_type)); if (result.second) { this->current_node_ = &*result.first; } } else { - xmlChar * name_chars = xmlTextReaderName(&reader); - const std::string name(name_chars, - name_chars + xmlStrlen(name_chars));; - throw std::runtime_error("unexpected element: " + name); + throw std::runtime_error("unexpected element: " + + reader.local_name()); } break; case component::xml_reader::requires: break; case component::xml_reader::node: - { + move_to_attr_result = reader.move_to_first_attribute(); + while (move_to_attr_result > 0) { using boost::lexical_cast; using openvrml::field_value; - using openvrml::node_interface; - node_interface interface_; - xmlChar * id_chars = xmlTextReaderGetAttribute(&reader, - BAD_CAST("id")); - scope_guard id_chars_guard = make_guard(free, id_chars); - boost::ignore_unused_variable_warning(id_chars_guard); - interface_.id.assign(id_chars, id_chars + xmlStrlen(id_chars)); - - xmlChar * type_chars = - xmlTextReaderGetAttribute(&reader, BAD_CAST("type")); - scope_guard type_chars_guard = make_guard(free, type_chars); - boost::ignore_unused_variable_warning(type_chars_guard); - const string type(type_chars, - type_chars + xmlStrlen(type_chars)); - try { - interface_.field_type = - lexical_cast<field_value::type_id>(string(type)); - } catch (const boost::bad_lexical_cast &) { - throw std::runtime_error( - "invalid field value type identifier \"" + type + '\"'); + if (reader.local_name() == "id") { + interface_.id = reader.value(); + } else if (reader.local_name() == "type") { + try { + interface_.field_type = + lexical_cast<field_value::type_id>(reader.value()); + } catch (const boost::bad_lexical_cast &) { + throw std::runtime_error( + "invalid field value type identifier \"" + + reader.value() + '\"'); + } + } else if (reader.local_name() == "access-type") { + try { + interface_.type = + lexical_cast<node_interface::type_id>( + reader.value()); + } catch (const boost::bad_lexical_cast &) { + throw std::runtime_error( + "invalid field access type identifier \"" + + reader.value() + '\"'); + } } - - xmlChar * access_type_chars = - xmlTextReaderGetAttribute(&reader, BAD_CAST("access-type")); - scope_guard access_type_chars_guard = - make_guard(free, access_type_chars); - boost::ignore_unused_variable_warning(access_type_chars_guard); - const string access_type( - access_type_chars, - access_type_chars + xmlStrlen(access_type_chars)); - - try { - interface_.type = - lexical_cast<node_interface::type_id>(access_type); - } catch (const boost::bad_lexical_cast &) { - throw std::runtime_error( - "invalid field access type identifier \"" + access_type - + '\"'); - } - - this->current_node_->second.interfaces.insert(interface_); + move_to_attr_result = reader.move_to_next_attribute(); } + this->current_node_->second.interfaces.insert(interface_); break; case component::xml_reader::field: default: assert(false); } } - void component::xml_reader::end_element(xmlTextReader & /* reader */) + void component::xml_reader::end_element(openvrml_::xml_reader & /* reader */) { switch (this->state_) { case component::xml_reader::none: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |