LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/stubs - common.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 33 149 22.1 %
Date: 2015-10-10 Functions: 10 45 22.2 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : 
      33             : #include <google/protobuf/stubs/common.h>
      34             : #include <google/protobuf/stubs/once.h>
      35             : #include <google/protobuf/stubs/status.h>
      36             : #include <google/protobuf/stubs/stringpiece.h>
      37             : #include <google/protobuf/stubs/strutil.h>
      38             : #include <google/protobuf/stubs/int128.h>
      39             : #include <errno.h>
      40             : #include <sstream>
      41             : #include <stdio.h>
      42             : #include <vector>
      43             : 
      44             : #ifdef _WIN32
      45             : #define WIN32_LEAN_AND_MEAN  // We only need minimal includes
      46             : #include <windows.h>
      47             : #define snprintf _snprintf    // see comment in strutil.cc
      48             : #elif defined(HAVE_PTHREAD)
      49             : #include <pthread.h>
      50             : #else
      51             : #error "No suitable threading library available."
      52             : #endif
      53             : #if defined(__ANDROID__)
      54             : #include <android/log.h>
      55             : #endif
      56             : 
      57             : namespace google {
      58             : namespace protobuf {
      59             : 
      60             : namespace internal {
      61             : 
      62         103 : void VerifyVersion(int headerVersion,
      63             :                    int minLibraryVersion,
      64             :                    const char* filename) {
      65         103 :   if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
      66             :     // Library is too old for headers.
      67           0 :     GOOGLE_LOG(FATAL)
      68           0 :       << "This program requires version " << VersionString(minLibraryVersion)
      69             :       << " of the Protocol Buffer runtime library, but the installed version "
      70           0 :          "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ".  Please update "
      71             :          "your library.  If you compiled the program yourself, make sure that "
      72             :          "your headers are from the same version of Protocol Buffers as your "
      73           0 :          "link-time library.  (Version verification failed in \""
      74           0 :       << filename << "\".)";
      75             :   }
      76         103 :   if (headerVersion < kMinHeaderVersionForLibrary) {
      77             :     // Headers are too old for library.
      78           0 :     GOOGLE_LOG(FATAL)
      79           0 :       << "This program was compiled against version "
      80           0 :       << VersionString(headerVersion) << " of the Protocol Buffer runtime "
      81           0 :          "library, which is not compatible with the installed version ("
      82           0 :       << VersionString(GOOGLE_PROTOBUF_VERSION) <<  ").  Contact the program "
      83             :          "author for an update.  If you compiled the program yourself, make "
      84             :          "sure that your headers are from the same version of Protocol Buffers "
      85           0 :          "as your link-time library.  (Version verification failed in \""
      86           0 :       << filename << "\".)";
      87             :   }
      88         103 : }
      89             : 
      90           0 : string VersionString(int version) {
      91           0 :   int major = version / 1000000;
      92           0 :   int minor = (version / 1000) % 1000;
      93           0 :   int micro = version % 1000;
      94             : 
      95             :   // 128 bytes should always be enough, but we use snprintf() anyway to be
      96             :   // safe.
      97             :   char buffer[128];
      98             :   snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
      99             : 
     100             :   // Guard against broken MSVC snprintf().
     101           0 :   buffer[sizeof(buffer)-1] = '\0';
     102             : 
     103           0 :   return buffer;
     104             : }
     105             : 
     106             : }  // namespace internal
     107             : 
     108             : // ===================================================================
     109             : // emulates google3/base/logging.cc
     110             : 
     111             : namespace internal {
     112             : #if defined(__ANDROID__)
     113             : inline void DefaultLogHandler(LogLevel level, const char* filename, int line,
     114             :                               const string& message) {
     115             : #ifdef GOOGLE_PROTOBUF_MIN_LOG_LEVEL
     116             :   if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) {
     117             :     return;
     118             :   }
     119             :   static const char* level_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
     120             : 
     121             :   static const int android_log_levels[] = {
     122             :       ANDROID_LOG_INFO,   // LOG(INFO),
     123             :       ANDROID_LOG_WARN,   // LOG(WARNING)
     124             :       ANDROID_LOG_ERROR,  // LOG(ERROR)
     125             :       ANDROID_LOG_FATAL,  // LOG(FATAL)
     126             :   };
     127             : 
     128             :   // Bound the logging level.
     129             :   const int android_log_level = android_log_levels[level];
     130             :   ::std::ostringstream ostr;
     131             :   ostr << "[libprotobuf " << level_names[level] << " " << filename << ":"
     132             :        << line << "] " << message.c_str();
     133             : 
     134             :   // Output the log string the Android log at the appropriate level.
     135             :   __android_log_write(android_log_level, "libprotobuf-native",
     136             :                       ostr.str().c_str());
     137             :   // Also output to std::cerr.
     138             :   fprintf(stderr, "%s", ostr.str().c_str());
     139             :   fflush(stderr);
     140             : 
     141             :   // Indicate termination if needed.
     142             :   if (android_log_level == ANDROID_LOG_FATAL) {
     143             :     __android_log_write(ANDROID_LOG_FATAL, "libprotobuf-native",
     144             :                         "terminating.\n");
     145             :   }
     146             : #endif
     147             : }
     148             : #else
     149           0 : void DefaultLogHandler(LogLevel level, const char* filename, int line,
     150             :                        const string& message) {
     151             :   static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
     152             : 
     153             :   // We use fprintf() instead of cerr because we want this to work at static
     154             :   // initialization time.
     155             :   fprintf(stderr, "[libprotobuf %s %s:%d] %s\n",
     156           0 :           level_names[level], filename, line, message.c_str());
     157           0 :   fflush(stderr);  // Needed on MSVC.
     158           0 : }
     159             : #endif
     160             : 
     161           0 : void NullLogHandler(LogLevel /* level */, const char* /* filename */,
     162             :                     int /* line */, const string& /* message */) {
     163             :   // Nothing.
     164           0 : }
     165             : 
     166             : static LogHandler* log_handler_ = &DefaultLogHandler;
     167             : static int log_silencer_count_ = 0;
     168             : 
     169             : static Mutex* log_silencer_count_mutex_ = NULL;
     170             : GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
     171             : 
     172           0 : void DeleteLogSilencerCount() {
     173           0 :   delete log_silencer_count_mutex_;
     174           0 :   log_silencer_count_mutex_ = NULL;
     175           0 : }
     176           0 : void InitLogSilencerCount() {
     177           0 :   log_silencer_count_mutex_ = new Mutex;
     178           0 :   OnShutdown(&DeleteLogSilencerCount);
     179           0 : }
     180           0 : void InitLogSilencerCountOnce() {
     181           0 :   GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
     182           0 : }
     183             : 
     184           0 : LogMessage& LogMessage::operator<<(const string& value) {
     185           0 :   message_ += value;
     186           0 :   return *this;
     187             : }
     188             : 
     189           0 : LogMessage& LogMessage::operator<<(const char* value) {
     190           0 :   message_ += value;
     191           0 :   return *this;
     192             : }
     193             : 
     194           0 : LogMessage& LogMessage::operator<<(const StringPiece& value) {
     195           0 :   message_ += value.ToString();
     196           0 :   return *this;
     197             : }
     198             : 
     199           0 : LogMessage& LogMessage::operator<<(
     200             :     const ::google::protobuf::util::Status& status) {
     201           0 :   message_ += status.ToString();
     202           0 :   return *this;
     203             : }
     204             : 
     205           0 : LogMessage& LogMessage::operator<<(const uint128& value) {
     206           0 :   std::ostringstream str;
     207           0 :   str << value;
     208           0 :   message_ += str.str();
     209           0 :   return *this;
     210             : }
     211             : 
     212             : // Since this is just for logging, we don't care if the current locale changes
     213             : // the results -- in fact, we probably prefer that.  So we use snprintf()
     214             : // instead of Simple*toa().
     215             : #undef DECLARE_STREAM_OPERATOR
     216             : #define DECLARE_STREAM_OPERATOR(TYPE, FORMAT)                       \
     217             :   LogMessage& LogMessage::operator<<(TYPE value) {                  \
     218             :     /* 128 bytes should be big enough for any of the primitive */   \
     219             :     /* values which we print with this, but well use snprintf() */  \
     220             :     /* anyway to be extra safe. */                                  \
     221             :     char buffer[128];                                               \
     222             :     snprintf(buffer, sizeof(buffer), FORMAT, value);                \
     223             :     /* Guard against broken MSVC snprintf(). */                     \
     224             :     buffer[sizeof(buffer)-1] = '\0';                                \
     225             :     message_ += buffer;                                             \
     226             :     return *this;                                                   \
     227             :   }
     228             : 
     229           0 : DECLARE_STREAM_OPERATOR(char         , "%c" )
     230           0 : DECLARE_STREAM_OPERATOR(int          , "%d" )
     231           0 : DECLARE_STREAM_OPERATOR(unsigned int , "%u" )
     232           0 : DECLARE_STREAM_OPERATOR(long         , "%ld")
     233           0 : DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
     234           0 : DECLARE_STREAM_OPERATOR(double       , "%g" )
     235           0 : DECLARE_STREAM_OPERATOR(void*        , "%p" )
     236           0 : DECLARE_STREAM_OPERATOR(long long         , "%" GOOGLE_LL_FORMAT "d")
     237           0 : DECLARE_STREAM_OPERATOR(unsigned long long, "%" GOOGLE_LL_FORMAT "u")
     238             : #undef DECLARE_STREAM_OPERATOR
     239             : 
     240           0 : LogMessage::LogMessage(LogLevel level, const char* filename, int line)
     241           0 :   : level_(level), filename_(filename), line_(line) {}
     242           0 : LogMessage::~LogMessage() {}
     243             : 
     244           0 : void LogMessage::Finish() {
     245           0 :   bool suppress = false;
     246             : 
     247           0 :   if (level_ != LOGLEVEL_FATAL) {
     248           0 :     InitLogSilencerCountOnce();
     249           0 :     MutexLock lock(log_silencer_count_mutex_);
     250           0 :     suppress = log_silencer_count_ > 0;
     251             :   }
     252             : 
     253           0 :   if (!suppress) {
     254           0 :     log_handler_(level_, filename_, line_, message_);
     255             :   }
     256             : 
     257           0 :   if (level_ == LOGLEVEL_FATAL) {
     258             : #if PROTOBUF_USE_EXCEPTIONS
     259           0 :     throw FatalException(filename_, line_, message_);
     260             : #else
     261             :     abort();
     262             : #endif
     263             :   }
     264           0 : }
     265             : 
     266           0 : void LogFinisher::operator=(LogMessage& other) {
     267           0 :   other.Finish();
     268           0 : }
     269             : 
     270             : }  // namespace internal
     271             : 
     272           0 : LogHandler* SetLogHandler(LogHandler* new_func) {
     273           0 :   LogHandler* old = internal::log_handler_;
     274           0 :   if (old == &internal::NullLogHandler) {
     275           0 :     old = NULL;
     276             :   }
     277           0 :   if (new_func == NULL) {
     278           0 :     internal::log_handler_ = &internal::NullLogHandler;
     279             :   } else {
     280           0 :     internal::log_handler_ = new_func;
     281             :   }
     282           0 :   return old;
     283             : }
     284             : 
     285           0 : LogSilencer::LogSilencer() {
     286           0 :   internal::InitLogSilencerCountOnce();
     287           0 :   MutexLock lock(internal::log_silencer_count_mutex_);
     288           0 :   ++internal::log_silencer_count_;
     289           0 : };
     290             : 
     291           0 : LogSilencer::~LogSilencer() {
     292           0 :   internal::InitLogSilencerCountOnce();
     293           0 :   MutexLock lock(internal::log_silencer_count_mutex_);
     294           0 :   --internal::log_silencer_count_;
     295           0 : };
     296             : 
     297             : // ===================================================================
     298             : // emulates google3/base/callback.cc
     299             : 
     300         190 : Closure::~Closure() {}
     301             : 
     302         190 : namespace internal { FunctionClosure0::~FunctionClosure0() {} }
     303             : 
     304           0 : void DoNothing() {}
     305             : 
     306             : // ===================================================================
     307             : // emulates google3/base/mutex.cc
     308             : 
     309             : #ifdef _WIN32
     310             : 
     311             : struct Mutex::Internal {
     312             :   CRITICAL_SECTION mutex;
     313             : #ifndef NDEBUG
     314             :   // Used only to implement AssertHeld().
     315             :   DWORD thread_id;
     316             : #endif
     317             : };
     318             : 
     319             : Mutex::Mutex()
     320             :   : mInternal(new Internal) {
     321             :   InitializeCriticalSection(&mInternal->mutex);
     322             : }
     323             : 
     324             : Mutex::~Mutex() {
     325             :   DeleteCriticalSection(&mInternal->mutex);
     326             :   delete mInternal;
     327             : }
     328             : 
     329             : void Mutex::Lock() {
     330             :   EnterCriticalSection(&mInternal->mutex);
     331             : #ifndef NDEBUG
     332             :   mInternal->thread_id = GetCurrentThreadId();
     333             : #endif
     334             : }
     335             : 
     336             : void Mutex::Unlock() {
     337             : #ifndef NDEBUG
     338             :   mInternal->thread_id = 0;
     339             : #endif
     340             :   LeaveCriticalSection(&mInternal->mutex);
     341             : }
     342             : 
     343             : void Mutex::AssertHeld() {
     344             : #ifndef NDEBUG
     345             :   GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
     346             : #endif
     347             : }
     348             : 
     349             : #elif defined(HAVE_PTHREAD)
     350             : 
     351             : struct Mutex::Internal {
     352             :   pthread_mutex_t mutex;
     353             : };
     354             : 
     355         410 : Mutex::Mutex()
     356         410 :   : mInternal(new Internal) {
     357         410 :   pthread_mutex_init(&mInternal->mutex, NULL);
     358         410 : }
     359             : 
     360         267 : Mutex::~Mutex() {
     361         267 :   pthread_mutex_destroy(&mInternal->mutex);
     362         267 :   delete mInternal;
     363         267 : }
     364             : 
     365         682 : void Mutex::Lock() {
     366         682 :   int result = pthread_mutex_lock(&mInternal->mutex);
     367         682 :   if (result != 0) {
     368           0 :     GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
     369             :   }
     370         682 : }
     371             : 
     372         682 : void Mutex::Unlock() {
     373         682 :   int result = pthread_mutex_unlock(&mInternal->mutex);
     374         682 :   if (result != 0) {
     375           0 :     GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
     376             :   }
     377         682 : }
     378             : 
     379         107 : void Mutex::AssertHeld() {
     380             :   // pthreads dosn't provide a way to check which thread holds the mutex.
     381             :   // TODO(kenton):  Maybe keep track of locking thread ID like with WIN32?
     382         107 : }
     383             : 
     384             : #endif
     385             : 
     386             : // ===================================================================
     387             : // emulates google3/util/endian/endian.h
     388             : //
     389             : // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
     390             : // google/protobuf/io/coded_stream.h and therefore can not be used here.
     391             : // Maybe move that macro definition here in the furture.
     392           0 : uint32 ghtonl(uint32 x) {
     393             :   union {
     394             :     uint32 result;
     395             :     uint8 result_array[4];
     396             :   };
     397           0 :   result_array[0] = static_cast<uint8>(x >> 24);
     398           0 :   result_array[1] = static_cast<uint8>((x >> 16) & 0xFF);
     399           0 :   result_array[2] = static_cast<uint8>((x >> 8) & 0xFF);
     400           0 :   result_array[3] = static_cast<uint8>(x & 0xFF);
     401           0 :   return result;
     402             : }
     403             : 
     404             : // ===================================================================
     405             : // Shutdown support.
     406             : 
     407             : namespace internal {
     408             : 
     409             : typedef void OnShutdownFunc();
     410             : vector<void (*)()>* shutdown_functions = NULL;
     411             : Mutex* shutdown_functions_mutex = NULL;
     412             : GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
     413             : 
     414          46 : void InitShutdownFunctions() {
     415          92 :   shutdown_functions = new vector<void (*)()>;
     416          46 :   shutdown_functions_mutex = new Mutex;
     417          46 : }
     418             : 
     419             : inline void InitShutdownFunctionsOnce() {
     420         334 :   GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
     421             : }
     422             : 
     423         334 : void OnShutdown(void (*func)()) {
     424             :   InitShutdownFunctionsOnce();
     425         334 :   MutexLock lock(shutdown_functions_mutex);
     426         334 :   shutdown_functions->push_back(func);
     427         334 : }
     428             : 
     429             : }  // namespace internal
     430             : 
     431           0 : void ShutdownProtobufLibrary() {
     432             :   internal::InitShutdownFunctionsOnce();
     433             : 
     434             :   // We don't need to lock shutdown_functions_mutex because it's up to the
     435             :   // caller to make sure that no one is using the library before this is
     436             :   // called.
     437             : 
     438             :   // Make it safe to call this multiple times.
     439           0 :   if (internal::shutdown_functions == NULL) return;
     440             : 
     441           0 :   for (int i = 0; i < internal::shutdown_functions->size(); i++) {
     442           0 :     internal::shutdown_functions->at(i)();
     443             :   }
     444           0 :   delete internal::shutdown_functions;
     445           0 :   internal::shutdown_functions = NULL;
     446           0 :   delete internal::shutdown_functions_mutex;
     447           0 :   internal::shutdown_functions_mutex = NULL;
     448             : }
     449             : 
     450             : #if PROTOBUF_USE_EXCEPTIONS
     451           0 : FatalException::~FatalException() throw() {}
     452             : 
     453           0 : const char* FatalException::what() const throw() {
     454           0 :   return message_.c_str();
     455             : }
     456             : #endif
     457             : 
     458             : }  // namespace protobuf
     459             : }  // namespace google

Generated by: LCOV version 1.10