Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/strings/safe_sprintf.h" | 5 #include "base/strings/safe_sprintf.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 namespace { | 65 namespace { |
| 66 const size_t kSSizeMaxConst = ((size_t)(ssize_t)-1) >> 1; | 66 const size_t kSSizeMaxConst = ((size_t)(ssize_t)-1) >> 1; |
| 67 | 67 |
| 68 const char kUpCaseHexDigits[] = "0123456789ABCDEF"; | 68 const char kUpCaseHexDigits[] = "0123456789ABCDEF"; |
| 69 const char kDownCaseHexDigits[] = "0123456789abcdef"; | 69 const char kDownCaseHexDigits[] = "0123456789abcdef"; |
| 70 } | 70 } |
| 71 | 71 |
| 72 #if defined(NDEBUG) | 72 #if defined(NDEBUG) |
| 73 // We would like to define kSSizeMax as std::numeric_limits<ssize_t>::max(), | 73 // We would like to define kSSizeMax as std::numeric_limits<ssize_t>::max(), |
| 74 // but C++ doesn't allow us to do that for constants. Instead, we have to | 74 // but C++ doesn't allow us to do that for constants. Instead, we have to |
| 75 // use careful casting and shifting. We later use a COMPILE_ASSERT to | 75 // use careful casting and shifting. We later use a static_assert to |
| 76 // verify that this worked correctly. | 76 // verify that this worked correctly. |
| 77 namespace { | 77 namespace { |
| 78 const size_t kSSizeMax = kSSizeMaxConst; | 78 const size_t kSSizeMax = kSSizeMaxConst; |
| 79 } | 79 } |
| 80 #else // defined(NDEBUG) | 80 #else // defined(NDEBUG) |
| 81 // For efficiency, we really need kSSizeMax to be a constant. But for unit | 81 // For efficiency, we really need kSSizeMax to be a constant. But for unit |
| 82 // tests, it should be adjustable. This allows us to verify edge cases without | 82 // tests, it should be adjustable. This allows us to verify edge cases without |
| 83 // having to fill the entire available address space. As a compromise, we make | 83 // having to fill the entire available address space. As a compromise, we make |
| 84 // kSSizeMax adjustable in debug builds, and then only compile that particular | 84 // kSSizeMax adjustable in debug builds, and then only compile that particular |
| 85 // part of the unit test in debug builds. | 85 // part of the unit test in debug builds. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 105 // has |size| bytes of writable storage. It is the caller's responsibility | 105 // has |size| bytes of writable storage. It is the caller's responsibility |
| 106 // to ensure that the buffer is at least one byte in size, so that it fits | 106 // to ensure that the buffer is at least one byte in size, so that it fits |
| 107 // the trailing NUL that will be added by the destructor. The buffer also | 107 // the trailing NUL that will be added by the destructor. The buffer also |
| 108 // must be smaller or equal to kSSizeMax in size. | 108 // must be smaller or equal to kSSizeMax in size. |
| 109 Buffer(char* buffer, size_t size) | 109 Buffer(char* buffer, size_t size) |
| 110 : buffer_(buffer), | 110 : buffer_(buffer), |
| 111 size_(size - 1), // Account for trailing NUL byte | 111 size_(size - 1), // Account for trailing NUL byte |
| 112 count_(0) { | 112 count_(0) { |
| 113 // The following assertion does not build on Mac and Android. This is because | 113 // The following assertion does not build on Mac and Android. This is because |
| 114 // static_assert only works with compile-time constants, but mac uses | 114 // static_assert only works with compile-time constants, but mac uses |
| 115 // libstdc++4.2 and android uses stlport, which both don't mark | 115 // libstdc++4.2 and android uses stlport, which both don't mark |
|
Mostyn Bramley-Moore
2015/11/23 06:44:14
IIRC we use libc++ on OSX and Android now (not sur
Avi (use Gerrit)
2015/11/24 04:49:43
Done.
| |
| 116 // numeric_limits::max() as constexp. Likewise, MSVS2013's standard library | 116 // numeric_limits::max() as constexp. Likewise, MSVS2013's standard library |
| 117 // also doesn't mark max() as constexpr yet. cl.exe supports static_cast but | 117 // also doesn't mark max() as constexpr yet. cl.exe supports static_cast but |
| 118 // doesn't really implement constexpr yet so it doesn't complain, but clang | 118 // doesn't really implement constexpr yet so it doesn't complain, but clang |
| 119 // does. | 119 // does. |
| 120 #if __cplusplus >= 201103 && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \ | 120 #if __cplusplus >= 201103 && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \ |
| 121 !defined(OS_IOS) && !(defined(__clang__) && defined(OS_WIN)) | 121 !defined(OS_IOS) && !(defined(__clang__) && defined(OS_WIN)) |
| 122 COMPILE_ASSERT(kSSizeMaxConst == \ | 122 static_assert(kSSizeMaxConst == |
| 123 static_cast<size_t>(std::numeric_limits<ssize_t>::max()), | 123 static_cast<size_t>(std::numeric_limits<ssize_t>::max()), |
| 124 kSSizeMax_is_the_max_value_of_an_ssize_t); | 124 "kSSizeMax_is_the_max_value_of_an_ssize_t"); |
| 125 #endif | 125 #endif |
| 126 DEBUG_CHECK(size > 0); | 126 DEBUG_CHECK(size > 0); |
| 127 DEBUG_CHECK(size <= kSSizeMax); | 127 DEBUG_CHECK(size <= kSSizeMax); |
| 128 } | 128 } |
| 129 | 129 |
| 130 ~Buffer() { | 130 ~Buffer() { |
| 131 // The code calling the constructor guaranteed that there was enough space | 131 // The code calling the constructor guaranteed that there was enough space |
| 132 // to store a trailing NUL -- and in debug builds, we are actually | 132 // to store a trailing NUL -- and in debug builds, we are actually |
| 133 // verifying this with DEBUG_CHECK()s in the constructor. So, we can | 133 // verifying this with DEBUG_CHECK()s in the constructor. So, we can |
| 134 // always unconditionally write the NUL byte in the destructor. We do not | 134 // always unconditionally write the NUL byte in the destructor. We do not |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 DEBUG_CHECK(src[0] != '%' || src[1] == '%'); | 679 DEBUG_CHECK(src[0] != '%' || src[1] == '%'); |
| 680 if (src[0] == '%' && src[1] == '%') { | 680 if (src[0] == '%' && src[1] == '%') { |
| 681 ++src; | 681 ++src; |
| 682 } | 682 } |
| 683 } | 683 } |
| 684 return buffer.GetCount(); | 684 return buffer.GetCount(); |
| 685 } | 685 } |
| 686 | 686 |
| 687 } // namespace strings | 687 } // namespace strings |
| 688 } // namespace base | 688 } // namespace base |
| OLD | NEW |