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