Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
simdtest.cpp
Go to the documentation of this file.
1
// Tencent is pleased to support the open source community by making RapidJSON available.
2
//
3
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4
//
5
// Licensed under the MIT License (the "License"); you may not use this file except
6
// in compliance with the License. You may obtain a copy of the License at
7
//
8
// http://opensource.org/licenses/MIT
9
//
10
// Unless required by applicable law or agreed to in writing, software distributed
11
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13
// specific language governing permissions and limitations under the License.
14
15
// Since Travis CI installs old Valgrind 3.7.0, which fails with some SSE4.2
16
// The unit tests prefix with SIMD should be skipped by Valgrind test
17
18
// __SSE2__ and __SSE4_2__ are recognized by gcc, clang, and the Intel compiler.
19
// We use -march=native with gmake to enable -msse2 and -msse4.2, if supported.
20
#if defined(__SSE4_2__)
21
# define RAPIDJSON_SSE42
22
#elif defined(__SSE2__)
23
# define RAPIDJSON_SSE2
24
#elif defined(__ARM_NEON)
25
# define RAPIDJSON_NEON
26
#endif
27
28
#define RAPIDJSON_NAMESPACE rapidjson_simd
29
30
#include "
unittest.h
"
31
32
#include "
rapidjson/reader.h
"
33
#include "
rapidjson/writer.h
"
34
35
#ifdef __GNUC__
36
RAPIDJSON_DIAG_PUSH
37
RAPIDJSON_DIAG_OFF(effc++)
38
#endif
39
40
using namespace
rapidjson_simd;
41
42
#ifdef RAPIDJSON_SSE2
43
#define SIMD_SUFFIX(name) name##_SSE2
44
#elif defined(RAPIDJSON_SSE42)
45
#define SIMD_SUFFIX(name) name##_SSE42
46
#elif defined(RAPIDJSON_NEON)
47
#define SIMD_SUFFIX(name) name##_NEON
48
#else
49
#define SIMD_SUFFIX(name) name
50
#endif
51
52
template
<
typename
StreamType>
53
void
TestSkipWhitespace
() {
54
for
(
size_t
step = 1; step < 32; step++) {
55
char
buffer[1025];
56
for
(
size_t
i = 0; i < 1024; i++)
57
buffer[i] =
" \t\r\n"
[i % 4];
58
for
(
size_t
i = 0; i < 1024; i += step)
59
buffer[i] =
'X'
;
60
buffer[1024] =
'\0'
;
61
62
StreamType s(buffer);
63
size_t
i = 0;
64
for
(;;) {
65
SkipWhitespace
(s);
66
if
(s.Peek() ==
'\0'
)
67
break
;
68
EXPECT_EQ
(i, s.Tell());
69
EXPECT_EQ
(
'X'
, s.Take());
70
i += step;
71
}
72
}
73
}
74
75
TEST
(SIMD,
SIMD_SUFFIX
(
SkipWhitespace
)) {
76
TestSkipWhitespace<StringStream>
();
77
TestSkipWhitespace<InsituStringStream>
();
78
}
79
80
TEST
(SIMD,
SIMD_SUFFIX
(SkipWhitespace_EncodedMemoryStream)) {
81
for
(
size_t
step = 1; step < 32; step++) {
82
char
buffer[1024];
83
for
(
size_t
i = 0; i < 1024; i++)
84
buffer[i] =
" \t\r\n"
[i % 4];
85
for
(
size_t
i = 0; i < 1024; i += step)
86
buffer[i] =
'X'
;
87
88
MemoryStream
ms(buffer, 1024);
89
EncodedInputStream<UTF8<>
,
MemoryStream
> s(ms);
90
size_t
i = 0;
91
for
(;;) {
92
SkipWhitespace
(s);
93
if
(s.
Peek
() ==
'\0'
)
94
break
;
95
//EXPECT_EQ(i, s.Tell());
96
EXPECT_EQ
(
'X'
, s.
Take
());
97
i += step;
98
}
99
}
100
}
101
102
struct
ScanCopyUnescapedStringHandler
:
BaseReaderHandler
<UTF8<>, ScanCopyUnescapedStringHandler> {
103
bool
String
(
const
char
* str,
size_t
length,
bool
) {
104
memcpy
(
buffer
, str, length + 1);
105
return
true
;
106
}
107
char
buffer
[1024 + 5 + 32];
108
};
109
110
template
<
unsigned
parseFlags,
typename
StreamType>
111
void
TestScanCopyUnescapedString
() {
112
char
buffer[1024 + 5 + 32];
113
char
backup[1024 + 5 + 32];
114
115
// Test "ABCDABCD...\\"
116
for
(
size_t
offset = 0; offset < 32; offset++) {
117
for
(
size_t
step = 0; step < 1024; step++) {
118
char
*
json
= buffer + offset;
119
char
*p =
json
;
120
*p++ =
'\"'
;
121
for
(
size_t
i = 0; i < step; i++)
122
*p++ =
"ABCD"
[i % 4];
123
*p++ =
'\\'
;
124
*p++ =
'\\'
;
125
*p++ =
'\"'
;
126
*p++ =
'\0'
;
127
strcpy(backup,
json
);
// insitu parsing will overwrite buffer, so need to backup first
128
129
StreamType s(
json
);
130
Reader
reader;
131
ScanCopyUnescapedStringHandler
h;
132
reader.
Parse
<parseFlags>(s, h);
133
EXPECT_TRUE
(memcmp(h.
buffer
, backup + 1, step) == 0);
134
EXPECT_EQ
(
'\\'
, h.
buffer
[step]);
// escaped
135
EXPECT_EQ
(
'\0'
, h.
buffer
[step + 1]);
136
}
137
}
138
139
// Test "\\ABCDABCD..."
140
for
(
size_t
offset = 0; offset < 32; offset++) {
141
for
(
size_t
step = 0; step < 1024; step++) {
142
char
*
json
= buffer + offset;
143
char
*p =
json
;
144
*p++ =
'\"'
;
145
*p++ =
'\\'
;
146
*p++ =
'\\'
;
147
for
(
size_t
i = 0; i < step; i++)
148
*p++ =
"ABCD"
[i % 4];
149
*p++ =
'\"'
;
150
*p++ =
'\0'
;
151
strcpy(backup,
json
);
// insitu parsing will overwrite buffer, so need to backup first
152
153
StreamType s(
json
);
154
Reader
reader;
155
ScanCopyUnescapedStringHandler
h;
156
reader.
Parse
<parseFlags>(s, h);
157
EXPECT_TRUE
(memcmp(h.
buffer
+ 1, backup + 3, step) == 0);
158
EXPECT_EQ
(
'\\'
, h.
buffer
[0]);
// escaped
159
EXPECT_EQ
(
'\0'
, h.
buffer
[step + 1]);
160
}
161
}
162
}
163
164
TEST
(SIMD,
SIMD_SUFFIX
(ScanCopyUnescapedString)) {
165
TestScanCopyUnescapedString<kParseDefaultFlags, StringStream>
();
166
TestScanCopyUnescapedString<kParseInsituFlag, InsituStringStream>
();
167
}
168
169
TEST
(SIMD,
SIMD_SUFFIX
(ScanWriteUnescapedString)) {
170
char
buffer[2048 + 1 + 32];
171
for
(
size_t
offset = 0; offset < 32; offset++) {
172
for
(
size_t
step = 0; step < 1024; step++) {
173
char
* s = buffer + offset;
174
char
* p = s;
175
for
(
size_t
i = 0; i < step; i++)
176
*p++ =
"ABCD"
[i % 4];
177
char
escape =
"\0\n\\\""
[step % 4];
178
*p++ = escape;
179
for
(
size_t
i = 0; i < step; i++)
180
*p++ =
"ABCD"
[i % 4];
181
182
StringBuffer
sb;
183
Writer<StringBuffer>
writer(sb);
184
writer.
String
(s,
SizeType
(step * 2 + 1));
185
const
char
* q = sb.
GetString
();
186
EXPECT_EQ
(
'\"'
, *q++);
187
for
(
size_t
i = 0; i < step; i++)
188
EXPECT_EQ
(
"ABCD"
[i % 4], *q++);
189
if
(escape ==
'\0'
) {
190
EXPECT_EQ
(
'\\'
, *q++);
191
EXPECT_EQ
(
'u'
, *q++);
192
EXPECT_EQ
(
'0'
, *q++);
193
EXPECT_EQ
(
'0'
, *q++);
194
EXPECT_EQ
(
'0'
, *q++);
195
EXPECT_EQ
(
'0'
, *q++);
196
}
197
else
if
(escape ==
'\n'
) {
198
EXPECT_EQ
(
'\\'
, *q++);
199
EXPECT_EQ
(
'n'
, *q++);
200
}
201
else
if
(escape ==
'\\'
) {
202
EXPECT_EQ
(
'\\'
, *q++);
203
EXPECT_EQ
(
'\\'
, *q++);
204
}
205
else
if
(escape ==
'\"'
) {
206
EXPECT_EQ
(
'\\'
, *q++);
207
EXPECT_EQ
(
'\"'
, *q++);
208
}
209
for
(
size_t
i = 0; i < step; i++)
210
EXPECT_EQ
(
"ABCD"
[i % 4], *q++);
211
EXPECT_EQ
(
'\"'
, *q++);
212
EXPECT_EQ
(
'\0'
, *q++);
213
}
214
}
215
}
216
217
#ifdef __GNUC__
218
RAPIDJSON_DIAG_POP
219
#endif
EncodedInputStream
Input byte stream wrapper with a statically bound encoding.
Definition
encodedstream.h:39
EncodedInputStream::Peek
Ch Peek() const
Definition
encodedstream.h:48
EncodedInputStream::Take
Ch Take()
Definition
encodedstream.h:49
GenericReader::Parse
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition
reader.h:557
GenericStringBuffer::GetString
const Ch * GetString() const
Definition
stringbuffer.h:73
Writer
JSON writer.
Definition
writer.h:89
Writer::String
bool String(const Ch *str, SizeType length, bool copy=false)
Definition
writer.h:202
Reader
GenericReader< UTF8< char >, UTF8< char >, CrtAllocator > Reader
Definition
fwd.h:90
StringBuffer
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
Definition
fwd.h:61
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition
gtest.h:1922
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition
gtest.h:1859
TEST
#define TEST(test_case_name, test_name)
Definition
gtest.h:2187
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition
glibc_compat.cpp:16
SizeType
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition
rapidjson.h:389
reader.h
SkipWhitespace
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition
reader.h:264
TestScanCopyUnescapedString
void TestScanCopyUnescapedString()
Definition
simdtest.cpp:111
SIMD_SUFFIX
#define SIMD_SUFFIX(name)
Definition
simdtest.cpp:49
TestSkipWhitespace
void TestSkipWhitespace()
Definition
simdtest.cpp:53
BaseReaderHandler
Default implementation of Handler.
Definition
reader.h:196
MemoryStream
Represents an in-memory input byte stream.
Definition
memorystream.h:40
ScanCopyUnescapedStringHandler
Definition
simdtest.cpp:102
ScanCopyUnescapedStringHandler::buffer
char buffer[1024+5+32]
Definition
simdtest.cpp:107
ScanCopyUnescapedStringHandler::String
bool String(const char *str, size_t length, bool)
Definition
simdtest.cpp:103
json
rapidjson::Document json
Definition
transport.cpp:49
unittest.h
writer.h
external
rapidjson
test
unittest
simdtest.cpp
Generated on
for Electroneum by
1.17.0