diff options
Diffstat (limited to 'ACE/ace/Log_Record.cpp')
-rw-r--r-- | ACE/ace/Log_Record.cpp | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/ACE/ace/Log_Record.cpp b/ACE/ace/Log_Record.cpp new file mode 100644 index 00000000000..ab30d20790b --- /dev/null +++ b/ACE/ace/Log_Record.cpp @@ -0,0 +1,372 @@ +// $Id$ + +#include "ace/Log_Record.h" + +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_time.h" +#include "ace/CDR_Stream.h" + +#if !defined (__ACE_INLINE__) +# include "ace/Log_Record.inl" +#endif /* __ACE_INLINE__ */ + +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) +// FUZZ: disable check_for_streams_include +# include "ace/streams.h" +#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ + +#include "ace/OS_Memory.h" + +ACE_RCSID(ace, Log_Record, "$Id$") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Log_Record) + +namespace +{ + // Symbolic names for the <ACE_Log_Priority> enumerators. + ACE_TCHAR const * ace_priority_names[] = + { + ACE_LIB_TEXT ("LM_SHUTDOWN"), + ACE_LIB_TEXT ("LM_TRACE"), + ACE_LIB_TEXT ("LM_DEBUG"), + ACE_LIB_TEXT ("LM_INFO"), + ACE_LIB_TEXT ("LM_NOTICE"), + ACE_LIB_TEXT ("LM_WARNING"), + ACE_LIB_TEXT ("LM_STARTUP"), + ACE_LIB_TEXT ("LM_ERROR"), + ACE_LIB_TEXT ("LM_CRITICAL"), + ACE_LIB_TEXT ("LM_ALERT"), + ACE_LIB_TEXT ("LM_EMERGENCY"), + ACE_LIB_TEXT ("LM_UNK(04000)"), + ACE_LIB_TEXT ("LM_UNK(010000)"), + ACE_LIB_TEXT ("LM_UNK(020000)"), + ACE_LIB_TEXT ("LM_UNK(040000)"), + ACE_LIB_TEXT ("LM_UNK(0100000)"), + ACE_LIB_TEXT ("LM_UNK(0200000)"), + ACE_LIB_TEXT ("LM_UNK(0400000)"), + ACE_LIB_TEXT ("LM_UNK(01000000)"), + ACE_LIB_TEXT ("LM_UNK(02000000)"), + ACE_LIB_TEXT ("LM_UNK(04000000)"), + ACE_LIB_TEXT ("LM_UNK(010000000)"), + ACE_LIB_TEXT ("LM_UNK(020000000)"), + ACE_LIB_TEXT ("LM_UNK(040000000)"), + ACE_LIB_TEXT ("LM_UNK(0100000000)"), + ACE_LIB_TEXT ("LM_UNK(0200000000)"), + ACE_LIB_TEXT ("LM_UNK(0400000000)"), + ACE_LIB_TEXT ("LM_UNK(01000000000)"), + ACE_LIB_TEXT ("LM_UNK(02000000000)"), + ACE_LIB_TEXT ("LM_UNK(04000000000)"), + ACE_LIB_TEXT ("LM_UNK(010000000000)"), + ACE_LIB_TEXT ("LM_UNK(020000000000)") + }; +} + +const ACE_TCHAR * +ACE_Log_Record::priority_name (ACE_Log_Priority p) +{ + return ace_priority_names[ACE::log2 (p)]; +} + +void +ACE_Log_Record::priority_name (ACE_Log_Priority p, + const ACE_TCHAR *name) +{ + // Name must be a statically allocated string + ace_priority_names[ACE::log2 (p)] = name; +} + +u_long +ACE_Log_Record::priority (void) const +{ + ACE_TRACE ("ACE_Log_Record::priority"); + + // Get the priority of the <Log_Record> <type_>. This is computed + // as the base 2 logarithm of <type_> (which must be a power of 2, + // as defined by the enums in <ACE_Log_Priority>). + return ACE::log2 ((u_long) this->type_); +} + +void +ACE_Log_Record::priority (u_long p) +{ + ACE_TRACE ("ACE_Log_Record::priority"); + + // Set the priority of the <Log_Record> <type_> (which must be a + // power of 2, as defined by the enums in <ACE_Log_Priority>). + this->type_ = (ACE_UINT32) p; +} + +void +ACE_Log_Record::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Log_Record::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("length_ = %d\n"), this->length_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntype_ = %u\n"), this->type_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntime_stamp_ = (%d, %d)\n"), this->secs_, this->usecs_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\npid_ = %u\n"), this->pid_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmsg_data_ = %s\n"), this->msg_data_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +void +ACE_Log_Record::msg_data (const ACE_TCHAR *data) +{ + // ACE_TRACE ("ACE_Log_Record::msg_data"); + ACE_OS::strsncpy (this->msg_data_, data, + (MAXLOGMSGLEN / sizeof (ACE_TCHAR))); + this->round_up (); +} + +ACE_Log_Record::ACE_Log_Record (ACE_Log_Priority lp, + long ts_sec, + long p) + : length_ (0), + type_ (ACE_UINT32 (lp)), + secs_ (ts_sec), + usecs_ (0), + pid_ (ACE_UINT32 (p)), + msg_data_ (0) +{ + // ACE_TRACE ("ACE_Log_Record::ACE_Log_Record"); + ACE_NEW_NORETURN (this->msg_data_, ACE_TCHAR[MAXLOGMSGLEN]); +} + +ACE_Log_Record::ACE_Log_Record (ACE_Log_Priority lp, + const ACE_Time_Value &ts, + long p) + : length_ (0), + type_ (ACE_UINT32 (lp)), + secs_ ((ACE_UINT32) ts.sec ()), + usecs_ ((ACE_UINT32) ts.usec ()), + pid_ (ACE_UINT32 (p)), + msg_data_ (0) +{ + // ACE_TRACE ("ACE_Log_Record::ACE_Log_Record"); + ACE_NEW_NORETURN (this->msg_data_, ACE_TCHAR[MAXLOGMSGLEN]); +} + +void +ACE_Log_Record::round_up (void) +{ + // ACE_TRACE ("ACE_Log_Record::round_up"); + // Determine the length of the payload. + size_t len = sizeof (*this) + (sizeof (ACE_TCHAR) * ((ACE_OS::strlen (this->msg_data_) + 1))); + + // Round up to the alignment. + len = ((len + ACE_Log_Record::ALIGN_WORDB - 1) + & ~(ACE_Log_Record::ALIGN_WORDB - 1)); + this->length_ = static_cast<ACE_UINT32> (len); +} + +ACE_Log_Record::ACE_Log_Record (void) + : length_ (0), + type_ (0), + secs_ (0), + usecs_ (0), + pid_ (0), + msg_data_ (0) +{ + // ACE_TRACE ("ACE_Log_Record::ACE_Log_Record"); + ACE_NEW_NORETURN (this->msg_data_, ACE_TCHAR[MAXLOGMSGLEN]); +} + +int +ACE_Log_Record::format_msg (const ACE_TCHAR host_name[], + u_long verbose_flag, + ACE_TCHAR *verbose_msg) +{ + /* 0123456789012345678901234 */ + /* Oct 18 14:25:36.000 1989<nul> */ + ACE_TCHAR timestamp[26]; // Only used by VERBOSE and VERBOSE_LITE. + + // The sprintf format needs to be different for Windows and POSIX + // in the wide-char case. +#if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR) + const ACE_TCHAR *time_fmt = ACE_LIB_TEXT ("%s.%03ld %s"); + const ACE_TCHAR *verbose_fmt = ACE_LIB_TEXT ("%s@%s@%u@%s@%s"); + const ACE_TCHAR *verbose_lite_fmt = ACE_LIB_TEXT ("%s@%s@%s"); +#else + const ACE_TCHAR *time_fmt = ACE_LIB_TEXT ("%ls.%03ld %ls"); + const ACE_TCHAR *verbose_fmt = ACE_LIB_TEXT ("%ls@%ls@%u@%ls@%ls"); + const ACE_TCHAR *verbose_lite_fmt = ACE_LIB_TEXT ("%ls@%ls@%ls"); +#endif + + if (ACE_BIT_ENABLED (verbose_flag, + ACE_Log_Msg::VERBOSE) + || ACE_BIT_ENABLED (verbose_flag, + ACE_Log_Msg::VERBOSE_LITE)) + { + time_t const now = this->secs_; + ACE_TCHAR ctp[26]; // 26 is a magic number... + + if (ACE_OS::ctime_r (&now, ctp, sizeof ctp) == 0) + return -1; + + /* 01234567890123456789012345 */ + /* Wed Oct 18 14:25:36 1989n0 */ + + ctp[19] = '\0'; // NUL-terminate after the time. + ctp[24] = '\0'; // NUL-terminate after the date. + + ACE_OS::sprintf (timestamp, + time_fmt, + ctp + 4, + ((long) this->usecs_) / 1000, + ctp + 20); + } + + if (ACE_BIT_ENABLED (verbose_flag, + ACE_Log_Msg::VERBOSE)) + { + const ACE_TCHAR *lhost_name = ((host_name == 0) + ? ACE_LIB_TEXT ("<local_host>") + : host_name); + ACE_OS::sprintf (verbose_msg, + verbose_fmt, + timestamp, + lhost_name, + this->pid_, + ACE_Log_Record::priority_name (ACE_Log_Priority (this->type_)), + this->msg_data_); + } + else if (ACE_BIT_ENABLED (verbose_flag, ACE_Log_Msg::VERBOSE_LITE)) + ACE_OS::sprintf (verbose_msg, + verbose_lite_fmt, + timestamp, + ACE_Log_Record::priority_name (ACE_Log_Priority (this->type_)), + this->msg_data_); + else + ACE_OS::strcpy (verbose_msg, this->msg_data_); + return 0; +} + +int +ACE_Log_Record::print (const ACE_TCHAR host_name[], + u_long verbose_flag, + FILE *fp) +{ + if (ACE_LOG_MSG->log_priority_enabled (ACE_Log_Priority (this->type_))) + { + ACE_TCHAR *verbose_msg = 0; + ACE_NEW_RETURN (verbose_msg, ACE_TCHAR[MAXVERBOSELOGMSGLEN], -1); + + int result = this->format_msg (host_name, + verbose_flag, + verbose_msg); + + if (result == 0) + { + if (fp != 0) + { + int verbose_msg_len = + static_cast<int> (ACE_OS::strlen (verbose_msg)); + int fwrite_result = ACE_OS::fprintf (fp, + ACE_LIB_TEXT ("%s"), + verbose_msg); + // We should have written everything + if (fwrite_result != verbose_msg_len) + result = -1; + else + ACE_OS::fflush (fp); + } + } + + delete [] verbose_msg; + + return result; + } + else + return 0; +} + +int +operator<< (ACE_OutputCDR &cdr, + const ACE_Log_Record &log_record) +{ + size_t msglen = log_record.msg_data_len (); + // The ACE_Log_Record::msg_data () function is non-const, since it + // returns a non-const pointer to internal class members. Since we + // know that no members are modified here, we can safely const_cast + // the log_record parameter without violating the interface + // contract. + ACE_Log_Record &nonconst_record = (const_cast<ACE_Log_Record&> (log_record)); + // Insert each field from <log_record> into the output CDR stream. + cdr << ACE_CDR::Long (log_record.type ()); + cdr << ACE_CDR::Long (log_record.pid ()); + cdr << ACE_CDR::Long (log_record.time_stamp ().sec ()); + cdr << ACE_CDR::Long (log_record.time_stamp ().usec ()); + cdr << ACE_CDR::ULong (msglen); +#if defined (ACE_USES_WCHAR) + cdr.write_wchar_array (nonconst_record.msg_data (), msglen); +#else + cdr.write_char_array (nonconst_record.msg_data (), msglen); +#endif /* ACE_USES_WCHAR */ + return cdr.good_bit (); +} + +int +operator>> (ACE_InputCDR &cdr, + ACE_Log_Record &log_record) +{ + ACE_CDR::Long type; + ACE_CDR::Long pid; + ACE_CDR::Long sec, usec; + ACE_CDR::ULong buffer_len; + + // Extract each field from input CDR stream into <log_record>. + if ((cdr >> type) && (cdr >> pid) && (cdr >> sec) && (cdr >> usec) + && (cdr >> buffer_len)) { + ACE_TCHAR *log_msg = new ACE_TCHAR[buffer_len + 1]; + log_record.type (type); + log_record.pid (pid); + log_record.time_stamp (ACE_Time_Value (sec, usec)); +#if defined (ACE_USES_WCHAR) + cdr.read_wchar_array (log_msg, buffer_len); +#else + cdr.read_char_array (log_msg, buffer_len); +#endif /* ACE_USES_WCHAR */ + log_msg[buffer_len] = '\0'; + log_record.set_msg_data_ptr (log_msg); + } + return cdr.good_bit (); +} + +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + +int +ACE_Log_Record::print (const ACE_TCHAR host_name[], + u_long verbose_flag, + ACE_OSTREAM_TYPE &s) +{ + if (ACE_LOG_MSG->log_priority_enabled (ACE_Log_Priority (this->type_))) + { + ACE_TCHAR* verbose_msg = 0; + ACE_NEW_RETURN (verbose_msg, ACE_TCHAR[MAXVERBOSELOGMSGLEN], -1); + + int const result = this->format_msg (host_name, verbose_flag, verbose_msg); + + if (result == 0) + { + // Since ostream expects only chars, we cannot pass wchar_t's + s << ACE_TEXT_ALWAYS_CHAR (verbose_msg); + s.flush (); + } + + delete [] verbose_msg; + + return result; + } + return 0; +} + +#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ + +ACE_END_VERSIONED_NAMESPACE_DECL |