diff options
Diffstat (limited to 'src/google/protobuf/stubs')
-rw-r--r-- | src/google/protobuf/stubs/port.h | 55 | ||||
-rw-r--r-- | src/google/protobuf/stubs/strutil.cc | 15 | ||||
-rw-r--r-- | src/google/protobuf/stubs/strutil.h | 4 |
3 files changed, 73 insertions, 1 deletions
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index d7f93b4c..376be5f7 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -327,6 +327,61 @@ static inline uint64 bswap_64(uint64 x) { #endif // =================================================================== +// from google3/util/bits/bits.h + +class Bits { + public: + static uint32 Log2FloorNonZero(uint32 n) { +#if defined(__GNUC__) + return 31 ^ __builtin_clz(n); +#elif defined(COMPILER_MSVC) && defined(_M_IX86) + _asm { + bsr ebx, n + mov n, ebx + } + return n; +#else + return Log2FloorNonZero_Portable(n); +#endif + } + + static uint64 Log2FloorNonZero64(uint64 n) { +#if defined(__GNUC__) + return 63 ^ __builtin_clzll(n); +#else + return Log2FloorNonZero64_Portable(n); +#endif + } + private: + static int Log2FloorNonZero_Portable(uint32 n) { + if (n == 0) + return -1; + int log = 0; + uint32 value = n; + for (int i = 4; i >= 0; --i) { + int shift = (1 << i); + uint32 x = value >> shift; + if (x != 0) { + value = x; + log += shift; + } + } + assert(value == 1); + return log; + } + + static int Log2FloorNonZero64_Portable(uint64 n) { + const uint32 topbits = static_cast<uint32>(n >> 32); + if (topbits == 0) { + // Top bits are zero, so scan in bottom bits + return Log2FloorNonZero(static_cast<uint32>(n)); + } else { + return 32 + Log2FloorNonZero(topbits); + } + } +}; + +// =================================================================== // from google3/util/endian/endian.h LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x); diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 7ba92e8f..4fa8e99f 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -93,6 +93,21 @@ void StripString(string* s, const char* remove, char replacewith) { } } +// ---------------------------------------------------------------------- +// ReplaceCharacters +// Replaces any occurrence of the character 'remove' (or the characters +// in 'remove') with the character 'replacewith'. +// ---------------------------------------------------------------------- +void ReplaceCharacters(string *s, const char *remove, char replacewith) { + const char *str_start = s->c_str(); + const char *str = str_start; + for (str = strpbrk(str, remove); + str != NULL; + str = strpbrk(str + 1, remove)) { + (*s)[str - str_start] = replacewith; + } +} + void StripWhitespace(string* str) { int str_length = str->length(); diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index 8bdd6110..df28c94d 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -147,7 +147,7 @@ inline string StripSuffixString(const string& str, const string& suffix) { } // ---------------------------------------------------------------------- -// StripString +// ReplaceCharacters // Replaces any occurrence of the character 'remove' (or the characters // in 'remove') with the character 'replacewith'. // Good for keeping html characters or protocol characters (\t) out @@ -155,6 +155,8 @@ inline string StripSuffixString(const string& str, const string& suffix) { // StripWhitespace // Removes whitespaces from both ends of the given string. // ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT void ReplaceCharacters(string* s, const char* remove, + char replacewith); LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove, char replacewith); |