Index: runtime/vm/log.cc |
diff --git a/runtime/vm/log.cc b/runtime/vm/log.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d24f9c5095b81fcf23e1984d8ba0cff02d1dbf34 |
--- /dev/null |
+++ b/runtime/vm/log.cc |
@@ -0,0 +1,118 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#include "vm/log.h" |
+ |
+#include "vm/flags.h" |
+ |
+namespace dart { |
+ |
+DEFINE_FLAG(bool, force_log_flush, false, "Always flush log messages."); |
+ |
+Log::Log(LogPrinter printer) |
+ : printer_(printer), |
+ manual_flush_(0), |
+ buffer_(0) { |
+} |
+ |
+ |
+Log::~Log() { |
+} |
+ |
+ |
+void Log::Print(const char* format, ...) { |
+ if (this == NoOpLog()) { |
+ return; |
+ } |
+ // Measure. |
+ va_list args; |
+ va_start(args, format); |
+ intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
+ va_end(args); |
+ |
+ // Print string to buffer. |
+ char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
+ va_list args2; |
+ va_start(args2, format); |
+ OS::VSNPrint(buffer, (len + 1), format, args2); |
+ va_end(args2); |
+ |
+ // Append. |
+ Append(buffer); |
+ free(buffer); |
+} |
+ |
+ |
+void Log::Append(const char* str) { |
+ if (this == NoOpLog()) { |
+ return; |
+ } |
+ ASSERT(str != NULL); |
+ intptr_t len = strlen(str); |
+ // Does not append the '\0' character. |
+ for (intptr_t i = 0; i < len; i++) { |
+ buffer_.Add(str[i]); |
+ } |
+ if ((manual_flush_ == 0) || FLAG_force_log_flush) { |
+ Flush(); |
+ } |
+} |
+ |
+ |
+void Log::Flush(const intptr_t cursor) { |
+ if (this == NoOpLog()) { |
+ return; |
+ } |
+ if (buffer_.is_empty()) { |
+ return; |
+ } |
+ if (buffer_.length() <= cursor) { |
+ return; |
+ } |
+ TerminateString(); |
+ const char* str = &buffer_[cursor]; |
+ ASSERT(str != NULL); |
+ printer_(str); |
+ buffer_.TruncateTo(cursor); |
+} |
+ |
+ |
+void Log::Clear() { |
+ if (this == NoOpLog()) { |
+ return; |
+ } |
+ buffer_.TruncateTo(0); |
+} |
+ |
+ |
+intptr_t Log::cursor() const { |
+ return buffer_.length(); |
+} |
+ |
+ |
+Log Log::noop_log_; |
+Log* Log::NoOpLog() { |
+ return &noop_log_; |
+} |
+ |
+ |
+void Log::TerminateString() { |
+ buffer_.Add('\0'); |
+} |
+ |
+ |
+void Log::EnableManualFlush() { |
+ manual_flush_++; |
+} |
+ |
+ |
+void Log::DisableManualFlush() { |
+ manual_flush_--; |
+ ASSERT(manual_flush_ >= 0); |
+ if (manual_flush_ == 0) { |
+ Flush(); |
+ } |
+} |
+ |
+} // namespace dart |