LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf/stubs - common.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 30 138 21.7 %
Date: 2017-07-14 16:53:18 Functions: 9 37 24.3 %
Legend: Lines: hit not hit

          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 <stdio.h>
      36             : #include <errno.h>
      37             : #include <vector>
      38             : 
      39             : 
      40             : #ifdef _WIN32
      41             : #define WIN32_LEAN_AND_MEAN  // We only need minimal includes
      42             : #include <windows.h>
      43             : #define snprintf _snprintf    // see comment in strutil.cc
      44             : #elif defined(HAVE_PTHREAD_H)
      45             : #include <pthread.h>
      46             : #else
      47             : #error "No suitable threading library available."
      48             : #endif
      49             : 
      50             : namespace google {
      51             : namespace protobuf {
      52             : 
      53             : namespace internal {
      54             : 
      55          12 : void VerifyVersion(int headerVersion,
      56             :                    int minLibraryVersion,
      57             :                    const char* filename) {
      58          12 :   if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
      59             :     // Library is too old for headers.
      60           0 :     GOOGLE_LOG(FATAL)
      61           0 :       << "This program requires version " << VersionString(minLibraryVersion)
      62             :       << " of the Protocol Buffer runtime library, but the installed version "
      63           0 :          "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ".  Please update "
      64             :          "your library.  If you compiled the program yourself, make sure that "
      65             :          "your headers are from the same version of Protocol Buffers as your "
      66           0 :          "link-time library.  (Version verification failed in \""
      67           0 :       << filename << "\".)";
      68             :   }
      69          12 :   if (headerVersion < kMinHeaderVersionForLibrary) {
      70             :     // Headers are too old for library.
      71           0 :     GOOGLE_LOG(FATAL)
      72           0 :       << "This program was compiled against version "
      73           0 :       << VersionString(headerVersion) << " of the Protocol Buffer runtime "
      74           0 :          "library, which is not compatible with the installed version ("
      75           0 :       << VersionString(GOOGLE_PROTOBUF_VERSION) <<  ").  Contact the program "
      76             :          "author for an update.  If you compiled the program yourself, make "
      77             :          "sure that your headers are from the same version of Protocol Buffers "
      78           0 :          "as your link-time library.  (Version verification failed in \""
      79           0 :       << filename << "\".)";
      80             :   }
      81          12 : }
      82             : 
      83           0 : string VersionString(int version) {
      84           0 :   int major = version / 1000000;
      85           0 :   int minor = (version / 1000) % 1000;
      86           0 :   int micro = version % 1000;
      87             : 
      88             :   // 128 bytes should always be enough, but we use snprintf() anyway to be
      89             :   // safe.
      90             :   char buffer[128];
      91           0 :   snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
      92             : 
      93             :   // Guard against broken MSVC snprintf().
      94           0 :   buffer[sizeof(buffer)-1] = '\0';
      95             : 
      96           0 :   return buffer;
      97             : }
      98             : 
      99             : }  // namespace internal
     100             : 
     101             : // ===================================================================
     102             : // emulates google3/base/logging.cc
     103             : 
     104             : namespace internal {
     105             : 
     106           0 : void DefaultLogHandler(LogLevel level, const char* filename, int line,
     107             :                        const string& message) {
     108             :   static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
     109             : 
     110             :   // We use fprintf() instead of cerr because we want this to work at static
     111             :   // initialization time.
     112           0 :   fprintf(stderr, "[libprotobuf %s %s:%d] %s\n",
     113           0 :           level_names[level], filename, line, message.c_str());
     114           0 :   fflush(stderr);  // Needed on MSVC.
     115           0 : }
     116             : 
     117           0 : void NullLogHandler(LogLevel /* level */, const char* /* filename */,
     118             :                     int /* line */, const string& /* message */) {
     119             :   // Nothing.
     120           0 : }
     121             : 
     122             : static LogHandler* log_handler_ = &DefaultLogHandler;
     123             : static int log_silencer_count_ = 0;
     124             : 
     125             : static Mutex* log_silencer_count_mutex_ = NULL;
     126             : GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
     127             : 
     128           0 : void DeleteLogSilencerCount() {
     129           0 :   delete log_silencer_count_mutex_;
     130           0 :   log_silencer_count_mutex_ = NULL;
     131           0 : }
     132           0 : void InitLogSilencerCount() {
     133           0 :   log_silencer_count_mutex_ = new Mutex;
     134           0 :   OnShutdown(&DeleteLogSilencerCount);
     135           0 : }
     136           0 : void InitLogSilencerCountOnce() {
     137           0 :   GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
     138           0 : }
     139             : 
     140           0 : LogMessage& LogMessage::operator<<(const string& value) {
     141           0 :   message_ += value;
     142           0 :   return *this;
     143             : }
     144             : 
     145           0 : LogMessage& LogMessage::operator<<(const char* value) {
     146           0 :   message_ += value;
     147           0 :   return *this;
     148             : }
     149             : 
     150             : // Since this is just for logging, we don't care if the current locale changes
     151             : // the results -- in fact, we probably prefer that.  So we use snprintf()
     152             : // instead of Simple*toa().
     153             : #undef DECLARE_STREAM_OPERATOR
     154             : #define DECLARE_STREAM_OPERATOR(TYPE, FORMAT)                       \
     155             :   LogMessage& LogMessage::operator<<(TYPE value) {                  \
     156             :     /* 128 bytes should be big enough for any of the primitive */   \
     157             :     /* values which we print with this, but well use snprintf() */  \
     158             :     /* anyway to be extra safe. */                                  \
     159             :     char buffer[128];                                               \
     160             :     snprintf(buffer, sizeof(buffer), FORMAT, value);                \
     161             :     /* Guard against broken MSVC snprintf(). */                     \
     162             :     buffer[sizeof(buffer)-1] = '\0';                                \
     163             :     message_ += buffer;                                             \
     164             :     return *this;                                                   \
     165             :   }
     166             : 
     167           0 : DECLARE_STREAM_OPERATOR(char         , "%c" )
     168           0 : DECLARE_STREAM_OPERATOR(int          , "%d" )
     169           0 : DECLARE_STREAM_OPERATOR(uint         , "%u" )
     170           0 : DECLARE_STREAM_OPERATOR(long         , "%ld")
     171           0 : DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
     172           0 : DECLARE_STREAM_OPERATOR(double       , "%g" )
     173             : #undef DECLARE_STREAM_OPERATOR
     174             : 
     175           0 : LogMessage::LogMessage(LogLevel level, const char* filename, int line)
     176           0 :   : level_(level), filename_(filename), line_(line) {}
     177           0 : LogMessage::~LogMessage() {}
     178             : 
     179           0 : void LogMessage::Finish() {
     180           0 :   bool suppress = false;
     181             : 
     182           0 :   if (level_ != LOGLEVEL_FATAL) {
     183           0 :     InitLogSilencerCountOnce();
     184           0 :     MutexLock lock(log_silencer_count_mutex_);
     185           0 :     suppress = log_silencer_count_ > 0;
     186             :   }
     187             : 
     188           0 :   if (!suppress) {
     189           0 :     log_handler_(level_, filename_, line_, message_);
     190             :   }
     191             : 
     192           0 :   if (level_ == LOGLEVEL_FATAL) {
     193             : #if PROTOBUF_USE_EXCEPTIONS
     194             :     throw FatalException(filename_, line_, message_);
     195             : #else
     196           0 :     abort();
     197             : #endif
     198             :   }
     199           0 : }
     200             : 
     201           0 : void LogFinisher::operator=(LogMessage& other) {
     202           0 :   other.Finish();
     203           0 : }
     204             : 
     205             : }  // namespace internal
     206             : 
     207           0 : LogHandler* SetLogHandler(LogHandler* new_func) {
     208           0 :   LogHandler* old = internal::log_handler_;
     209           0 :   if (old == &internal::NullLogHandler) {
     210           0 :     old = NULL;
     211             :   }
     212           0 :   if (new_func == NULL) {
     213           0 :     internal::log_handler_ = &internal::NullLogHandler;
     214             :   } else {
     215           0 :     internal::log_handler_ = new_func;
     216             :   }
     217           0 :   return old;
     218             : }
     219             : 
     220           0 : LogSilencer::LogSilencer() {
     221           0 :   internal::InitLogSilencerCountOnce();
     222           0 :   MutexLock lock(internal::log_silencer_count_mutex_);
     223           0 :   ++internal::log_silencer_count_;
     224           0 : };
     225             : 
     226           0 : LogSilencer::~LogSilencer() {
     227           0 :   internal::InitLogSilencerCountOnce();
     228           0 :   MutexLock lock(internal::log_silencer_count_mutex_);
     229           0 :   --internal::log_silencer_count_;
     230           0 : };
     231             : 
     232             : // ===================================================================
     233             : // emulates google3/base/callback.cc
     234             : 
     235          12 : Closure::~Closure() {}
     236             : 
     237          12 : namespace internal { FunctionClosure0::~FunctionClosure0() {} }
     238             : 
     239           0 : void DoNothing() {}
     240             : 
     241             : // ===================================================================
     242             : // emulates google3/base/mutex.cc
     243             : 
     244             : #ifdef _WIN32
     245             : 
     246             : struct Mutex::Internal {
     247             :   CRITICAL_SECTION mutex;
     248             : #ifndef NDEBUG
     249             :   // Used only to implement AssertHeld().
     250             :   DWORD thread_id;
     251             : #endif
     252             : };
     253             : 
     254             : Mutex::Mutex()
     255             :   : mInternal(new Internal) {
     256             :   InitializeCriticalSection(&mInternal->mutex);
     257             : }
     258             : 
     259             : Mutex::~Mutex() {
     260             :   DeleteCriticalSection(&mInternal->mutex);
     261             :   delete mInternal;
     262             : }
     263             : 
     264             : void Mutex::Lock() {
     265             :   EnterCriticalSection(&mInternal->mutex);
     266             : #ifndef NDEBUG
     267             :   mInternal->thread_id = GetCurrentThreadId();
     268             : #endif
     269             : }
     270             : 
     271             : void Mutex::Unlock() {
     272             : #ifndef NDEBUG
     273             :   mInternal->thread_id = 0;
     274             : #endif
     275             :   LeaveCriticalSection(&mInternal->mutex);
     276             : }
     277             : 
     278             : void Mutex::AssertHeld() {
     279             : #ifndef NDEBUG
     280             :   GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
     281             : #endif
     282             : }
     283             : 
     284             : #elif defined(HAVE_PTHREAD)
     285             : 
     286             : struct Mutex::Internal {
     287             :   pthread_mutex_t mutex;
     288             : };
     289             : 
     290           9 : Mutex::Mutex()
     291           9 :   : mInternal(new Internal) {
     292           9 :   pthread_mutex_init(&mInternal->mutex, NULL);
     293           9 : }
     294             : 
     295           0 : Mutex::~Mutex() {
     296           0 :   pthread_mutex_destroy(&mInternal->mutex);
     297           0 :   delete mInternal;
     298           0 : }
     299             : 
     300          24 : void Mutex::Lock() {
     301          24 :   int result = pthread_mutex_lock(&mInternal->mutex);
     302          24 :   if (result != 0) {
     303           0 :     GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
     304             :   }
     305          24 : }
     306             : 
     307          24 : void Mutex::Unlock() {
     308          24 :   int result = pthread_mutex_unlock(&mInternal->mutex);
     309          24 :   if (result != 0) {
     310           0 :     GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
     311             :   }
     312          24 : }
     313             : 
     314           0 : void Mutex::AssertHeld() {
     315             :   // pthreads dosn't provide a way to check which thread holds the mutex.
     316             :   // TODO(kenton):  Maybe keep track of locking thread ID like with WIN32?
     317           0 : }
     318             : 
     319             : #endif
     320             : 
     321             : // ===================================================================
     322             : // emulates google3/util/endian/endian.h
     323             : //
     324             : // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
     325             : // google/protobuf/io/coded_stream.h and therefore can not be used here.
     326             : // Maybe move that macro definition here in the furture.
     327           0 : uint32 ghtonl(uint32 x) {
     328             :   union {
     329             :     uint32 result;
     330             :     uint8 result_array[4];
     331             :   };
     332           0 :   result_array[0] = static_cast<uint8>(x >> 24);
     333           0 :   result_array[1] = static_cast<uint8>((x >> 16) & 0xFF);
     334           0 :   result_array[2] = static_cast<uint8>((x >> 8) & 0xFF);
     335           0 :   result_array[3] = static_cast<uint8>(x & 0xFF);
     336           0 :   return result;
     337             : }
     338             : 
     339             : // ===================================================================
     340             : // Shutdown support.
     341             : 
     342             : namespace internal {
     343             : 
     344             : typedef void OnShutdownFunc();
     345             : vector<void (*)()>* shutdown_functions = NULL;
     346             : Mutex* shutdown_functions_mutex = NULL;
     347             : GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
     348             : 
     349           3 : void InitShutdownFunctions() {
     350           3 :   shutdown_functions = new vector<void (*)()>;
     351           3 :   shutdown_functions_mutex = new Mutex;
     352           3 : }
     353             : 
     354          24 : inline void InitShutdownFunctionsOnce() {
     355          24 :   GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
     356          24 : }
     357             : 
     358          24 : void OnShutdown(void (*func)()) {
     359          24 :   InitShutdownFunctionsOnce();
     360          48 :   MutexLock lock(shutdown_functions_mutex);
     361          24 :   shutdown_functions->push_back(func);
     362          24 : }
     363             : 
     364             : }  // namespace internal
     365             : 
     366           0 : void ShutdownProtobufLibrary() {
     367           0 :   internal::InitShutdownFunctionsOnce();
     368             : 
     369             :   // We don't need to lock shutdown_functions_mutex because it's up to the
     370             :   // caller to make sure that no one is using the library before this is
     371             :   // called.
     372             : 
     373             :   // Make it safe to call this multiple times.
     374           0 :   if (internal::shutdown_functions == NULL) return;
     375             : 
     376           0 :   for (int i = 0; i < internal::shutdown_functions->size(); i++) {
     377           0 :     internal::shutdown_functions->at(i)();
     378             :   }
     379           0 :   delete internal::shutdown_functions;
     380           0 :   internal::shutdown_functions = NULL;
     381           0 :   delete internal::shutdown_functions_mutex;
     382           0 :   internal::shutdown_functions_mutex = NULL;
     383             : }
     384             : 
     385             : #if PROTOBUF_USE_EXCEPTIONS
     386             : FatalException::~FatalException() throw() {}
     387             : 
     388             : const char* FatalException::what() const throw() {
     389             :   return message_.c_str();
     390             : }
     391             : #endif
     392             : 
     393             : }  // namespace protobuf
     394             : }  // namespace google

Generated by: LCOV version 1.13