summaryrefslogtreecommitdiff
path: root/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp
diff options
context:
space:
mode:
authorjai <jai@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-01-29 21:15:18 +0000
committerjai <jai@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-01-29 21:15:18 +0000
commitb71531b42b3325fd6079a7039aae8641262c8adf (patch)
treea5b9aa16924c541fcb424ee9460b1ac7f5a89352 /modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp
parenta0f67cc97c0050d907145e312135b60c0125e56e (diff)
downloadATCD-b71531b42b3325fd6079a7039aae8641262c8adf.tar.gz
branching/taggingDS-main
Diffstat (limited to 'modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp')
-rw-r--r--modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp
new file mode 100644
index 00000000000..774a70e501f
--- /dev/null
+++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp
@@ -0,0 +1,233 @@
+// file : CCF/CodeGenerationKit/IndentationXML.hpp
+// author : Diego Sevilla Ruiz <dsevilla@ditec.um.es>
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_XML_HPP
+#define CCF_CODE_GENERATION_KIT_INDENTATION_XML_HPP
+
+#include <deque>
+
+#include "CCF/CodeGenerationKit/IndentationBuffer.hpp"
+
+namespace Indentation
+{
+ template <typename C>
+ class XML : public Buffer<C>
+ {
+ public:
+ typedef
+ typename Buffer<C>::traits_type
+ traits_type;
+
+ typedef
+ typename Buffer<C>::char_type
+ char_type;
+
+ typedef
+ typename Buffer<C>::int_type
+ int_type;
+
+ typedef
+ typename Buffer<C>::EndOfStream
+ EndOfStream;
+
+ public:
+ XML (Buffer<C>& out)
+ : out_ (out),
+ indentation_ (0),
+ base_indent_ (indentation_),
+ spaces_ (2),
+ construct_ (OTHER)
+ {
+ }
+
+ virtual
+ ~XML () throw () {}
+
+ public:
+ virtual int_type
+ put (char_type c) throw (ExH::System::Exception)
+ {
+ int_type result = traits_type::to_int_type (c);
+
+ try
+ {
+ switch (c)
+ {
+ case '\n':
+ {
+ flush_buffer ();
+
+ // If we are inside a tag, just output an artificial tab character
+ if (construct_ == INSIDE_TAG)
+ {
+ hold_.push_back (c);
+ c = traits_type::to_int_type (' ');
+
+ // spaces_ - 1 because at the end the last space will be
+ // put into the hold_ queue.
+ for (unsigned long i = 0; i < spaces_ - 1; i++)
+ hold_.push_back (c);
+ }
+
+ base_indent_ = indentation_;
+
+ break;
+ }
+
+ // Case with <?xxx and <!DOCTYPE (for example).
+ // We still don't handle XML comments
+ case '?':
+ case '!':
+ {
+ if (construct_ == INSIDE_TAG && hold_.back () == '<')
+ indentation_--;
+
+ break;
+ }
+
+ case '<':
+ {
+ //@@ This construct must not be INSIDE_TAG
+ if (construct_ == OTHER)
+ {
+ construct_ = INSIDE_TAG;
+ indentation_++;
+ }
+
+ break;
+ }
+
+ case '>':
+ {
+ if (construct_ == INSIDE_TAG)
+ construct_ = OTHER;
+
+ break;
+ }
+
+ case '/':
+ {
+ if (construct_ == INSIDE_TAG)
+ {
+ if (hold_.back () == '<')
+ indentation_ -= 2;
+ else
+ indentation_--;
+
+ if (indentation_ < 0)
+ indentation_ = 0;
+ }
+
+ break;
+ }
+
+ case '\"':
+ {
+ if (construct_ == INSIDE_TAG)
+ construct_ = STRING_LITERAL;
+ else if (construct_ == STRING_LITERAL)
+ construct_ = INSIDE_TAG;
+
+ break;
+ }
+
+ }
+
+ hold_.push_back (c);
+
+ }
+ catch (Full const&)
+ {
+ result = traits_type::eof ();
+ }
+
+ return result;
+ }
+
+ virtual void
+ unbuffer () throw (EndOfStream, ExH::System::Exception)
+ {
+ try
+ {
+ flush_buffer ();
+ } catch (const Full&)
+ {
+ throw EndOfStream ("unable to flush buffer");
+ }
+ }
+
+ private:
+ class Full {};
+
+ void
+ flush_buffer () throw (Full)
+ {
+ long delta = indentation_ - base_indent_;
+
+ if (delta > 0)
+ delta = 0;
+
+ while (!hold_.empty ())
+ {
+ int_type c = hold_.front ();
+
+ write (c);
+
+ if (c == '\n')
+ output_indentation (base_indent_ + delta);
+
+ hold_.pop_front ();
+ }
+ }
+
+ void
+ output_indentation (unsigned long indentation) throw (Full)
+ {
+ for (unsigned long i = 0; i < indentation * spaces_; i++)
+ {
+ write (' ');
+ }
+ }
+
+ int_type
+ write (int_type c) throw (Full)
+ {
+ int_type result;
+
+ result = out_.put (c);
+
+ if (result == traits_type::eof ()) throw Full ();
+
+ return result;
+ }
+
+
+ private:
+ Buffer<C>& out_;
+ long indentation_;
+ unsigned long base_indent_;
+ unsigned long spaces_;
+
+ enum Construct
+ {
+ OTHER,
+ /* Strings literals can only happen inside tags, like:
+ * <tag whatever="xxx
+ */
+ STRING_LITERAL,
+ INSIDE_TAG
+ };
+
+ Construct construct_;
+
+ typedef
+ std::deque<int_type>
+ Hold;
+
+ Hold hold_;
+ };
+}
+
+#endif // CCF_CODE_GENERATION_KIT_INDENTATION_XML_HPP