aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/stubs
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/stubs')
-rw-r--r--src/google/protobuf/stubs/port.h55
-rw-r--r--src/google/protobuf/stubs/strutil.cc15
-rw-r--r--src/google/protobuf/stubs/strutil.h4
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);