On Thu, 2003-06-12 at 22:12, Stefan Seefeld wrote: > I'm wrapping libxml2. The structs provided by libxml2 all carry a > '_private' member, precisely because it's a good way for extensions > such as language wrapping. > libxml2 itself calls callbacks whenever it allocates instances of these > structs, and I allocate my C++ wrappers in these callbacks, and let the > _private member point to it. > That way I'v got a pointer from the C struct to the C++ wrapper > (_private), as well as a pointer from the C++ wrapper to the C struct > (my_impl).
Would a thin proxy object not be a better way to go? More in keeping with the "you don't pay for what you don't use" philosophy of C++. I have attached the wrappers I have written. They do not cover much of libxml2 (just what I needed at the time). Feel free to borrow as much or as little from it as you like. If you look in node_iterator.h you can see that it uses a proxy containing just a pointer to the libxml2 node. Looking up this node's parent node is thus simply > static_cast<Node *>(this->my_impl->parent->_private); If there was a parent lookup in node_proxy it would be class node_proxy { public: node_proxy parent() { return node_proxy( node_->parent ); } ... private: xmlNodePtr node_; }; > > Here are some suggestions... > > > > 1) parse_file could be > > > > class parse_file > > { > > public: > > parse_file( const std::string & ) : {} > > ... > > }; > > making 'parse_file' a class suggests it is carrying some data/state. > What would that be ? I'm thinking of 'parse_file' as a stateless > factory, i.e. a function returning a newly created document. Sorry I should have included the ... bit class parse_file { public: parse_file( const std::string & f ) : file_name_ {} private: const std::string & file_name_; template< ... > friend class ::boost::xml::dom::document; }; Put that together with the constructor... template<...> class basic_document { public: basic_document( const parse_file & f ) { // does what parse_file function does now } }; And you can write code that goes xml::dom::document doc( xml::dom::parse_file( "a.xml" ) ); No auto_ptr needed. It's not in my wrappers as I only thought of it while I was reading through yours. > > 2) How about parse_string (based on xmlParseMemory)? > > hmm, while that would be possible, I think it's more C++'ish to > provide document extraction from a std::streambuf, which could be > a string_buf or any other buffer implementation. (Note that I wouldn't > use std::iostreams as that would suggest that formatted extraction is > possible, which would only work on ascii, not on unicode content. parse_stream would indeed be even better. As I recall there are functions in libxml2 that allow you to write to the parser as well. How about this for reading an input stream... xml::dom::document doc( parse_stream( std::cin.rdbuf() ) ); and if you want to write to to the parser (for instance if the data is coming from a series of asynchronous read operations). class document { public: std::streambuf & parser(); }; xml::dom::document doc; doc.parser().write( buffer, buffer_size ); > > 4) How about something like > > > > class basic_document > > { > > public: > > ... > > > > typedef node_iterator iterator; > > typedef const_node_iterator const_iterator; > > > > iterator begin() > > { return iterator( ptr_->children ); } > > const_iterator begin() const > > { return const_iterator( ptr_->children ); } > > iterator end() { return iterator(); } > > const_iterator end() const { return const_iterator(); } > > > > iterator root() > > { return iterator( xmlDocGetRootElement( ptr_ ) ); } > > const_iterator root() const > > { return const_iterator( xmlDocGetRootElement( ptr_ ) ); } > > }; > > I don't understand: are you suggesting an iterator that traverses > the whole tree (as opposed the children of a single node) ? No just the children. If figure node.begin() and node.end() be fore iteration over the child nodes. -- Hamish Mackenzie <[EMAIL PROTECTED]>
xml_stuff.tar.gz
Description: application/compressed-tar
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost