Skip to content

Commit a1fac15

Browse files
authored
Merge pull request Tencent#872 from StilesCrisis/issue845_native_strlen
Use native strlen
2 parents 02de698 + c4e3d62 commit a1fac15

File tree

5 files changed

+70
-9
lines changed

5 files changed

+70
-9
lines changed

include/rapidjson/internal/strfunc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define RAPIDJSON_INTERNAL_STRFUNC_H_
1717

1818
#include "../stream.h"
19+
#include <cwchar>
1920

2021
RAPIDJSON_NAMESPACE_BEGIN
2122
namespace internal {
@@ -34,6 +35,16 @@ inline SizeType StrLen(const Ch* s) {
3435
return SizeType(p - s);
3536
}
3637

38+
template <>
39+
inline SizeType StrLen(const char* s) {
40+
return SizeType(std::strlen(s));
41+
}
42+
43+
template <>
44+
inline SizeType StrLen(const wchar_t* s) {
45+
return SizeType(std::wcslen(s));
46+
}
47+
3748
//! Returns number of code points in a encoded string.
3849
template<typename Encoding>
3950
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {

include/rapidjson/prettywriter.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
107107
return Base::WriteString(str, length);
108108
}
109109

110-
bool String(const Ch* str, SizeType length, bool copy = false) {
110+
template <typename T>
111+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* str, SizeType length, bool copy = false) {
111112
RAPIDJSON_ASSERT(str != 0);
112113
(void)copy;
113114
PrettyPrefix(kStringType);
@@ -126,7 +127,8 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
126127
return Base::WriteStartObject();
127128
}
128129

129-
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
130+
template <typename T>
131+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* str, SizeType length, bool copy = false) { return String(str, length, copy); }
130132

131133
#if RAPIDJSON_HAS_STDSTRING
132134
bool Key(const std::basic_string<Ch>& str) {
@@ -184,8 +186,22 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
184186
//@{
185187

186188
//! Simpler but slower overload.
187-
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
188-
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
189+
template <typename T>
190+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* const& str) { return String(str, internal::StrLen(str)); }
191+
template <typename T>
192+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* const& str) { return Key(str, internal::StrLen(str)); }
193+
194+
//! The compiler can give us the length of quoted strings for free.
195+
template <typename T, size_t N>
196+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T (&str)[N]) {
197+
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
198+
return String(str, N-1);
199+
}
200+
template <typename T, size_t N>
201+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T (&str)[N]) {
202+
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
203+
return Key(str, N-1);
204+
}
189205

190206
//@}
191207

include/rapidjson/writer.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define RAPIDJSON_WRITER_H_
1717

1818
#include "stream.h"
19+
#include "internal/meta.h"
1920
#include "internal/stack.h"
2021
#include "internal/strfunc.h"
2122
#include "internal/dtoa.h"
@@ -198,7 +199,8 @@ class Writer {
198199
return EndValue(WriteString(str, length));
199200
}
200201

201-
bool String(const Ch* str, SizeType length, bool copy = false) {
202+
template <typename T>
203+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* str, SizeType length, bool copy = false) {
202204
RAPIDJSON_ASSERT(str != 0);
203205
(void)copy;
204206
Prefix(kStringType);
@@ -217,7 +219,8 @@ class Writer {
217219
return WriteStartObject();
218220
}
219221

220-
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
222+
template <typename T>
223+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* str, SizeType length, bool copy = false) { return String(str, length, copy); }
221224

222225
bool EndObject(SizeType memberCount = 0) {
223226
(void)memberCount;
@@ -247,8 +250,22 @@ class Writer {
247250
//@{
248251

249252
//! Simpler but slower overload.
250-
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
251-
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
253+
template <typename T>
254+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* const& str) { return String(str, internal::StrLen(str)); }
255+
template <typename T>
256+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* const& str) { return Key(str, internal::StrLen(str)); }
257+
258+
//! The compiler can give us the length of quoted strings for free.
259+
template <typename T, size_t N>
260+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T (&str)[N]) {
261+
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
262+
return String(str, N-1);
263+
}
264+
template <typename T, size_t N>
265+
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T (&str)[N]) {
266+
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
267+
return Key(str, N-1);
268+
}
252269

253270
//@}
254271

test/unittest/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ add_test(NAME unittest
7979
if(NOT MSVC)
8080
# Not running SIMD.* unit test cases for Valgrind
8181
add_test(NAME valgrind_unittest
82-
COMMAND valgrind --leak-check=full --error-exitcode=1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest --gtest_filter=-SIMD.*
82+
COMMAND valgrind --suppressions=${CMAKE_SOURCE_DIR}/test/valgrind.supp --leak-check=full --error-exitcode=1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest --gtest_filter=-SIMD.*
8383
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
8484

8585
if(CMAKE_BUILD_TYPE STREQUAL "Debug")

test/valgrind.supp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
Suppress wcslen valgrind report 1
3+
Memcheck:Cond
4+
fun:__wcslen_sse2
5+
}
6+
7+
{
8+
Suppress wcslen valgrind report 2
9+
Memcheck:Addr8
10+
fun:__wcslen_sse2
11+
}
12+
13+
{
14+
Suppress wcslen valgrind report 3
15+
Memcheck:Value8
16+
fun:__wcslen_sse2
17+
}

0 commit comments

Comments
 (0)