Index: chrome/browser/sync/notifier/base/string.cc |
=================================================================== |
--- chrome/browser/sync/notifier/base/string.cc (revision 0) |
+++ chrome/browser/sync/notifier/base/string.cc (revision 0) |
@@ -0,0 +1,403 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifdef OS_MACOSX |
+#include <CoreFoundation/CoreFoundation.h> |
+#endif |
+ |
+#include <float.h> |
+#include <string.h> |
+ |
+#include "base/format_macros.h" |
+#include "base/string_util.h" |
+#include "chrome/browser/sync/notifier/base/string.h" |
+#include "talk/base/common.h" |
+#include "talk/base/logging.h" |
+#include "talk/base/stringencode.h" |
+ |
+using base::snprintf; |
+ |
+namespace notifier { |
+ |
+std::string HtmlEncode(const std::string& src) { |
+ size_t max_length = src.length() * 6 + 1; |
+ std::string dest; |
+ dest.resize(max_length); |
+ size_t new_size = talk_base::html_encode(&dest[0], max_length, |
+ src.data(), src.length()); |
+ dest.resize(new_size); |
+ return dest; |
+} |
+ |
+std::string HtmlDecode(const std::string& src) { |
+ size_t max_length = src.length() + 1; |
+ std::string dest; |
+ dest.resize(max_length); |
+ size_t new_size = talk_base::html_decode(&dest[0], max_length, |
+ src.data(), src.length()); |
+ dest.resize(new_size); |
+ return dest; |
+} |
+ |
+std::string UrlEncode(const std::string& src) { |
+ size_t max_length = src.length() * 6 + 1; |
+ std::string dest; |
+ dest.resize(max_length); |
+ size_t new_size = talk_base::url_encode(&dest[0], max_length, |
+ src.data(), src.length()); |
+ dest.resize(new_size); |
+ return dest; |
+} |
+ |
+std::string UrlDecode(const std::string& src) { |
+ size_t max_length = src.length() + 1; |
+ std::string dest; |
+ dest.resize(max_length); |
+ size_t new_size = talk_base::url_decode(&dest[0], max_length, |
+ src.data(), src.length()); |
+ dest.resize(new_size); |
+ return dest; |
+} |
+ |
+int CharToHexValue(char hex) { |
+ if (hex >= '0' && hex <= '9') { |
+ return hex - '0'; |
+ } else if (hex >= 'A' && hex <= 'F') { |
+ return hex - 'A' + 10; |
+ } else if (hex >= 'a' && hex <= 'f') { |
+ return hex - 'a' + 10; |
+ } else { |
+ return -1; |
+ } |
+} |
+ |
+// Template function to convert a string to an int/int64 |
+// If strict is true, check for the validity and overflow |
+template<typename T> |
+bool ParseStringToIntTemplate(const char* str, |
+ T* value, |
+ bool strict, |
+ T min_value) { |
+ ASSERT(str); |
+ ASSERT(value); |
+ |
+ // Skip spaces |
+ while (*str == ' ') { |
+ ++str; |
+ } |
+ |
+ // Process sign |
+ int c = static_cast<int>(*str++); // current char |
+ int possible_sign = c; // save sign indication |
+ if (c == '-' || c == '+') { |
+ c = static_cast<int>(*str++); |
+ } |
+ |
+ // Process numbers |
+ T total = 0; |
+ while (c && (c = CharToDigit(static_cast<char>(c))) != -1) { |
+ // Check for overflow |
+ if (strict && (total < min_value / 10 || |
+ (total == min_value / 10 && |
+ c > ((-(min_value + 10)) % 10)))) { |
+ return false; |
+ } |
+ |
+ // Accumulate digit |
+ // Note that we accumulate in the negative direction so that we will not |
+ // blow away with the largest negative number |
+ total = 10 * total - c; |
+ |
+ // Get next char |
+ c = static_cast<int>(*str++); |
+ } |
+ |
+ // Fail if encountering non-numeric character |
+ if (strict && c == -1) { |
+ return false; |
+ } |
+ |
+ // Negate the number if needed |
+ if (possible_sign == '-') { |
+ *value = total; |
+ } else { |
+ // Check for overflow |
+ if (strict && total == min_value) { |
+ return false; |
+ } |
+ |
+ *value = -total; |
+ } |
+ |
+ return true; |
+} |
+ |
+// Convert a string to an int |
+// If strict is true, check for the validity and overflow |
+bool ParseStringToInt(const char* str, int* value, bool strict) { |
+ return ParseStringToIntTemplate<int>(str, value, strict, kint32min); |
+} |
+ |
+// Convert a string to an int |
+// This version does not check for the validity and overflow |
+int StringToInt(const char* str) { |
+ int value = 0; |
+ ParseStringToInt(str, &value, false); |
+ return value; |
+} |
+ |
+// Convert a string to an unsigned int. |
+// If strict is true, check for the validity and overflow |
+bool ParseStringToUint(const char* str, uint32* value, bool strict) { |
+ ASSERT(str); |
+ ASSERT(value); |
+ |
+ int64 int64_value; |
+ if (!ParseStringToInt64(str, &int64_value, strict)) { |
+ return false; |
+ } |
+ if (int64_value < 0 || int64_value > kuint32max) { |
+ return false; |
+ } |
+ |
+ *value = static_cast<uint32>(int64_value); |
+ return true; |
+} |
+ |
+// Convert a string to an int |
+// This version does not check for the validity and overflow |
+uint32 StringToUint(const char* str) { |
+ uint32 value = 0; |
+ ParseStringToUint(str, &value, false); |
+ return value; |
+} |
+ |
+// Convert a string to an int64 |
+// If strict is true, check for the validity and overflow |
+bool ParseStringToInt64(const char* str, int64* value, bool strict) { |
+ return ParseStringToIntTemplate<int64>(str, value, strict, kint64min); |
+} |
+ |
+// Convert a string to an int64 |
+// This version does not check for the validity and overflow |
+int64 StringToInt64(const char* str) { |
+ int64 value = 0; |
+ ParseStringToInt64(str, &value, false); |
+ return value; |
+} |
+ |
+// Convert a string to a double |
+// If strict is true, check for the validity and overflow |
+bool ParseStringToDouble(const char* str, double* value, bool strict) { |
+ ASSERT(str); |
+ ASSERT(value); |
+ |
+ // Skip spaces |
+ while (*str == ' ') { |
+ ++str; |
+ } |
+ |
+ // Process sign |
+ int c = static_cast<int>(*str++); // current char |
+ int sign = c; // save sign indication |
+ if (c == '-' || c == '+') { |
+ c = static_cast<int>(*str++); |
+ } |
+ |
+ // Process numbers before "." |
+ double total = 0.0; |
+ while (c && (c != '.') && (c = CharToDigit(static_cast<char>(c))) != -1) { |
+ // Check for overflow |
+ if (strict && total >= DBL_MAX / 10) { |
+ return false; |
+ } |
+ |
+ // Accumulate digit |
+ total = 10.0 * total + c; |
+ |
+ // Get next char |
+ c = static_cast<int>(*str++); |
+ } |
+ |
+ // Process "." |
+ if (c == '.') { |
+ c = static_cast<int>(*str++); |
+ } else { |
+ // Fail if encountering non-numeric character |
+ if (strict && c == -1) { |
+ return false; |
+ } |
+ } |
+ |
+ // Process numbers after "." |
+ double power = 1.0; |
+ while ((c = CharToDigit(static_cast<char>(c))) != -1) { |
+ // Check for overflow |
+ if (strict && total >= DBL_MAX / 10) { |
+ return false; |
+ } |
+ |
+ // Accumulate digit |
+ total = 10.0 * total + c; |
+ power *= 10.0; |
+ |
+ // Get next char |
+ c = static_cast<int>(*str++); |
+ } |
+ |
+ // Get the final number |
+ *value = total / power; |
+ if (sign == '-') { |
+ *value = -(*value); |
+ } |
+ |
+ return true; |
+} |
+ |
+// Convert a string to a double |
+// This version does not check for the validity and overflow |
+double StringToDouble(const char* str) { |
+ double value = 0; |
+ ParseStringToDouble(str, &value, false); |
+ return value; |
+} |
+ |
+// Convert a float to a string |
+std::string FloatToString(float f) { |
+ char buf[80]; |
+ snprintf(buf, sizeof(buf), "%f", f); |
+ return std::string(buf); |
+} |
+ |
+std::string DoubleToString(double d) { |
+ char buf[160]; |
+ snprintf(buf, sizeof(buf), "%.17g", d); |
+ return std::string(buf); |
+} |
+ |
+std::string UIntToString(uint32 i) { |
+ char buf[80]; |
+ snprintf(buf, sizeof(buf), "%lu", i); |
+ return std::string(buf); |
+} |
+ |
+// Convert an int to a string |
+std::string IntToString(int i) { |
+ char buf[80]; |
+ snprintf(buf, sizeof(buf), "%d", i); |
+ return std::string(buf); |
+} |
+ |
+// Convert an int64 to a string |
+std::string Int64ToString(int64 i64) { |
+ char buf[80]; |
+ snprintf(buf, sizeof(buf), "%" PRId64 "d", i64); |
+ return std::string(buf); |
+} |
+ |
+std::string UInt64ToString(uint64 i64) { |
+ char buf[80]; |
+ snprintf(buf, sizeof(buf), "%" PRId64 "u", i64); |
+ return std::string(buf); |
+} |
+ |
+std::string Int64ToHexString(int64 i64) { |
+ char buf[80]; |
+ snprintf(buf, sizeof(buf), "%" PRId64 "x", i64); |
+ return std::string(buf); |
+} |
+ |
+// Parse a single "delim" delimited string from "*source" |
+// Modify *source to point after the delimiter. |
+// If no delimiter is present after the string, set *source to NULL. |
+// |
+// Mainly a stringified wrapper around strpbrk() |
+std::string SplitOneStringToken(const char** source, const char* delim) { |
+ ASSERT(source); |
+ ASSERT(delim); |
+ |
+ if (!*source) { |
+ return std::string(); |
+ } |
+ const char* begin = *source; |
+ *source = strpbrk(*source, delim); |
+ if (*source) { |
+ return std::string(begin, (*source)++); |
+ } else { |
+ return std::string(begin); |
+ } |
+} |
+ |
+std::string LowerWithUnderToPascalCase(const char* lower_with_under) { |
+ ASSERT(lower_with_under); |
+ |
+ std::string pascal_case; |
+ bool make_upper = true; |
+ for (; *lower_with_under != '\0'; lower_with_under++) { |
+ char current_char = *lower_with_under; |
+ if (current_char == '_') { |
+ ASSERT(!make_upper); |
+ make_upper = true; |
+ continue; |
+ } |
+ if (make_upper) { |
+ current_char = toupper(current_char); |
+ make_upper = false; |
+ } |
+ pascal_case.append(1, current_char); |
+ } |
+ return pascal_case; |
+} |
+ |
+std::string PascalCaseToLowerWithUnder(const char* pascal_case) { |
+ ASSERT(pascal_case); |
+ |
+ std::string lower_with_under; |
+ bool previous_was_upper = true; |
+ for(; *pascal_case != '\0'; pascal_case++) { |
+ char current_char = *pascal_case; |
+ if (isupper(current_char)) { |
+ // DNSName should be dns_name |
+ if ((islower(pascal_case[1]) && !lower_with_under.empty()) || |
+ !previous_was_upper) { |
+ lower_with_under.append(1, '_'); |
+ } |
+ current_char = tolower(current_char); |
+ } else if (previous_was_upper) { |
+ previous_was_upper = false; |
+ } |
+ lower_with_under.append(1, current_char); |
+ } |
+ return lower_with_under; |
+} |
+void StringReplace(std::string* s, |
+ const char* old_sub, |
+ const char* new_sub, |
+ bool replace_all) { |
+ ASSERT(s); |
+ |
+ // If old_sub is empty, nothing to do |
+ if (!old_sub || !*old_sub) { |
+ return; |
+ } |
+ |
+ int old_sub_size = strlen(old_sub); |
+ std::string res; |
+ std::string::size_type start_pos = 0; |
+ |
+ do { |
+ std::string::size_type pos = s->find(old_sub, start_pos); |
+ if (pos == std::string::npos) { |
+ break; |
+ } |
+ res.append(*s, start_pos, pos - start_pos); |
+ res.append(new_sub); |
+ start_pos = pos + old_sub_size; // start searching again after the "old" |
+ } while (replace_all); |
+ res.append(*s, start_pos, s->length() - start_pos); |
+ |
+ *s = res; |
+} |
+ |
+} // namespace notifier |
Property changes on: chrome\browser\sync\notifier\base\string.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |