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