1 // time_format_holder.hpp 2 3 // Boost Logging library 4 // 5 // Author: John Torjo, www.torjo.com 6 // 7 // Copyright (C) 2007 John Torjo (see www.torjo.com for email) 8 // 9 // Distributed under the Boost Software License, Version 1.0. 10 // (See accompanying file LICENSE_1_0.txt or copy at 11 // http://www.boost.org/LICENSE_1_0.txt) 12 // 13 // See http://www.boost.org for updates, documentation, and revision history. 14 // See http://www.torjo.com/log2/ for more details 15 16 17 #ifndef JT28092007_time_format_holder_HPP_DEFINED 18 #define JT28092007_time_format_holder_HPP_DEFINED 19 20 #include <hpx/util/assert.hpp> 21 #include <hpx/util/logging/detail/fwd.hpp> 22 23 #include <algorithm> 24 #include <cstdio> 25 #include <cstddef> 26 #include <sstream> 27 #include <string> 28 #include <vector> 29 30 namespace hpx { namespace util { namespace logging { namespace detail { 31 32 /** 33 This only holds the time format, and allows writing a certain time 34 */ 35 struct time_format_holder { 36 private: 37 struct index_info { 38 typedef std::size_t uint; 39 index_infohpx::util::logging::detail::time_format_holder::index_info40 index_info(uint src_idx_, int *format_idx_, int advance_size_ = 2, 41 int size_ = 2) 42 : src_idx(src_idx_), format_idx(format_idx_), 43 advance_size(advance_size_), size(size_) {} 44 uint src_idx; 45 int * format_idx; 46 int advance_size; 47 int size; 48 by_indexhpx::util::logging::detail::time_format_holder::index_info49 static bool by_index(const index_info & first, const index_info & second) { 50 return first.src_idx < second.src_idx; 51 } 52 }; 53 54 public: operator ==hpx::util::logging::detail::time_format_holder55 bool operator==(const time_format_holder & other) const { 56 return m_format == other.m_format; 57 } 58 59 60 /** 61 constructs a time format holder object 62 */ time_format_holderhpx::util::logging::detail::time_format_holder63 time_format_holder(const std::string & format) : m_day(-1), 64 m_month(-1), m_yy(-1), m_yyyy(-1), m_hour(-1), m_min(-1), 65 m_sec(-1),m_millisec(-1),m_microsec(-1),m_nanosec(-1) { 66 set_format(format); 67 } 68 set_formathpx::util::logging::detail::time_format_holder69 void set_format(const std::string & format) { 70 // format too big 71 HPX_ASSERT( format.size() < 64); 72 m_format.clear(); 73 74 m_day = -1; m_month = -1; m_yy = -1; m_yyyy = -1; m_hour = -1; 75 m_min = -1; m_sec = -1;m_millisec = -1;m_microsec = -1;m_nanosec = -1; 76 77 typedef std::size_t uint; 78 uint day_idx = format.find("$dd"); 79 uint month_idx = format.find("$MM"); 80 uint yy_idx = format.find("$yy"); 81 uint yyyy_idx = format.find("$yyyy"); 82 uint hour_idx = format.find("$hh"); 83 uint min_idx = format.find("$mm"); 84 uint sec_idx = format.find("$ss"); 85 uint millisec_idx = format.find("$mili"); 86 uint microsec_idx = format.find("$micro"); 87 uint nanosec_idx = format.find("$nano"); 88 89 typedef std::vector<index_info> array; 90 array indexes; 91 if ( day_idx != std::string::npos) 92 indexes.push_back( index_info(day_idx, &m_day) ); 93 if ( month_idx != std::string::npos) 94 indexes.push_back( index_info(month_idx, &m_month) ); 95 96 if ( yy_idx != std::string::npos || yyyy_idx != std::string::npos) { 97 if ( yyyy_idx != std::string::npos) 98 indexes.push_back( index_info(yyyy_idx, &m_yyyy, 4) ); //-V112 99 else 100 indexes.push_back( index_info(yy_idx, &m_yy) ); 101 } 102 103 if ( hour_idx != std::string::npos) 104 indexes.push_back( index_info(hour_idx, &m_hour ) ); 105 if ( min_idx != std::string::npos) 106 indexes.push_back( index_info(min_idx, &m_min) ); 107 if ( sec_idx != std::string::npos) 108 indexes.push_back( index_info(sec_idx, &m_sec) ); 109 if ( millisec_idx != std::string::npos) 110 indexes.push_back( index_info(millisec_idx, &m_millisec, 4, 3) ); 111 //-V112 //-V525 112 if ( microsec_idx != std::string::npos) 113 indexes.push_back( index_info(microsec_idx, &m_microsec, 5, 6) ); 114 if ( nanosec_idx != std::string::npos) 115 indexes.push_back( index_info(nanosec_idx, &m_nanosec, 4, 9) ); //-V112 116 117 std::sort( indexes.begin(), indexes.end(), index_info::by_index); 118 119 // create the format string, that we can actually pass to sprintf 120 uint prev_idx = 0; 121 int idx = 0; 122 for ( array::iterator begin = indexes.begin(), end = indexes.end(); 123 begin != end; ++begin) { 124 m_format += format.substr( prev_idx, begin->src_idx - prev_idx); 125 *begin->format_idx = idx; 126 std::ostringstream cur_sprintf_format; 127 cur_sprintf_format << "%0" << begin->size << "d"; 128 m_format += cur_sprintf_format.str(); 129 prev_idx = static_cast<hpx::util::logging::detail 130 ::time_format_holder::index_info::uint>(begin->src_idx + 131 static_cast<hpx::util::logging::detail::time_format_holder 132 ::index_info::uint>(begin->advance_size) + 1ul); 133 ++idx; 134 } 135 136 m_format += format.substr(prev_idx); 137 } 138 write_timehpx::util::logging::detail::time_format_holder139 void write_time(char buffer[], int day, int month, 140 int year, int hour, int min, int sec, int millisec, int microsec, 141 int nanosec) const { 142 int vals[11]; 143 vals[m_day + 1] = day; 144 vals[m_month + 1] = month; 145 vals[m_yy + 1] = year % 100; 146 vals[m_yyyy + 1] = year; 147 vals[m_hour + 1] = hour; 148 vals[m_min + 1] = min; 149 vals[m_sec + 1] = sec; 150 vals[m_millisec + 1] = millisec; 151 vals[m_microsec + 1] = microsec; 152 vals[m_nanosec + 1] = nanosec; 153 154 // ignore value at index 0 155 // - it's there so that I don't have to test for an index being -1 156 sprintf( buffer, m_format.c_str(), vals[1], vals[2], vals[3], 157 vals[4], vals[5], vals[6], vals[7], vals[8], vals[9], vals[10] ); 158 } 159 write_timehpx::util::logging::detail::time_format_holder160 void write_time(char buffer[], int day, int month, int year, 161 int hour, int min, int sec) const { 162 int vals[8]; 163 vals[m_day + 1] = day; 164 vals[m_month + 1] = month; 165 vals[m_yy + 1] = year % 100; 166 vals[m_yyyy + 1] = year; 167 vals[m_hour + 1] = hour; 168 vals[m_min + 1] = min; 169 vals[m_sec + 1] = sec; 170 171 // ignore value at index 0 172 // - it's there so that I don't have to test for an index being -1 173 sprintf( buffer, m_format.c_str(), vals[1], vals[2], vals[3], 174 vals[4], vals[5], vals[6], vals[7] ); 175 } 176 177 private: 178 // the indexes of each escape sequence within the format string 179 int m_day, m_month, m_yy, m_yyyy, m_hour, m_min, m_sec, m_millisec, 180 m_microsec, m_nanosec; 181 std::string m_format; 182 }; 183 184 }}}} 185 186 #endif 187