github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/database/leveldb.chai2010/src/port/win_logger.cc (about)

     1  // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file. See the AUTHORS file for names of contributors.
     4  
     5  #include "port/win_logger.h"
     6  
     7  #include <stdio.h> 
     8  #include <windows.h>
     9  
    10  namespace leveldb {
    11  
    12  void WinLogger::Logv(const char* format, va_list ap) {
    13    const uint64_t thread_id = static_cast<uint64_t>(::GetCurrentThreadId());
    14  
    15    // We try twice: the first time with a fixed-size stack allocated buffer,
    16    // and the second time with a much larger dynamically allocated buffer.
    17    char buffer[500];
    18  
    19    for (int iter = 0; iter < 2; iter++) {
    20      char* base;
    21      int bufsize;
    22      if (iter == 0) {
    23        bufsize = sizeof(buffer);
    24        base = buffer;
    25      } else {
    26        bufsize = 30000;
    27        base = new char[bufsize];
    28      }
    29  
    30      char* p = base;
    31      char* limit = base + bufsize;
    32  
    33      SYSTEMTIME st;
    34  
    35      // GetSystemTime returns UTC time, we want local time!
    36      ::GetLocalTime(&st);
    37  
    38  #ifdef _MSC_VER
    39      p += _snprintf_s(p, limit - p, _TRUNCATE,
    40        "%04d/%02d/%02d-%02d:%02d:%02d.%03d %llx ",
    41        st.wYear,
    42        st.wMonth,
    43        st.wDay,
    44        st.wHour,
    45        st.wMinute,
    46        st.wSecond,
    47        st.wMilliseconds,
    48        static_cast<uint64_t>(thread_id));
    49  #else
    50      p += _snprintf(p, limit - p,
    51        "%04d/%02d/%02d-%02d:%02d:%02d.%03d %llx ",
    52        st.wYear,
    53        st.wMonth,
    54        st.wDay,
    55        st.wHour,
    56        st.wMinute,
    57        st.wSecond,
    58        st.wMilliseconds,
    59        static_cast<uint64_t>(thread_id));
    60  #endif
    61  
    62      // Print the message
    63      if (p < limit) {
    64        va_list backup_ap = ap;
    65        p += vsnprintf(p, limit - p, format, backup_ap);
    66        va_end(backup_ap);
    67      }
    68  
    69      // Truncate to available space if necessary
    70      if (p >= limit) {
    71        if (iter == 0) {
    72          continue; // Try again with larger buffer
    73        } else {
    74          p = limit - 1;
    75        }
    76      }
    77  
    78      // Add newline if necessary
    79      if (p == base || p[-1] != '\n') {
    80        *p++ = '\n';
    81      }
    82  
    83      assert(p <= limit);
    84      fwrite(base, 1, p - base, file_);
    85      fflush(file_);
    86      if (base != buffer) {
    87        delete[] base;
    88      }
    89      break;
    90    }
    91  }
    92  
    93  }