DEADSOFTWARE

Completely convert .odc to .txt using Visitor
authorGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Tue, 8 Nov 2011 22:18:05 +0000 (22:18 +0000)
committerGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Tue, 8 Nov 2011 22:18:05 +0000 (22:18 +0000)
Makefile
alien.cc
alien.h
fold.cc
fold.h
odcread.cc
store.cc
store.h
textmodel.cc
textmodel.h
visitor.h [new file with mode: 0644]

index e3f74e5ddf148a5018ffd21b9347676e16466af8..4ad7260b49abef09e303cfabd32437671153d4ff 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-HEADERS=oberon.h store.h reader.h domain.h alien.h typeregister.h textmodel.h fold.h
+HEADERS=oberon.h store.h reader.h domain.h alien.h typeregister.h textmodel.h fold.h visitor.h
 
 odcread: odcread.o reader.o store.o util.o alien.o typeregister.o textmodel.o fold.o 
        g++ -o $@ $^
index fddd2024dbcb0dfd2ee200c52b3b93170f8c6a54..dc4f50920c7d61d30bec5744a7bba9e8ccacd018 100644 (file)
--- a/alien.cc
+++ b/alien.cc
@@ -8,8 +8,7 @@ std::string AlienPiece::toString() {
        return std::string("AlienPiece");
 }
 
-std::string AlienPiece::toPlainText() {
-       return std::string();
+void AlienPiece::accept(Visitor &visitor) const {
 }
 
 AlienPart::AlienPart(Store * const store): d_store(store) {}
@@ -21,11 +20,10 @@ std::string AlienPart::toString() {
                return "NULL";
 }
 
-std::string AlienPart::toPlainText() {
-       if (d_store != 0)
-               return d_store->toPlainText();
-       else
-               return std::string();
+void AlienPart::accept(Visitor &visitor) const {
+       if (d_store != 0) {
+               d_store->accept(visitor);
+       }
 }
 
 Alien::Alien(INTEGER id, const TypePath &path): Store(id), d_path(path), d_comps() {}
@@ -42,12 +40,10 @@ std::string Alien::toString() {
        return sofar + "}";
 }
 
-std::string Alien::toPlainText() {
-       std::string sofar = std::string();
+void Alien::accept(Visitor &visitor) const {
        for (int i = 0; i < d_comps.size(); ++i) {
-               sofar += d_comps[i]->toPlainText();
+               d_comps[i]->accept(visitor);
        }
-       return sofar;
 }
 
 }
diff --git a/alien.h b/alien.h
index 7447f953cc9ec3e4ee9b987853cb4b94f1629d9f..9f061dc412224be3e1236b94191afb3b54ee5faa 100644 (file)
--- a/alien.h
+++ b/alien.h
@@ -3,6 +3,7 @@
 
 #include <oberon.h>
 #include <store.h>
+#include <visitor.h>
 #include <iostream>
 #include <vector>
 #include <string>
@@ -14,7 +15,7 @@ namespace odc {
  */
 struct AlienComponent {
        virtual std::string toString() = 0;
-       virtual std::string toPlainText() = 0;
+       virtual void accept(Visitor &visitor) const = 0;
 };
 
 /**
@@ -27,7 +28,7 @@ struct AlienPiece : public AlienComponent {
        AlienPiece(const char * const data, const size_t len);
 
        virtual std::string toString();
-       virtual std::string toPlainText();
+       virtual void accept(Visitor &visitor) const;
 };
 
 /**
@@ -39,7 +40,7 @@ struct AlienPart : public AlienComponent {
        AlienPart(Store * const store);
 
        virtual std::string toString();
-       virtual std::string toPlainText();
+       virtual void accept(Visitor &visitor) const;
 };
 
 class Alien : public Store {
@@ -57,7 +58,7 @@ class Alien : public Store {
        // comps-: AlienComp    (** the constituent components of this alien store **)
 
        virtual std::string toString();
-       virtual std::string toPlainText();
+       virtual void accept(Visitor &visitor) const;
 };
 
 }
diff --git a/fold.cc b/fold.cc
index ae4d016cfd3d602bfadc9c0318ea212dec6f88c7..37e0fd667756bff233d05d0a9f911d6257b373b8 100644 (file)
--- a/fold.cc
+++ b/fold.cc
@@ -51,7 +51,8 @@ void Fold::internalize(Reader &reader) {
 //             rd.ReadXInt(xint);fold.leftSide := xint = 0;
        reader.readSInt();
 //             rd.ReadXInt(xint); fold.collapsed := xint = 0;
-       reader.readSInt();
+       SHORTINT c = reader.readSInt();
+       d_collapsed = (c == 0);
 //             rd.ReadXString(fold.label);
        d_label = new SHORTCHAR[32];
        reader.readSString(d_label); // the label
@@ -70,11 +71,13 @@ std::string Fold::toString() {
        return std::string("Fold(left) \"") + std::string(d_label) + std::string("\" { ") + d_hidden->toString() + std::string("  }");
 }
 
-std::string Fold::toPlainText() {
-       if (d_hidden == 0) {
-               return std::string();
+void Fold::accept(Visitor &visitor) const {
+       if (d_hidden == 0) { // right part
+               visitor.foldRight();
+       } else { // left part
+               visitor.foldLeft(d_collapsed);
+               d_hidden->accept(visitor);
        }
-       return std::string(d_label) + std::string("\n") + d_hidden->toPlainText();
 }
 
 } // namespace odc
diff --git a/fold.h b/fold.h
index e53e06d08ce1ee65d41128610b8101d6126f21cf..589b76b28783fa740cb718e700231fbb09a9d0d8 100644 (file)
--- a/fold.h
+++ b/fold.h
@@ -1,5 +1,5 @@
-#ifndef _TEXTMODEL_H_
-#define _TEXTMODEL_H_
+#ifndef _FOLD_H_
+#define _FOLD_H_
 
 #include <oberon.h>
 #include <typeregister.h>
@@ -27,6 +27,7 @@ namespace odc {
 
                Store *d_hidden;
                SHORTCHAR *d_label;
+               bool d_collapsed;
 
                public:
                Fold(INTEGER id);
@@ -36,9 +37,9 @@ namespace odc {
                virtual void internalize(Reader &reader);
 
                virtual std::string toString();
-               virtual std::string toPlainText();
+               virtual void accept(Visitor &visitor) const;
        };
 
 }
 
-#endif
+#endif // _FOLD_H_
index 151c86181db470156f3c31c3154bafc0255d8941..4ba36802c058412591472bd9fb6c4af470c6a41f 100644 (file)
@@ -5,8 +5,90 @@
 #include <oberon.h>
 #include <reader.h>
 #include <store.h>
+#include <textmodel.h>
+#include <visitor.h>
 
 namespace odc {
+       class Context {
+               public:
+               virtual void addPiece(std::string &piece) = 0;
+               virtual std::string getPlainText() const = 0;
+       };
+       class PartContext : public Context {
+               private:
+               std::string d_text;
+               public:
+               virtual void addPiece(std::string &piece) {
+                       d_text += piece;
+               }
+               virtual std::string getPlainText() const {
+                       return d_text;
+               }
+       };
+       class FoldContext : public Context {
+               private:
+               bool d_collapsed;
+               bool d_haveFirst; // flag that first part has been set
+               std::string d_firstPart;
+               std::string d_remainder;
+               public:
+               FoldContext(bool collapsed) : d_collapsed(collapsed), d_haveFirst(false) {}
+               virtual void addPiece(std::string &piece) {
+                       if (!d_haveFirst) {
+                               d_haveFirst = true;
+                               d_firstPart = piece;
+                       } else {
+                               d_remainder += piece;
+                       }
+               }
+               virtual std::string getPlainText() const {
+                       if (d_collapsed) {
+                               return std::string("##=>") + d_remainder + "\n" + d_firstPart +"##<=";
+                       } else {
+                               return std::string("##=>") + d_firstPart + "\n" + d_remainder +"##<=";
+                       }
+               }
+       };
+
+       class MyVisitor : public Visitor {
+               private:
+               std::vector<Context*> d_context;
+
+               void terminateContext() {
+                       Context *c = *(d_context.end() - 1);
+                       d_context.erase(d_context.end() - 1);
+                       if (d_context.size() == 0) {
+                               std::cout << c->getPlainText() << std::endl;
+                       } else {
+                               std::string text = c->getPlainText();
+                               (*(d_context.end() - 1))->addPiece(text);
+                       }
+                       delete c;
+               }
+               
+               public:
+               virtual void partStart() {
+                       d_context.push_back(new PartContext());
+               }
+               virtual void partEnd() {
+                       terminateContext();
+               }
+               virtual void foldLeft(bool collapsed) {
+                       d_context.push_back(new FoldContext(collapsed));
+               }
+               virtual void foldRight() {
+                       terminateContext();
+               }
+               virtual void textShortPiece(const ShortPiece *piece) {
+                       std::string text = piece->getText();
+                       (*(d_context.end() - 1))->addPiece(text);
+               }
+               virtual void textLongPiece(const LongPiece *piece) {
+                       std::string text = piece->getText();
+                       (*(d_context.end() - 1))->addPiece(text);
+               }
+       };
+
        Store* importDocument(std::istream &is) {
                const INTEGER docTag = 0x6F4F4443;
                const INTEGER docVersion = 0;
@@ -33,7 +115,9 @@ int main(int argc, char *argv[]) {
 //     std::cout << s->toPlainText() << std::endl;
 //     std::cout << std::endl << std::endl;
 
-       std::cout << s->toString() << std::endl;
+       odc::MyVisitor visitor;
+       s->accept(visitor);
+//     std::cout << s->toString() << std::endl;
 //     std::cout << in.tellg() << " " << in.eof() << std::endl;
 
 //     odc::TypePath path;
index d03467cf64df6a8736cdc81ba86d34462293aeb9..4bbabf83591858e3106d1a1fd5cd4767240d3362 100644 (file)
--- a/store.cc
+++ b/store.cc
@@ -1,5 +1,6 @@
 #include <store.h>
 #include <reader.h>
+#include <visitor.h>
 
 #include <iostream>
 
@@ -65,9 +66,7 @@ std::string Store::toString() {
        return getTypeName(); 
 }
 
-std::string Store::toPlainText() {
-       return std::string();
-}
+void Store::accept(Visitor &visitor) const {}
 
 const std::string Elem::TYPENAME("Stores.Elem^");
 const TypeProxy<Elem> Elem::PROXY;
diff --git a/store.h b/store.h
index 66e58b0cae59d4dd6d0d093c5cccbcf1d3d74b71..4e7360e782170315dafd917c53816b6ae5d141c4 100644 (file)
--- a/store.h
+++ b/store.h
@@ -4,6 +4,7 @@
 #include <oberon.h>
 #include <domain.h>
 #include <typeregister.h>
+#include <visitor.h>
 
 #include <string>
 #include <vector>
@@ -130,7 +131,11 @@ namespace odc {
                // FIXME
 
                virtual std::string toString();
-               virtual std::string toPlainText();
+
+               /**
+                * Receiving end of the Visitor pattern.
+                */
+               virtual void accept(Visitor &visitor) const;
 
                private:
                void calcTypePath(TypePath * out, const std::string &name) const;
index 977bd447e35ecca8efd0b71617597f709577771b..f9dbae242b007f39c8438e7dfae1708cae626a8c 100644 (file)
@@ -157,12 +157,12 @@ std::string StdTextModel::toString() {
        return sofar + "}";
 }
 
-std::string StdTextModel::toPlainText() {
-       std::string sofar = "";
+void StdTextModel::accept(Visitor &visitor) const {
+       visitor.partStart();
        for (int i = 0; i < d_pieces.size(); ++i) {
-               sofar += d_pieces[i]->toPlainText();
+               d_pieces[i]->accept(visitor);
        }
-       return sofar;
+       visitor.partEnd();
 }
 
 TextPiece::TextPiece(size_t len): d_len(len) {}
@@ -178,14 +178,18 @@ void LongPiece::read(Reader &reader) {
        reader.readLChar(d_buf, d_len);
 }
 
-std::string LongPiece::toString() {
+std::string LongPiece::toString() const {
        return std::string("LongPiece(FIXME)");// + std::wstring((wchar_t*)d_buf) + std::string(")");
 }
 
-std::string LongPiece::toPlainText() {
+std::string LongPiece::getText() const {
        return std::string("FIXME");// + std::wstring((wchar_t*)d_buf) + std::string(")");
 }
 
+void LongPiece::accept(Visitor &visitor) const {
+       visitor.textLongPiece(this);
+}
+
 ShortPiece::ShortPiece(size_t len): TextPiece(len) {}
 
 ShortPiece::~ShortPiece() {
@@ -205,12 +209,20 @@ void ShortPiece::read(Reader &reader) {
 //     delete buf;
 }
 
-std::string ShortPiece::toString() {
+std::string ShortPiece::toString() const {
        return std::string("ShortPiece(") + std::string(d_buf) + std::string(")");
 }
 
-std::string ShortPiece::toPlainText() {
-       return std::string(d_buf);
+std::string ShortPiece::getText() const {
+       std::string str(d_buf);
+       for (std::string::iterator it = str.begin(); it < str.end(); ++it) {
+               if (*it == '\r') *it = '\n';
+       }
+       return str;
+}
+
+void ShortPiece::accept(Visitor &visitor) const {
+       visitor.textShortPiece(this);
 }
 
 ViewPiece::ViewPiece(Store *view): TextPiece(0), d_view(view) {}
@@ -219,12 +231,12 @@ void ViewPiece::read(Reader &reader) {
        reader.readByte();
 }
 
-std::string ViewPiece::toString() {
+std::string ViewPiece::toString() const {
        return std::string("ViewPiece { ") + d_view->toString() + " }";
 }
 
-std::string ViewPiece::toPlainText() {
-       return d_view->toPlainText();
+void ViewPiece::accept(Visitor &visitor) const {
+       return d_view->accept(visitor);
 }
 
 } // namespace odc
index 38eb7c55b73d0546c5884263a98e2ec01d53b474..92d387a61b5596595b4dd985c9f1c36692671755 100644 (file)
@@ -25,8 +25,8 @@ namespace odc {
                const size_t d_len;
                TextPiece(size_t len);
                virtual void read(Reader &reader) = 0;
-               virtual std::string toString() = 0;
-               virtual std::string toPlainText() = 0;
+               virtual std::string toString() const = 0;
+               virtual void accept(Visitor &visitor) const = 0;
        };
 
        class LongPiece : public TextPiece {
@@ -36,8 +36,9 @@ namespace odc {
                LongPiece(size_t len);
                ~LongPiece();
                virtual void read(Reader &reader);
-               virtual std::string toString();
-               virtual std::string toPlainText();
+               virtual std::string toString() const;
+               virtual std::string getText() const;
+               virtual void accept(Visitor &visitor) const;
        };
 
        class ShortPiece : public TextPiece {
@@ -47,8 +48,9 @@ namespace odc {
                ShortPiece(size_t len);
                ~ShortPiece();
                virtual void read(Reader &reader);
-               virtual std::string toString();
-               virtual std::string toPlainText();
+               virtual std::string toString() const;
+               virtual std::string getText() const;
+               virtual void accept(Visitor &visitor) const;
        };
 
        class ViewPiece : public TextPiece {
@@ -56,8 +58,8 @@ namespace odc {
                public:
                ViewPiece(Store *view);
                virtual void read(Reader &reader);
-               virtual std::string toString();
-               virtual std::string toPlainText();
+               virtual std::string toString() const;
+               virtual void accept(Visitor &visitor) const;
        };
 
        class StdTextModel : public TextModel {
@@ -74,7 +76,7 @@ namespace odc {
                virtual void internalize(Reader &reader);
 
                virtual std::string toString();
-               virtual std::string toPlainText();
+               virtual void accept(Visitor &visitor) const;
        };
 
 } // namespace odc
diff --git a/visitor.h b/visitor.h
new file mode 100644 (file)
index 0000000..4b30261
--- /dev/null
+++ b/visitor.h
@@ -0,0 +1,45 @@
+#ifndef _VISITOR_H_
+#define _VISITOR_H_
+
+namespace odc {
+
+       class ShortPiece;
+       class LongPiece;
+
+       /**
+        * Visitor role of the Visitor design pattern.
+        * Can be used to transform the document tree.
+        */
+       class Visitor {
+               public:
+               /**
+                * A "part" that can contain other elements starts here.
+                * This can be an StdTextModel or a ViewPiece or another container.
+                */
+               virtual void partStart() = 0;
+               /**
+                * A "part" ends here.
+                */
+               virtual void partEnd() = 0;
+               /**
+                * A left fold has been found.
+                * If the fold is collapsed, the first part that follows is the
+                * "hidden" part, otherwise the first part that follows is the
+                * "alternative" text. The rest is the vice versa.
+                * This is the main reason we even need a visitor.
+                * @param collapsed true if the fold is in collapsed form.
+                */
+               virtual void foldLeft(bool collapsed) = 0;
+               /**
+                * A right fold has been found.
+                */
+               virtual void foldRight() = 0;
+               /**
+                * A text piece has been found.
+                */
+               virtual void textShortPiece(const ShortPiece *piece) = 0;
+               virtual void textLongPiece(const LongPiece *piece) = 0;
+       };
+}
+
+#endif // _VISITOR_H_