audit_scoped.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 The FLWOR Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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 /* vim:set et sw=2 ts=2: */
blog comments powered by Disqus