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
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __PRINTABLE_H
00034 #define __PRINTABLE_H
00035
00036 #include <string>
00037 #include <sstream>
00038 #include <iomanip>
00039 #include <ctype.h>
00040 #include <boost/shared_ptr.hpp>
00041 #include <boost/lexical_cast.hpp>
00042 #include <map>
00043 #include <list>
00044
00045 #include "hash_string.h"
00046 #include "Base64.h"
00047
00053 namespace mace {
00054
00065 class PrintNode;
00066 typedef std::list<PrintNode> PrintNodeList;
00067
00068 class PrintNode {
00069 public:
00070 PrintNode() { }
00071 virtual ~PrintNode() { }
00072
00073 PrintNode(const std::string& name, const std::string& type, const std::string& value = std::string()) :
00074 name(name), type(type), value(value) { }
00075
00076 void addChild(const PrintNode& n) { children.push_back(n); }
00077 const PrintNodeList& getChildren() const { return children; }
00078 const std::string& getName() const { return name; }
00079 const std::string& getType() const { return type; }
00080 const std::string& getValue() const { return value; }
00081
00082 protected:
00083 std::string name;
00084 std::string type;
00085 std::string value;
00086 PrintNodeList children;
00087 };
00088
00089
00090 class Printable {
00091 public:
00092 virtual std::string toString() const = 0;
00093
00094
00097 virtual std::string toStateString() const = 0;
00098 virtual std::string toXml() const = 0;
00099 virtual void print(std::ostream& printer) const = 0;
00100 virtual void printState(std::ostream& printer) const = 0;
00101 virtual void print(PrintNode& printer, const std::string& name) const = 0;
00102 virtual void printXml(std::ostream& printer) const = 0;
00103 virtual ~Printable() {}
00104 };
00105
00109 class PrintPrintable : virtual public Printable {
00110 public:
00111 std::string toString() const {
00112 std::ostringstream out;
00113 print(out);
00114 return out.str();
00115 }
00116 std::string toStateString() const {
00117 std::ostringstream out;
00118 printState(out);
00119 return out.str();
00120 }
00121 std::string toXml() const {
00122 std::ostringstream out;
00123 printXml(out);
00124 return out.str();
00125 }
00126 virtual void printState(std::ostream& printer) const {
00127 print(printer);
00128 }
00129 virtual void printXml(std::ostream& printer) const {
00130 printer << "<generic>";
00131 print(printer);
00132 printer << "</generic>";
00133 }
00134 using Printable::print;
00135 virtual void print(PrintNode& printer, const std::string& name) const {
00136 printer.addChild(PrintNode(name, std::string(), toString()));
00137 }
00138
00139 virtual ~PrintPrintable() {}
00140 };
00141
00146 class ToStringPrintable : virtual public Printable {
00147 public:
00148 virtual void print(PrintNode& printer, const std::string& name) const {
00149 printer.addChild(PrintNode(name, std::string(), toString()));
00150 }
00151 void print(std::ostream& printer) const {
00152 printer << toString();
00153 }
00154 void printState(std::ostream& printer) const {
00155 printer << toStateString();
00156 }
00157 void printXml(std::ostream& printer) const {
00158 printer << toXml();
00159 }
00160 virtual std::string toStateString() const {
00161 return toString();
00162 }
00163 virtual std::string toXml() const {
00164 return toString();
00165 }
00166 virtual ~ToStringPrintable() {}
00167 };
00168
00170 template<typename S>
00171 const int noConvertToString(const S* dud) { return 0; }
00172
00184 inline void printItem(std::ostream& out, const void* pitem) {
00185
00186 std::ios::fmtflags f(out.flags());
00187 out << std::hex;
00188 out << "[NON-PRINTABLE: ptr=" << pitem << "]";
00189 out.flags(f);
00190 }
00191
00192 inline void printItem(PrintNode& pr, const std::string& name, const void* pitem) {
00193 std::ostringstream os;
00194 os << std::hex;
00195 os << pitem;
00196 pr.addChild(PrintNode(name, "void*", os.str()));
00197 }
00198
00199 inline void printItem(std::ostream& out, const bool* pitem) {
00200 out << (*pitem?"true":"false");
00201 }
00202
00203 inline void printItem(PrintNode& pr, const std::string& name, const bool* pitem) {
00204 pr.addChild(PrintNode(name, "bool", *pitem ? "true" : "false"));
00205 }
00206
00207 inline void printItem(std::ostream& out, const double* pitem) {
00208 out << *pitem;
00209 }
00210
00211 inline void printItem(PrintNode& pr, const std::string& name, const double* pitem) {
00212 pr.addChild(PrintNode(name, "double", boost::lexical_cast<std::string>(*pitem)));
00213 }
00214
00215 inline void printItem(std::ostream& out, const float* pitem) {
00216 out << *pitem;
00217 }
00218
00219 inline void printItem(PrintNode& pr, const std::string& name, const float* pitem) {
00220 pr.addChild(PrintNode(name, "float", boost::lexical_cast<std::string>(*pitem)));
00221 }
00222
00223 inline void printItem(std::ostream& out, const int* pitem) {
00224 out << *pitem;
00225 }
00226
00227 inline void printItem(PrintNode& pr, const std::string& name, const int* pitem) {
00228 pr.addChild(PrintNode(name, "int", boost::lexical_cast<std::string>(*pitem)));
00229 }
00230
00231 inline void printItem(std::ostream& out, const char* pitem) {
00232 out << (int)*pitem;
00233 if(isprint(*pitem)) {
00234 out << " '" << (*pitem) << "'";
00235 }
00236 }
00237
00238 inline void printItem(PrintNode& pr, const std::string& name, const char* pitem) {
00239 std::ostringstream os;
00240 os << (int)*pitem;
00241 if (isprint(*pitem)) {
00242 os << " '" << (*pitem) << "'";
00243 }
00244 pr.addChild(PrintNode(name, "char", os.str()));
00245 }
00246
00247 inline void printItem(std::ostream& out, const unsigned int* pitem) {
00248 out << *pitem;
00249 }
00250
00251 inline void printItem(PrintNode& pr, const std::string& name, const unsigned int* pitem) {
00252 pr.addChild(PrintNode(name, "uint", boost::lexical_cast<std::string>(*pitem)));
00253 }
00254
00255 inline void printItem(std::ostream& out, const long int* pitem) {
00256 out << *pitem;
00257 }
00258
00259 inline void printItem(PrintNode& pr, const std::string& name, const long int* pitem) {
00260 pr.addChild(PrintNode(name, "long", boost::lexical_cast<std::string>(*pitem)));
00261 }
00262
00263 inline void printItem(std::ostream& out, const short* pitem) {
00264 out << *pitem;
00265 }
00266
00267 inline void printItem(PrintNode& pr, const std::string& name, const short* pitem) {
00268 pr.addChild(PrintNode(name, "short", boost::lexical_cast<std::string>(*pitem)));
00269 }
00270
00271 inline void printItem(std::ostream& out, const unsigned short* pitem) {
00272 out << *pitem;
00273 }
00274
00275 inline void printItem(PrintNode& pr, const std::string& name, const unsigned short* pitem) {
00276 pr.addChild(PrintNode(name, "ushort", boost::lexical_cast<std::string>(*pitem)));
00277 }
00278
00279 inline void printItem(std::ostream& out, const unsigned long long* pitem) {
00280 out << *pitem;
00281 }
00282
00283 inline void printItem(PrintNode& pr, const std::string& name, const unsigned long long* pitem) {
00284 pr.addChild(PrintNode(name, "ullong", boost::lexical_cast<std::string>(*pitem)));
00285 }
00286
00287 inline void printItem(std::ostream& out, const long long* pitem) {
00288 out << *pitem;
00289 }
00290
00291 inline void printItem(PrintNode& pr, const std::string& name, const long long* pitem) {
00292 pr.addChild(PrintNode(name, "llong", boost::lexical_cast<std::string>(*pitem)));
00293 }
00294
00295 #ifdef UINT64T_IS_NOT_ULONGLONG
00296 inline void printItem(std::ostream& out, const uint64_t* pitem) {
00297 out << *pitem;
00298 }
00299
00300 inline void printItem(PrintNode& pr, const std::string& name, const uint64_t* pitem) {
00301 pr.addChild(PrintNode(name, "uint64", boost::lexical_cast<std::string>(*pitem)));
00302 }
00303
00304
00305
00306
00307
00308 #endif
00309
00310 inline void printItem(std::ostream& out, const std::string* pitem) {
00311 if (Base64::isPrintable(*pitem)) {
00312 out << *pitem;
00313 } else {
00314 static const hash_string hasher = hash_string();
00315 out << "(str)[" << hasher(*pitem) << "]";
00316 }
00317 }
00318
00319 inline void printItem(PrintNode& pr, const std::string& name, const std::string* pitem) {
00320 static const hash_string hasher = hash_string();
00321 pr.addChild(PrintNode(name, "string",
00322 Base64::isPrintable(*pitem) ? *pitem : "(str)[" + boost::lexical_cast<std::string>(hasher(*pitem)) + "]"));
00323 }
00324
00325 inline void printItem(std::ostream& out, const char** pitem) {
00326 out << *pitem;
00327 }
00328
00329 inline void printItem(PrintNode& pr, const std::string& name, const char** pitem) {
00330 pr.addChild(PrintNode(name, "string", *pitem));
00331 }
00332
00333 inline void printItem(std::ostream& out, const Printable* pitem) {
00334 pitem->print(out);
00335 }
00336
00337 inline void printItem(PrintNode& pr, const std::string& name, const Printable* pitem) {
00338 pitem->print(pr, name);
00339 }
00340
00341 inline void printItem(std::ostream& out, const Printable** pitem) {
00342
00343 (*pitem)->print(out);
00344 }
00345
00346 inline void printItem(PrintNode& pr, const std::string& name, const Printable** pitem) {
00347 (*pitem)->print(pr, name);
00348 }
00349
00350 template<typename S>
00351 void printItem(std::ostream& out, const boost::shared_ptr<S>* pitem) {
00352 out << "shared_ptr(";
00353 mace::printItem(out, pitem->get());
00354 out << ")";
00355 }
00356
00357 template<typename S>
00358 void printItem(PrintNode& pr, const std::string& name, const boost::shared_ptr<S>* pitem) {
00359 mace::printItem(pr, name, pitem->get());
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00370 template<typename S>
00371 std::string mapToString(const S& m, bool newlines = false) {
00372 std::ostringstream os;
00373 for (typename S::const_iterator i = m.begin(); i != m.end(); i++) {
00374 os << "( " << convertToString(&(i->first), i->first) << " -> " << convertToString(&(i->second), i->second) << " )";
00375 if (newlines) {
00376 os << std::endl;
00377 }
00378 else {
00379 os << " ";
00380 }
00381 }
00382 return os.str();
00383 }
00384
00385 template<typename S>
00386 void printMap(PrintNode& pr, const std::string& name, const std::string& type, const S& b, const S& e) {
00387 PrintNode node(name, type);
00388 size_t n = 0;
00389 for (S i = b; i != e; i++) {
00390 std::string sn = boost::lexical_cast<std::string>(n);
00391 printItem(node, "key" + sn, &(i->first));
00392 printItem(node, "value" + sn, &(i->second));
00393 n++;
00394 }
00395 pr.addChild(node);
00396 }
00397
00399 template<typename S>
00400 void printMap(std::ostream& os, const S& b, const S& e, bool newlines = false) {
00401 os << "[";
00402 if(newlines) { os << std::endl; } else { os << " "; }
00403 for (S i = b; i != e; i++) {
00404 os << "( ";
00405 printItem(os, &(i->first));
00406 os << " -> ";
00407 printItem(os, &(i->second));
00408 os << " )";
00409 if (newlines) {
00410 os << std::endl;
00411 }
00412 else {
00413 os << " ";
00414 }
00415 }
00416 os << "]";
00417 if (newlines) {
00418 os << std::endl;
00419 }
00420 }
00421
00423 template<typename S>
00424 void printMapState(std::ostream& os, const S& b, const S& e, bool newlines = false) {
00425 os << "[";
00426 if(newlines) { os << std::endl; } else { os << " "; }
00427 for (S i = b; i != e; i++) {
00428 os << "( ";
00429 printState(os, &(i->first), i->first);
00430 os << " -> ";
00431 printState(os, &(i->second), i->second);
00432 os << " )";
00433 if (newlines) {
00434 os << std::endl;
00435 }
00436 else {
00437 os << " ";
00438 }
00439 }
00440 os << "]";
00441 if (newlines) {
00442 os << std::endl;
00443 }
00444 }
00445
00447 template<typename S>
00448 std::string listToString(const S& l, bool newlines = false) {
00449 std::ostringstream os;
00450 for (typename S::const_iterator i = l.begin(); i != l.end(); i++) {
00451 os << convertToString(&(*i), *i);
00452 if (newlines) {
00453 os << std::endl;
00454 }
00455 else {
00456 os << " ";
00457 }
00458 }
00459 return os.str();
00460 }
00461
00463 template<typename S>
00464 std::string listToString(const S& b, const S& e, bool newlines = false) {
00465 std::ostringstream os;
00466 for (S i = b; i != e; i++) {
00467 os << convertToString(&(*i), *i);
00468 if (newlines) {
00469 os << std::endl;
00470 }
00471 else {
00472 os << " ";
00473 }
00474 }
00475 return os.str();
00476 }
00477
00479 template<typename S>
00480 void printList(std::ostream& os, const S& b, const S& e, bool newlines = false) {
00481 os << "[";
00482 if(newlines) { os << std::endl; } else { os << " "; }
00483 for (S i = b; i != e; i++) {
00484 printItem(os, &(*i));
00485 if (newlines) {
00486 os << std::endl;
00487 }
00488 else {
00489 os << " ";
00490 }
00491 }
00492 os << "]";
00493 if (newlines) {
00494 os << std::endl;
00495 }
00496 }
00497
00498 template<typename S>
00499 void printList(PrintNode& pr, const std::string& name, const std::string& type, const S& b, const S& e) {
00500 PrintNode node(name, type);
00501 size_t n = 0;
00502 for (S i = b; i != e; i++) {
00503 printItem(node, "item" + boost::lexical_cast<std::string>(n), &(*i));
00504 n++;
00505 }
00506 pr.addChild(node);
00507 }
00508
00510 template<typename S>
00511 std::string pointerListToString(const S& l, bool newlines = false) {
00512 std::ostringstream os;
00513 for (typename S::const_iterator i = l.begin(); i != l.end(); i++) {
00514 os << convertToString(&(**i), **i);
00515 if (newlines) {
00516 os << std::endl;
00517 }
00518 else {
00519 os << " ";
00520 }
00521 }
00522 return os.str();
00523 }
00524
00526
00530 template<typename S>
00531 std::string convertToString(const S* pitem, const S& item) {
00532 std::ostringstream out;
00533 mace::printItem(out, pitem);
00534 return out.str();
00535 }
00536
00538
00542 template<typename S>
00543 void printState(std::ostream& out, const void* pitem, const S& item) {
00544 mace::printItem(out, &item);
00545 }
00546
00548
00551 template<typename S>
00552 void printState(std::ostream& out, const Printable* pitem, const S& item) {
00553 item.printState(out);
00554 }
00555
00556 template<typename S>
00557 void printState(std::ostream& out, const boost::shared_ptr<S>* pitem, const boost::shared_ptr<S>& item) {
00558 out << "shared_ptr(";
00559 mace::printState(out, item.get(), *item);
00560 out << ")";
00561 }
00562
00564 template<typename S>
00565 void printListState(std::ostream& os, const S& b, const S& e, bool newlines = false) {
00566 os << "[";
00567 if(newlines) { os << std::endl; } else { os << " "; }
00568 for (S i = b; i != e; i++) {
00569 printState(os, &(*i), *i);
00570 if (newlines) {
00571 os << std::endl;
00572 }
00573 else {
00574 os << " ";
00575 }
00576 }
00577 os << "]";
00578 if (newlines) {
00579 os << std::endl;
00580 }
00581 }
00582
00584 template<typename S>
00585 void printXml(std::ostream& os, const void* pitem, const S& item) {
00586 mace::printItem(os, &item);
00587 }
00588
00589 template<typename S>
00590 void printXml(std::ostream& os, const Printable* pitem, const S& item) {
00591 pitem->printXml(os);
00592 }
00593
00594 }
00595
00597 inline std::ostream& operator<<(std::ostream& o, const mace::Printable& p) {
00598 p.print(o);
00599 return o;
00600 }
00601
00602 #endif //__PRINTABLE_H
00603