00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef __GNUG__
00026 # pragma implementation "GraphVizVisitor.h"
00027 #endif
00028
00029 #include "StrMod/GraphVizVisitor.h"
00030 #include "StrMod/DynamicBuffer.h"
00031 #include <iostream>
00032 #include <iomanip>
00033 #include <cstddef>
00034 #include <cctype>
00035 #include <cstring>
00036
00037 namespace strmod {
00038 namespace strmod {
00039
00040 const STR_ClassIdent GraphVizVisitor::identifier(48UL);
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 const StrChunkPtr GraphVizVisitor::visit(const StrChunkPtr &root, std::ostream &out)
00051 {
00052 StrChunkPtr retval;
00053 static char name = 'A';
00054 if (root)
00055 {
00056 data_ = new DynamicBuffer;
00057 data_->resize(root->Length());
00058 rootpos_ = 0;
00059 edges_.clear();
00060 out_ = &out;
00061 try {
00062 out << "digraph " << (name++) << " {\n";
00063 startVisit(root);
00064 {
00065 const void *dataptr = data_->getVoidP();
00066 out << "n_" << root.GetPtr() << " -> d_" << dataptr << ";\n";
00067 printData(data_->getVoidP(), data_->Length());
00068 out.flush();
00069 assert(data_->Length() == rootpos_);
00070 }
00071 out << "}\n";
00072 }
00073 catch (...) {
00074
00075 out_ = NULL;
00076 rootpos_ = 0;
00077 delete data_;
00078 data_ = 0;
00079 edges_.clear();
00080 throw;
00081 }
00082 out_ = NULL;
00083 rootpos_ = 0;
00084 retval = data_;
00085 data_ = 0;
00086 edges_.clear();
00087 }
00088 return(retval);
00089 }
00090
00091 void GraphVizVisitor::use_visitStrChunk(const StrChunkPtr &chunk,
00092 const LinearExtent &used)
00093 throw(halt_visitation)
00094 {
00095 const void *parent = getParent().GetPtr();
00096 if (parent)
00097 {
00098 const void *me = chunk.GetPtr();
00099 const edge_t edge(me, parent);
00100 if (edges_.find(edge) == edges_.end())
00101 {
00102 edges_.insert(edge);
00103 (*out_) << "n_" << parent << " -> n_" << me << ";\n";
00104 }
00105 }
00106 }
00107
00108 void GraphVizVisitor::use_visitDataBlock(const void *start, size_t len,
00109 const void *realstart, size_t reallen)
00110 throw(halt_visitation)
00111 {
00112 const void *parent = getParent().GetPtr();
00113 const void *me = realstart;
00114 const edge_t edge(me, parent);
00115 if (edges_.find(edge) == edges_.end())
00116 {
00117 edges_.insert(edge);
00118 (*out_) << "n_" << parent << " -> d_" << me << ";\n";
00119 printData(realstart, reallen);
00120 }
00121 assert((rootpos_ + len) <= data_->Length());
00122 memcpy(data_->getCharP() + rootpos_, start, len);
00123 rootpos_ += len;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 void GraphVizVisitor::printData(const void *data, size_t len)
00133 {
00134 (*out_) << "d_" << data << "[shape=box,label=\"";
00135 const unsigned char *tmp = static_cast<const unsigned char *>(data);
00136 for (size_t i = 0; i < len; ++i)
00137 {
00138 if (tmp[i] == '"')
00139 {
00140 (*out_) << "\\042";
00141 }
00142 else if (isprint(tmp[i]))
00143 {
00144 (*out_) << tmp[i];
00145 }
00146 else
00147 {
00148 unsigned int val = tmp[i];
00149 (*out_) << '\\' << std::oct << val;
00150 }
00151 }
00152 (*out_) << "\"];\n";
00153 }
00154
00155 };
00156 };