Wire Sysio Wire Sysion 1.0.0
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__
36RAPIDJSON_DIAG_PUSH
37RAPIDJSON_DIAG_OFF(effc++)
38#endif
39
40using 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
52template <typename StreamType>
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 (;;) {
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
79
80TEST(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);
90 size_t i = 0;
91 for (;;) {
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
102struct 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
110template <unsigned parseFlags, typename StreamType>
112 char buffer[1024u + 5 + 32];
113 char backup[1024u + 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;
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;
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
168
169TEST(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__
218RAPIDJSON_DIAG_POP
219#endif
const mie::Vuint & p
Definition bn.cpp:27
Input byte stream wrapper with a statically bound encoding.
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition reader.h:557
const Ch * GetString() const
JSON writer.
Definition writer.h:89
bool String(const Ch *str, SizeType length, bool copy=false)
Definition writer.h:202
#define EXPECT_EQ(val1, val2)
Definition gtest.h:1954
#define EXPECT_TRUE(condition)
Definition gtest.h:1895
#define TEST(test_case_name, test_name)
Definition gtest.h:2275
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:384
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition reader.h:264
void TestScanCopyUnescapedString()
Definition simdtest.cpp:111
#define SIMD_SUFFIX(name)
Definition simdtest.cpp:49
void TestSkipWhitespace()
Definition simdtest.cpp:53
Default implementation of Handler.
Definition reader.h:196
Represents an in-memory input byte stream.
bool String(const char *str, size_t length, bool)
Definition simdtest.cpp:103
char * s
memcpy((char *) pInfo->slotDescription, s, l)