Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef ZORBA_AUDIT_SCOPED_H
00018 #define ZORBA_AUDIT_SCOPED_H
00019
00020 #include <iostream>
00021 #include <sstream>
00022 #include <cassert>
00023 #include <zorba/audit.h>
00024 #include <zorba/util/timer.h>
00025
00026 namespace zorba {
00027 namespace audit {
00028
00029 class ZORBA_DLL_PUBLIC ScopedRecord {
00030 public:
00031 ScopedRecord(Event* event) : theEvent(event), theRecord(0) {
00032 assert(event);
00033 }
00034
00035 ~ScopedRecord() {
00036 if (theRecord) {
00037 theEvent->submitRecord(theRecord);
00038 theRecord = 0;
00039 }
00040 }
00041
00042 Event* getEvent() {
00043 return theEvent;
00044 }
00045
00046 Record* getRecord() {
00047 if (! theRecord) {
00048 theRecord = theEvent->createRecord();
00049 }
00050 return theRecord;
00051 }
00052
00053 private:
00054 Event* theEvent;
00055 Record* theRecord;
00056 };
00057
00058 template <class T, unsigned char flags = 0> struct AuditorTraits {
00059 };
00060
00061 template <class T, unsigned char flags = 0> class ScopedAuditor {
00062 public:
00063 ScopedAuditor(ScopedRecord& record, const Property& prop, T& value)
00064 : theRecord(record), theProperty(prop), theValue(value) {
00065 theNeedToAuditFlag = record.getEvent()->audit(prop);
00066 if (theNeedToAuditFlag) {
00067 AuditorTraits<T, flags>::start(value);
00068 }
00069 }
00070
00071 ScopedAuditor(ScopedRecord& record, const String& prop_name, T& value)
00072 : theRecord(record),
00073 theProperty(*record.getEvent()->getDynamicProperty(prop_name)),
00074 theValue(value) {
00075 theNeedToAuditFlag = record.getEvent()->audit(prop_name);
00076 if (theNeedToAuditFlag) {
00077 AuditorTraits<T>::start(value);
00078 }
00079 }
00080
00081 ~ScopedAuditor() {
00082 now();
00083 }
00084
00085 void now() {
00086 if (theNeedToAuditFlag) {
00087 Record* rec = theRecord.getRecord();
00088 rec->add(theProperty, AuditorTraits<T, flags>::end(theValue));
00089 theNeedToAuditFlag = false;
00090 }
00091 }
00092
00093 private:
00094 ScopedAuditor() {}
00095 ScopedAuditor(const ScopedAuditor&) {}
00096
00097 ScopedRecord& theRecord;
00098 const Property& theProperty;
00099 bool theNeedToAuditFlag;
00100 T& theValue;
00101 };
00102
00103 typedef ScopedAuditor<const std::string> StringAuditor;
00104 typedef ScopedAuditor<const int> IntAuditor;
00105 typedef ScopedAuditor<zorba::time::Timer> DurationAuditor;
00106 typedef ScopedAuditor<zorba::time::Timer, 0x1> TimestampAuditor;
00107
00108 template<> struct AuditorTraits<const std::string> {
00109 typedef const std::string value_type;
00110 typedef const std::string audit_type;
00111 static inline void start(value_type& value) {
00112 }
00113 static inline audit_type end(value_type& value) {
00114 return value;
00115 }
00116 };
00117
00118 template<> struct AuditorTraits<String> {
00119 typedef String value_type;
00120 typedef String audit_type;
00121 static inline void start(value_type& value) {
00122 }
00123 static inline audit_type end(value_type& value) {
00124 return value;
00125 }
00126 };
00127
00128 template<> struct AuditorTraits<const int> {
00129 typedef const int value_type;
00130 typedef long long audit_type;
00131 static inline void start(value_type& value) {
00132 }
00133 static inline audit_type end(value_type& value) {
00134 return value;
00135 }
00136 };
00137
00138 template<> struct AuditorTraits<const char*> {
00139 typedef const char* value_type;
00140 typedef const char* audit_type;
00141 static inline void start(value_type& value) {
00142 }
00143 static inline audit_type end(value_type& value) {
00144 return value;
00145 }
00146 };
00147
00148 template<> struct AuditorTraits< std::pair<std::streampos, std::istream*> > {
00149 typedef std::pair<std::streampos, std::istream*> value_type;
00150 typedef long long audit_type;
00151 static inline void start(value_type& value) {
00152 value.first = value.second->tellg();
00153 }
00154 static inline audit_type end(value_type& value) {
00155 return value.second->tellg() - value.first;
00156 }
00157 };
00158
00159 template<> struct AuditorTraits< std::pair<std::streampos, std::ostream*> > {
00160 typedef std::pair<std::streampos, std::ostream*> value_type;
00161 typedef long long audit_type;
00162 static inline void start(value_type& value) {
00163 value.first = value.second->tellp();
00164 }
00165 static inline audit_type end(value_type& value) {
00166 return value.second->tellp() - value.first;
00167 }
00168 };
00169
00170 template<> struct AuditorTraits<zorba::time::Timer> {
00171 typedef zorba::time::Timer value_type;
00172 typedef long long audit_type;
00173 static inline void start(value_type& value) {
00174 value.start();
00175 }
00176 static inline audit_type end(value_type& value) {
00177 return static_cast<audit_type>(value.elapsed());
00178 }
00179
00180 };
00181
00182 template<> struct AuditorTraits<zorba::time::Timer, 0x1> {
00183 typedef zorba::time::Timer value_type;
00184 typedef long long audit_type;
00185 static inline void start(value_type& value) {
00186 value.start();
00187 }
00188 static inline audit_type end(value_type& value) {
00189 return static_cast<audit_type>(value.getStart());
00190 }
00191 };
00192 }
00193 }
00194 #endif
00195