home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / system / source / log.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  4.5 KB  |  172 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <vd2/system/vdtypes.h>
  28. #include <list>
  29. #include <utility>
  30. #include <vd2/system/log.h>
  31. #include <vd2/system/thread.h>
  32. #include <vd2/system/VDString.h>
  33.  
  34. namespace {
  35.     wchar_t        g_log[16384];            // 32K log
  36.     int            g_logHead, g_logTail;
  37.     VDCriticalSection    g_csLog;
  38.  
  39.     typedef std::list<std::pair<IVDLogger *, VDThreadID> > tVDLoggers;
  40.     tVDLoggers g_loggers;
  41. }
  42.  
  43. void VDLog(int severity, const VDStringW& s) {
  44.     int strSize = s.size() + 1;
  45.  
  46.     if (strSize >= 16384) {
  47.         VDASSERT(false);
  48.         return;
  49.     }
  50.  
  51.     vdsynchronized(g_csLog) {
  52.         for(;;) {
  53.             int currentSize = (g_logTail - g_logHead) & 16383;
  54.  
  55.             if (currentSize + strSize < 16384)    // NOTE: This means that the last byte in the ring buffer can never be used.
  56.                 break;
  57.  
  58.             while(g_log[g_logHead++ & 16383])
  59.                 ;
  60.  
  61.             g_logHead &= 16383;
  62.         }
  63.  
  64.         const wchar_t *ps = s.data();
  65.  
  66.         g_log[g_logTail++] = severity;
  67.  
  68.         for(int i=1; i<strSize; ++i)
  69.             g_log[g_logTail++ & 16383] = *ps++;
  70.  
  71.         g_log[g_logTail++ & 16383] = 0;
  72.  
  73.         g_logTail &= 16383;
  74.  
  75.         VDThreadID currentThread = VDGetCurrentThreadID();
  76.         for(tVDLoggers::const_iterator it(g_loggers.begin()), itEnd(g_loggers.end()); it!=itEnd; ++it) {
  77.             if (!(*it).second || currentThread == (*it).second)
  78.                 (*it).first->AddLogEntry(severity, s);
  79.         }
  80.     }
  81. }
  82.  
  83. void VDLogF(int severity, const wchar_t *format, ...) {
  84.     va_list val;
  85.     va_start(val, format);
  86.     VDStringW s;
  87.     s.append_vsprintf(format, val);
  88.     va_end(val);
  89.  
  90.     VDLog(severity, s);
  91. }
  92.  
  93. void VDAttachLogger(IVDLogger *pLogger, bool bThisThreadOnly, bool bReplayLog) {
  94.     vdsynchronized(g_csLog) {
  95.         g_loggers.push_back(tVDLoggers::value_type(pLogger, bThisThreadOnly ? VDGetCurrentThreadID() : 0));
  96.  
  97.         if (bReplayLog) {
  98.             int idx = g_logHead;
  99.  
  100.             while(idx != g_logTail) {
  101.                 int severity = g_log[idx++];
  102.                 int headidx = idx;
  103.  
  104.                 idx &= 16383;
  105.  
  106.                 for(;;) {
  107.                     wchar_t c = g_log[idx];
  108.  
  109.                     idx = (idx+1) & 16383;
  110.  
  111.                     if (!c)
  112.                         break;
  113.                 }
  114.  
  115.                 if (idx > headidx) {
  116.                     pLogger->AddLogEntry(severity, VDStringW(g_log + headidx, idx-headidx-1));
  117.                 } else {
  118.                     VDStringW t(idx+16383-headidx);
  119.  
  120.                     std::copy(g_log + headidx, g_log + 16384, const_cast<wchar_t *>(t.data()));
  121.                     std::copy(g_log, g_log + idx - 1, const_cast<wchar_t *>(t.data() + (16384 - headidx)));
  122.                     pLogger->AddLogEntry(severity, t);
  123.                 }
  124.             }
  125.         }
  126.     }
  127. }
  128.  
  129. void VDDetachLogger(IVDLogger *pLogger) {
  130.     vdsynchronized(g_csLog) {
  131.         for(tVDLoggers::iterator it(g_loggers.begin()), itEnd(g_loggers.end()); it!=itEnd; ++it) {
  132.             if (pLogger == (*it).first) {
  133.                 g_loggers.erase(it);
  134.                 break;
  135.             }
  136.         }
  137.     }
  138. }
  139.  
  140. ///////////////////////////////////////////////////////////////////////////
  141. //
  142. //    autologger
  143. //
  144. ///////////////////////////////////////////////////////////////////////////
  145.  
  146. VDAutoLogger::VDAutoLogger(int min_severity)
  147.     : mbAttached(true)
  148.     , mMinSeverity(min_severity)
  149. {
  150.     VDAttachLogger(this, false, false);
  151. }
  152.  
  153. VDAutoLogger::~VDAutoLogger() {
  154.     if (mbAttached)
  155.         VDDetachLogger(this);
  156. }
  157.  
  158. void VDAutoLogger::AddLogEntry(int severity, const VDStringW& s) {
  159.     if (severity >= mMinSeverity)
  160.         mEntries.push_back(Entry(severity, s));
  161. }
  162.  
  163. const VDAutoLogger::tEntries& VDAutoLogger::GetEntries() {
  164.     if (mbAttached) {
  165.         VDDetachLogger(this);
  166.         mbAttached = false;
  167.     }
  168.  
  169.     return mEntries;
  170. }
  171.  
  172.