diff --git a/SAX/filter/Writer.h b/SAX/filter/Writer.h index 33b2fbb9..a2c8e4d6 100644 --- a/SAX/filter/Writer.h +++ b/SAX/filter/Writer.h @@ -2,13 +2,15 @@ #define SAXWriter_H #include +#include #include #include namespace SAX { template -class basic_Writer : public basic_XMLFilterImpl +class basic_Writer : public basic_XMLFilterImpl, + private basic_LexicalHandler { public: typedef string_type stringT; @@ -18,17 +20,24 @@ class basic_Writer : public basic_XMLFilterImpl typedef basic_XMLReader XMLReaderT; typedef basic_XMLFilterImpl XMLFilterT; typedef Unicode UnicodeT; + private: + typedef basic_LexicalHandler LexicalHandlerT; - basic_Writer(std::ostream& stream) : + public: + basic_Writer(ostreamT& stream) : + lexicalHandler_(0), indent_(2), - stream_(&stream) + stream_(&stream), + inCDATA_(false) { } // basic_Writer basic_Writer(ostreamT& stream, XMLReaderT& parent) : XMLFilterT(parent), + lexicalHandler_(0), indent_(2), - stream_(&stream) + stream_(&stream), + inCDATA_(false) { } // basic_Writer @@ -45,13 +54,31 @@ class basic_Writer : public basic_XMLFilterImpl virtual void processingInstruction(const stringT& target, const stringT& data); virtual void skippedEntity(const stringT& name); + virtual void parse(InputSourceT& input); + + protected: + virtual std::auto_ptr doGetProperty(const stringT& name); + virtual void doSetProperty(const stringT& name, std::auto_ptr value); + private: + virtual void startDTD(const stringT& name, const stringT& publicId, const stringT& systemId); + virtual void endDTD(); + virtual void startEntity(const stringT& name); + virtual void endEntity(const stringT& name); + virtual void startCDATA(); + virtual void endCDATA(); + virtual void comment(const stringT& text); + void doIndent(); bool isDtd(const stringT& name); + bool inCDATA_; int indent_; int depth_; ostreamT* stream_; + + LexicalHandlerT* lexicalHandler_; + const SAX::PropertyNames properties_; }; // class basic_Writer template @@ -60,6 +87,8 @@ void basic_Writer::startDocument() *stream_ << "" << std::endl; depth_ = 0; + inCDATA_ = false; + XMLFilterT::startDocument(); } // startDocument @@ -134,6 +163,15 @@ void basic_Writer::skippedEntity(const stringT& name) std::cout << UnicodeT::AMPERSAND << name << UnicodeT::SEMI_COLON; } // skippedEntity +template +void basic_Writer::parse(InputSourceT& input) +{ + XMLReaderT* parent = getParent(); + if(parent) + parent->setProperty(properties_.lexicalHandler, static_cast(*this)); + + XMLFilterT::parse(input); +} // parse template void basic_Writer::doIndent() @@ -153,6 +191,101 @@ bool basic_Writer::isDtd(const string_type& name) name[4] == UnicodeT::RIGHT_SQUARE_BRACKET); } // isDtd +template +std::auto_ptr::XMLReaderT::PropertyBase> basic_Writer::doGetProperty(const string_type& name) +{ + if(name == properties_.lexicalHandler) + { + XMLReaderT::Property* prop = + new XMLReaderT::Property(lexicalHandler_); + return std::auto_ptr(prop); + } + + return XMLFilterT::doGetProperty(name); +} // doGetProperty + +template +void basic_Writer::doSetProperty(const string_type& name, typename std::auto_ptr::XMLReaderT::PropertyBase> value) +{ + if(name == properties_.lexicalHandler) + { + XMLReaderT::Property* prop = + dynamic_cast*>(value.get()); + + if(!prop) + throw std::bad_cast(); + + lexicalHandler_ = &(prop->get()); + } + return XMLFilterT::doSetProperty(name, value); +} // doSetProperty + +template +void basic_Writer::startDTD(const stringT& name, const stringT& publicId, const stringT& systemId) +{ + if(lexicalHandler_) + lexicalHandler_->startDTD(name, publicId, systemId); +} // startDTD + +template +void basic_Writer::endDTD() +{ + if(lexicalHandler_) + lexicalHandler_->endDTD(); +} // endDTD + +template +void basic_Writer::startEntity(const stringT& name) +{ + if(lexicalHandler_) + lexicalHandler_->startEntity(name); +} // startEntity + +template +void basic_Writer::endEntity(const stringT& name) +{ + if(lexicalHandler_) + lexicalHandler_->endEntity(name); +} // endEntity + +template +void basic_Writer::startCDATA() +{ + inCDATA_ = true; + + std::cout << UnicodeT::LESS_THAN_SIGN + << UnicodeT::EXCLAMATION_MARK + << UnicodeT::LEFT_SQUARE_BRACKET + << static_cast('C') + << static_cast('D') + << static_cast('A') + << static_cast('T') + << static_cast('A') + << UnicodeT::LEFT_SQUARE_BRACKET; + + if(lexicalHandler_) + lexicalHandler_->startCDATA(); +} // startCDATA + +template +void basic_Writer::endCDATA() +{ + std::cout << UnicodeT::RIGHT_SQUARE_BRACKET + << UnicodeT::RIGHT_SQUARE_BRACKET + << UnicodeT::GREATER_THAN_SIGN; + + inCDATA_ = false; + + if(lexicalHandler_) + lexicalHandler_->endCDATA(); +} // endCDATA + +template +void basic_Writer::comment(const stringT& text) +{ + if(lexicalHandler_) + lexicalHandler_->comment(text); +} // comment typedef basic_Writer Writer; typedef basic_Writer wWriter;