|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <map> 00010 00011 #include <stk_util/environment/LogControl.hpp> 00012 00013 namespace stk_classic { 00014 00015 namespace { 00016 00017 typedef std::map<std::ostream *, LogControl *> OStreamLogControlMap; 00018 00019 OStreamLogControlMap & 00020 get_ostream_log_control_map() 00021 { 00022 static OStreamLogControlMap s_ostreamLogControlMap; 00023 00024 return s_ostreamLogControlMap; 00025 } 00026 00027 } // namespace <unnamed> 00028 00029 00030 LogControlRuleInterval::LogControlRuleInterval( 00031 int interval) 00032 : m_interval(interval), 00033 m_count(-1) 00034 {} 00035 00036 00037 bool 00038 LogControlRuleInterval::next() 00039 { 00040 ++m_count; 00041 00042 if (m_count < 0) { 00043 return false; 00044 } 00045 00046 else if (m_count == 0) { 00047 return true; 00048 } 00049 00050 else { 00051 return m_count%m_interval == 0 ? true : false; 00052 } 00053 } 00054 00055 00056 LogControl::LogControl( 00057 std::ostream & log_ostream, 00058 const LogControlRule & rule) 00059 : m_parent(0), 00060 m_rule(rule.clone()), 00061 m_state(ON), 00062 m_logStream(log_ostream), 00063 m_logStreambuf(log_ostream.rdbuf()), 00064 m_cacheStream() 00065 { 00066 OStreamLogControlMap &ostream_log_control_map = get_ostream_log_control_map(); 00067 00068 // Append this as tail of linked list of LogControl's sharing this ostream. 00069 m_parent = ostream_log_control_map[&m_logStream]; 00070 ostream_log_control_map[&m_logStream] = this; 00071 00072 // Make sure log stream buffer is that of the root's. 00073 for (LogControl *parent = m_parent; parent != 0; parent = parent->m_parent) 00074 m_logStreambuf = parent->m_logStream.rdbuf(); 00075 } 00076 00077 00078 // LogControl::LogControl( 00079 // std::ostream & log_ostream, 00080 // const std::string & rule_name) 00081 // : m_parent(0), 00082 // m_rule(get_rule_map().getLogControlRule(rule_name)->clone()), 00083 // m_state(ON), 00084 // m_logStream(log_ostream), 00085 // m_logStreambuf(log_ostream.rdbuf()), 00086 // m_cacheStream() 00087 // { 00088 // OStreamLogControlMap &ostream_log_control_map = get_ostream_log_control_map(); 00089 00090 // // Append this as tail of linked list of LogControl's sharing this ostream. 00091 // m_parent = ostream_log_control_map[&m_logStream]; 00092 // ostream_log_control_map[&m_logStream] = this; 00093 // } 00094 00095 00096 LogControl::~LogControl() 00097 { 00098 OStreamLogControlMap &ostream_log_control_map = get_ostream_log_control_map(); 00099 00100 // Reset tail pointer to this's parent. 00101 ostream_log_control_map[&m_logStream] = m_parent; 00102 00103 // Reset log stream to either the parent's cache or the original log stream buffer. And, 00104 // concatenate cached text to the parent's cache or log stream. 00105 if (!m_parent || m_parent->m_state == ON) { // Parent is writing 00106 m_logStream.rdbuf(m_logStreambuf); // Set output stream back to real buffer 00107 if (m_state == CACHE) // This is caching 00108 m_logStream << m_cacheStream.str(); // Last cache is always written 00109 } 00110 else { // Parent is caching 00111 m_logStream.rdbuf(m_parent->m_cacheStream.rdbuf()); // Set output to parent's cache 00112 m_parent->m_cacheStream << m_cacheStream.str(); // Append our cache to parent's 00113 } 00114 00115 delete m_rule; 00116 } 00117 00118 00119 void 00120 LogControl::fail() 00121 { 00122 m_logStream.rdbuf(m_logStreambuf); 00123 m_logStream << m_cacheStream.str(); 00124 m_cacheStream.str(""); 00125 m_state = ON; 00126 } 00127 00128 00129 void 00130 LogControl::next() 00131 { 00132 m_cacheStream.str(""); 00133 00134 if (m_parent && m_parent->m_state == CACHE) 00135 m_state = CACHE; 00136 else 00137 m_state = !m_rule || m_rule->next() ? ON : CACHE; 00138 00139 if (m_state != CACHE) { 00140 if (m_logStream.rdbuf() != m_logStreambuf) { 00141 m_logStream.rdbuf(m_logStreambuf); 00142 } 00143 } 00144 else { 00145 if (m_logStream.rdbuf() != m_cacheStream.rdbuf()) 00146 m_logStream.rdbuf(m_cacheStream.rdbuf()); 00147 } 00148 } 00149 00150 00151 } // namespace stk_classic