MemDump.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                            MemDump.cpp
00004 //------------------------------------------------------------------------------
00005 //  Copyright (C) 1997-2002  Vladislav Grinchenko 
00006 //
00007 //  This library is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU Library General Public
00009 //  License as published by the Free Software Foundation; either
00010 //  version 2 of the License, or (at your option) any later version.
00011 //
00012 // $Source: /cvsroot/libassa/libassa/assa/MemDump.cpp,v $
00013 // $Revision: 1.5 $
00014 // $Locker:  $
00015 // $Author: vlg $
00016 // $Date: 2005/10/08 02:42:00 $
00017 //------------------------------------------------------------------------------
00018 
00019 #include "assa/Logger.h"
00020 #include "assa/MemDump.h"
00021 
00022 using namespace ASSA;
00023 
00024 const char MemDump::m_empty_str[] = "Null";
00025 
00026 MemDump::
00027 MemDump(const char* msg_, int len_) : m_dump (NULL)
00028 {
00029     register int i;     // ptr into source buffer
00030     register int j;     // pair elements counter
00031     register int k;     // pairs counter [0;16[
00032     
00033     const char *p;      // ptr into source buffer
00034     char *hex;      // hex ptr into destination buffer
00035     char *ascii;        // ascii ptr into destination buffer
00036     
00037     long final_len;
00038 
00039     /*--- Precondition ---  */
00040     if (len_ <= 0 || msg_ == (char*) NULL) {
00041         DL((ERROR,"No data to process.\n"));
00042         DL((ERROR,"Data length requested: %d <= 0!\n", len_));
00043         return;
00044     }
00045     j = k = 1;
00046 
00047     /*---
00048       Each row holds 16 bytes of data. It requres 74 characters maximum.
00049       Here's some examples:
00050 
00051 0         1         2         3         4         5         6         7
00052 0123456789012345678901234567890123456789012345678901234567890123456789012
00053 -------------------------------------------------------------------------
00054 3132 3037 3039 3039 3031 3130 3839 3033  1207090901108903
00055 3038 3132 3030 3331 3030 0d0a 3839 3033  0812003100\r\n8903
00056 0d0a 0d0a 0d0a 0d0a 0d0a 0d0a 0d0a 0d0a  \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
00057 
00058           If all 16 bytes are control characters, the ASCII representation
00059       will extend line to 72 characters plus cartrige return and line 
00060       feed at the end of the line.
00061 
00062       If len_ is not multiple of 16, we add one more row and another row
00063       just to be on a safe side.
00064       ---*/
00065     
00066     final_len = (int (len_/16) + 1 + (len_ % 16 ? 1:0)) * 74;
00067     
00068     m_dump = new char[final_len];
00069     memset(m_dump, ' ', final_len);
00070     
00071     p = msg_;           // ptr to original image
00072     hex = m_dump;           // current ptr to hex image
00073     ascii = m_dump + 41;        // current ptr to ascii image
00074     
00075     for(i=0; i<len_; i++) {
00076         sprintf(hex,"%01x%01x", p[i] >> 4 & 0x0f, p[i] & 0x0f); 
00077         hex+=2;
00078 
00079         if (p[i] == '\n') { sprintf(ascii,"\\n"); ascii+=2; }
00080         else if (p[i] == '\t') { sprintf(ascii,"\\t"); ascii+=2; }
00081         else if (p[i] == '\v') { sprintf(ascii,"\\v"); ascii+=2; }
00082         else if (p[i] == '\b') { sprintf(ascii,"\\b"); ascii+=2; }
00083         else if (p[i] == '\r') { sprintf(ascii,"\\r"); ascii+=2; }
00084         else if (p[i] == '\f') { sprintf(ascii,"\\f"); ascii+=2; }
00085         else if (p[i] == '\a') { sprintf(ascii,"\\a"); ascii+=2; }
00086         else if (p[i] == '\0') { sprintf(ascii,"\\0"); ascii+=2; }
00087         else sprintf(ascii++,"%c",((p[i]<' ' || p[i]>'~')?'.':p[i]));
00088         
00089         if (!(j++ % 2)) 
00090             sprintf(hex++," ");
00091         k %= 16;
00092         if (!(k++)) {
00093             *hex = ' ';
00094             sprintf(ascii++,"\n");
00095             hex = ascii;
00096             ascii +=  41;
00097         }
00098     }
00099     *hex = ' ';
00100     m_dump[final_len-1] = '\0';
00101     
00102 }
00103 
00104 void
00105 MemDump::
00106 dump_to_log (unsigned long mask_, const char* info_, const char* msg_, int len_)
00107 {
00108     /* A very important shortcut (performance-wise)
00109      * It saves on constructing unnecessary MemDump object when
00110      * message logging for that particular group is disabled.
00111      */
00112 
00113     if (LOGGER->group_enabled (static_cast<Group> (mask_)) && len_ > 0) 
00114     {       
00115         MemDump temp (msg_, len_);
00116         DL((mask_, "(%d bytes) %s\n", len_, info_));
00117         DL((mask_, "\n\n%s\n\n", temp.getMemDump ()));
00118     }
00119 }
00120 

Generated on Mon Dec 19 16:20:18 2005 for libassa by  doxygen 1.4.5