From 9e77d565b3b817ceb427d7ffc2c71fd7ffe5d169 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 26 Nov 2009 08:38:15 +0200 Subject: Implement buffering of small write requests in ostream_format_target --- libxsd/xsd/cxx/xml/dom/serialization-source.hxx | 47 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/libxsd/xsd/cxx/xml/dom/serialization-source.hxx b/libxsd/xsd/cxx/xml/dom/serialization-source.hxx index 4593f9c..08cbcd5 100644 --- a/libxsd/xsd/cxx/xml/dom/serialization-source.hxx +++ b/libxsd/xsd/cxx/xml/dom/serialization-source.hxx @@ -91,17 +91,17 @@ namespace xsd xercesc::DOMErrorHandler& eh, unsigned long flags); - // - // + class ostream_format_target: public xercesc::XMLFormatTarget { + static const std::size_t buf_max = 1024; + public: ostream_format_target (std::ostream& os) - : os_ (os) + : n_ (0), os_ (os) { } - public: // I know, some of those consts are stupid. But that's what // Xerces folks put into their interfaces and VC-7.1 thinks @@ -116,14 +116,32 @@ namespace xsd #endif xercesc::XMLFormatter* const) { - // Ignore the data if there was a stream failure and - // the stream is not using exceptions. + // Ignore the write request if there was a stream failure and the + // stream is not using exceptions. + // + if (os_.fail ()) + return; + + // Flush the buffer if the block is too large or if we don't have + // any space left. // - if (!(os_.bad () || os_.fail ())) + if ((size >= buf_max / 8 || n_ + size > buf_max) && n_ != 0) { + os_.write (buf_, static_cast (n_)); + n_ = 0; + + if (os_.fail ()) + return; + } + + if (size < buf_max / 8) + { + memcpy (buf_ + n_, reinterpret_cast (buf), size); + n_ += size; + } + else os_.write (reinterpret_cast (buf), static_cast (size)); - } } @@ -133,13 +151,24 @@ namespace xsd // Ignore the flush request if there was a stream failure // and the stream is not using exceptions. // - if (!(os_.bad () || os_.fail ())) + if (!os_.fail ()) { + if (n_ != 0) + { + os_.write (buf_, static_cast (n_)); + n_ = 0; + + if (os_.fail ()) + return; + } + os_.flush (); } } private: + char buf_[buf_max]; + size_t n_; std::ostream& os_; }; } -- cgit v1.1