Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/string_util.h" | 5 #include "base/string_util.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #include <ctype.h> | 9 #include <ctype.h> |
| 10 #include <errno.h> | 10 #include <errno.h> |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 936 // the va_list, the caller is expected to do that. | 936 // the va_list, the caller is expected to do that. |
| 937 template <class StringType> | 937 template <class StringType> |
| 938 static void StringAppendVT(StringType* dst, | 938 static void StringAppendVT(StringType* dst, |
| 939 const typename StringType::value_type* format, | 939 const typename StringType::value_type* format, |
| 940 va_list ap) { | 940 va_list ap) { |
| 941 // First try with a small fixed size buffer. | 941 // First try with a small fixed size buffer. |
| 942 // This buffer size should be kept in sync with StringUtilTest.GrowBoundary | 942 // This buffer size should be kept in sync with StringUtilTest.GrowBoundary |
| 943 // and StringUtilTest.StringPrintfBounds. | 943 // and StringUtilTest.StringPrintfBounds. |
| 944 typename StringType::value_type stack_buf[1024]; | 944 typename StringType::value_type stack_buf[1024]; |
| 945 | 945 |
| 946 va_list backup_ap; | 946 va_list ap_copy; |
| 947 GG_VA_COPY(backup_ap, ap); | 947 GG_VA_COPY(ap_copy, ap); |
| 948 | 948 |
| 949 #if !defined(OS_WIN) | 949 #if !defined(OS_WIN) |
| 950 errno = 0; | 950 errno = 0; |
| 951 #endif | 951 #endif |
| 952 int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, backup_ap); | 952 int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, ap_copy); |
| 953 va_end(backup_ap); | 953 va_end(ap_copy); |
| 954 | 954 |
| 955 if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) { | 955 if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) { |
| 956 // It fit. | 956 // It fit. |
| 957 dst->append(stack_buf, result); | 957 dst->append(stack_buf, result); |
| 958 return; | 958 return; |
| 959 } | 959 } |
| 960 | 960 |
| 961 // Repeatedly increase buffer size until it fits. | 961 // Repeatedly increase buffer size until it fits. |
| 962 int mem_length = arraysize(stack_buf); | 962 int mem_length = arraysize(stack_buf); |
| 963 while (true) { | 963 while (true) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 983 if (mem_length > 32 * 1024 * 1024) { | 983 if (mem_length > 32 * 1024 * 1024) { |
| 984 // That should be plenty, don't try anything larger. This protects | 984 // That should be plenty, don't try anything larger. This protects |
| 985 // against huge allocations when using vsnprintfT implementations that | 985 // against huge allocations when using vsnprintfT implementations that |
| 986 // return -1 for reasons other than overflow without setting errno. | 986 // return -1 for reasons other than overflow without setting errno. |
| 987 DLOG(WARNING) << "Unable to printf the requested string due to size."; | 987 DLOG(WARNING) << "Unable to printf the requested string due to size."; |
| 988 return; | 988 return; |
| 989 } | 989 } |
| 990 | 990 |
| 991 std::vector<typename StringType::value_type> mem_buf(mem_length); | 991 std::vector<typename StringType::value_type> mem_buf(mem_length); |
| 992 | 992 |
| 993 // Restore the va_list before we use it again. | 993 // NOTE: You can only use a va_list once. Since we're in a while loop, we |
| 994 GG_VA_COPY(backup_ap, ap); | 994 // need to make a new copy each time so we don't use up the original. |
| 995 | 995 GG_VA_COPY(ap_copy, ap); |
| 996 result = vsnprintfT(&mem_buf[0], mem_length, format, ap); | 996 result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy); |
|
Evan Martin
2009/08/24 20:28:50
(note for brett: aside from the variable rename, t
| |
| 997 va_end(backup_ap); | 997 va_end(ap_copy); |
| 998 | 998 |
| 999 if ((result >= 0) && (result < mem_length)) { | 999 if ((result >= 0) && (result < mem_length)) { |
| 1000 // It fit. | 1000 // It fit. |
| 1001 dst->append(&mem_buf[0], result); | 1001 dst->append(&mem_buf[0], result); |
| 1002 return; | 1002 return; |
| 1003 } | 1003 } |
| 1004 } | 1004 } |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 namespace { | 1007 namespace { |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1665 // Each input byte creates two output hex characters. | 1665 // Each input byte creates two output hex characters. |
| 1666 std::string ret(size * 2, '\0'); | 1666 std::string ret(size * 2, '\0'); |
| 1667 | 1667 |
| 1668 for (size_t i = 0; i < size; ++i) { | 1668 for (size_t i = 0; i < size; ++i) { |
| 1669 char b = reinterpret_cast<const char*>(bytes)[i]; | 1669 char b = reinterpret_cast<const char*>(bytes)[i]; |
| 1670 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; | 1670 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; |
| 1671 ret[(i * 2) + 1] = kHexChars[b & 0xf]; | 1671 ret[(i * 2) + 1] = kHexChars[b & 0xf]; |
| 1672 } | 1672 } |
| 1673 return ret; | 1673 return ret; |
| 1674 } | 1674 } |
| OLD | NEW |