1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // assa/Logger_Impl.cpp
4 //------------------------------------------------------------------------------
5 // $Id: Logger_Impl.cpp,v 1.7 2012/05/21 03:20:39 vlg Exp $
6 //------------------------------------------------------------------------------
7 // Copyright (c) Vladislav Grinchenko
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Library General Public
11 // License as published by the Free Software Foundation; either
12 // version 2 of the License, or (at your option) any later version.
13 //------------------------------------------------------------------------------
14
15 #include <iostream>
16 #include <iomanip>
17 #include <string.h> // strerror(3)
18
19 #include "assa/TimeVal.h"
20 #include "assa/Logger_Impl.h"
21
22 #if defined (WIN32)
23 # include <windows.h> // for vsnprintf() bug
24 #else
25 # include <stdio.h>
26 #endif
27
28 using namespace ASSA;
29
30 char Logger_Impl::m_msgbuf [LOGGER_MAXLINE];
31
32 u_short
33 Logger_Impl::
add_timestamp(ostream & sink_)34 add_timestamp (ostream& sink_)
35 {
36 /*--- 'DD/MM/CC HH:MM:SS.MMMM ' - 23 chars ---*/
37 u_short bytecount = 0;
38
39 if (timestamp_enabled ()) {
40 TimeVal tv = TimeVal::gettimeofday ();
41 tv.tz (m_tz);
42 sink_ << tv.fmtString ("%m/%d/%Y %H:%M:%S") << '.';
43 char oldfill = sink_.fill('0');
44 sink_ << std::setw (3) << (tv.msec () % 1000000)/1000 << ' ';
45 sink_.fill (oldfill);
46 bytecount = 23;
47 }
48 return bytecount;
49 }
50
51 u_short
52 Logger_Impl::
indent_func_name(ostream & sink_,const string & func_name_,size_t indent_level_,marker_t type_)53 indent_func_name (ostream& sink_,
54 const string& func_name_,
55 size_t indent_level_,
56 marker_t type_)
57 {
58 u_short bytecount = 0;
59
60 if (func_name_.size ()) {
61 u_int i = 1;
62 while (i < indent_level_) {
63 sink_ << '|';
64 for (u_short j = 0; j < m_indent_step-1; j++) {
65 sink_ << ' ';
66 }
67 i++;
68 }
69 if (type_ == FUNC_ENTRY) {
70 sink_ << '/' << func_name_ << " ";
71 }
72 else if (type_ == FUNC_EXIT) {
73 sink_ << '\\' << func_name_ << " ";
74 }
75 else if (type_ == FUNC_MSG) {
76 sink_ << '[' << func_name_ << "] ";
77 }
78 bytecount += indent_level_ * m_indent_step + func_name_.size () + 3;
79 }
80 return bytecount;
81 }
82
83 char*
84 Logger_Impl::
format_msg(size_t expected_sz_,const char * fmt_,va_list vap_,bool & release_)85 format_msg (size_t expected_sz_,
86 const char* fmt_,
87 va_list vap_,
88 bool& release_) // tell the caller it needs to release memory
89 {
90 char* msg = m_msgbuf; // Use internal buffer
91 int ret = 0;
92
93 release_ = false;
94 expected_sz_++; // Expected size includes '\0'
95
96 if (expected_sz_ >= LOGGER_MAXLINE) { // Allocate temporary buffer
97 msg = new char [expected_sz_];
98 release_ = true;
99 }
100
101 ret = ::vsnprintf (msg, expected_sz_, fmt_, vap_);
102 #if NEVER
103 if (ret < 0) {
104 std::cout << "Logger_Impl: format_mg(expected_sz=" << expected_sz_
105 << ")=-1 failed! errno=" << errno << " ("
106 << strerror(errno) << "\n" << std::flush;
107 }
108 #endif
109
110 return (ret < 0 ? NULL : msg);
111 }
112