bitcoinleveldb_log/
posix_logger.rs

1/*!
2  | Logger implementation that can be shared
3  | by all environments where enough posix
4  | functionality is available.
5  |
6  */
7
8crate::ix!();
9
10
11
12//-------------------------------------------[.cpp/bitcoin/src/leveldb/util/posix_logger.h]
13
14pub struct PosixLogger {
15    fp:   *const libc::FILE,
16}
17
18impl Logger for PosixLogger {
19
20}
21
22impl Logv for PosixLogger {
23
24    fn logv(&mut self, 
25        format:    *const u8,
26        arguments: &[&str])  {
27        
28        todo!();
29        /*
30            // Record the time as close to the Logv() call as possible.
31        struct ::timeval now_timeval;
32        ::gettimeofday(&now_timeval, nullptr);
33        const std::time_t now_seconds = now_timeval.tv_sec;
34        struct std::tm now_components;
35        ::localtime_r(&now_seconds, &now_components);
36
37        // Record the thread ID.
38        constexpr const int kMaxThreadIdSize = 32;
39        std::ostringstream thread_stream;
40        thread_stream << std::this_thread::get_id();
41        std::string thread_id = thread_stream.str();
42        if (thread_id.size() > kMaxThreadIdSize) {
43          thread_id.resize(kMaxThreadIdSize);
44        }
45
46        // We first attempt to print into a stack-allocated buffer. If this attempt
47        // fails, we make a second attempt with a dynamically allocated buffer.
48        constexpr const int kStackBufferSize = 512;
49        char stack_buffer[kStackBufferSize];
50        const_assert(sizeof(stack_buffer) == static_cast<size_t>(kStackBufferSize),
51                      "sizeof(char) is expected to be 1 in C++");
52
53        int dynamic_buffer_size = 0;  // Computed in the first iteration.
54        for (int iteration = 0; iteration < 2; ++iteration) {
55          const int buffer_size =
56              (iteration == 0) ? kStackBufferSize : dynamic_buffer_size;
57          char* const buffer =
58              (iteration == 0) ? stack_buffer : new char[dynamic_buffer_size];
59
60          // Print the header into the buffer.
61          int buffer_offset = snprintf(
62              buffer, buffer_size, "%04d/%02d/%02d-%02d:%02d:%02d.%06d %s ",
63              now_components.tm_year + 1900, now_components.tm_mon + 1,
64              now_components.tm_mday, now_components.tm_hour, now_components.tm_min,
65              now_components.tm_sec, static_cast<int>(now_timeval.tv_usec),
66              thread_id.c_str());
67
68          // The header can be at most 28 characters (10 date + 15 time +
69          // 3 delimiters) plus the thread ID, which should fit comfortably into the
70          // static buffer.
71          assert(buffer_offset <= 28 + kMaxThreadIdSize);
72          const_assert(28 + kMaxThreadIdSize < kStackBufferSize,
73                        "stack-allocated buffer may not fit the message header");
74          assert(buffer_offset < buffer_size);
75
76          // Print the message into the buffer.
77          std::va_list arguments_copy;
78          va_copy(arguments_copy, arguments);
79          buffer_offset +=
80              std::vsnprintf(buffer + buffer_offset, buffer_size - buffer_offset,
81                             format, arguments_copy);
82          va_end(arguments_copy);
83
84          // The code below may append a newline at the end of the buffer, which
85          // requires an extra character.
86          if (buffer_offset >= buffer_size - 1) {
87            // The message did not fit into the buffer.
88            if (iteration == 0) {
89              // Re-run the loop and use a dynamically-allocated buffer. The buffer
90              // will be large enough for the log message, an extra newline and a
91              // null terminator.
92              dynamic_buffer_size = buffer_offset + 2;
93              continue;
94            }
95
96            // The dynamically-allocated buffer was incorrectly sized. This should
97            // not happen, assuming a correct implementation of (v)snprintf. Fail
98            // in tests, recover by truncating the log message in production.
99            assert(false);
100            buffer_offset = buffer_size - 1;
101          }
102
103          // Add a newline if necessary.
104          if (buffer[buffer_offset - 1] != '\n') {
105            buffer[buffer_offset] = '\n';
106            ++buffer_offset;
107          }
108
109          assert(buffer_offset <= buffer_size);
110          std::fwrite(buffer, 1, buffer_offset, fp_);
111          std::fflush(fp_);
112
113          if (iteration != 0) {
114            delete[] buffer;
115          }
116          break;
117        }
118        */
119    }
120}
121
122impl Drop for PosixLogger {
123    fn drop(&mut self) {
124        todo!();
125        /*
126            std::fclose(fp_);
127        */
128    }
129}
130
131impl PosixLogger {
132
133    /**
134      | Creates a logger that writes to the given
135      | file.
136      |
137      | The PosixLogger instance takes ownership of
138      | the file handle.
139      */
140    pub fn new(fp: *mut libc::FILE) -> Self {
141    
142        todo!();
143        /*
144        : fp(fp),
145
146            assert(fp != nullptr);
147        */
148    }
149}