simdtest.cpp (rapidjson-1.0.2) | : | simdtest.cpp (rapidjson-1.1.0) | ||
---|---|---|---|---|
skipping to change at line 31 | skipping to change at line 31 | |||
# define RAPIDJSON_SSE42 | # define RAPIDJSON_SSE42 | |||
#elif defined(__SSE2__) | #elif defined(__SSE2__) | |||
# define RAPIDJSON_SSE2 | # define RAPIDJSON_SSE2 | |||
#endif | #endif | |||
#define RAPIDJSON_NAMESPACE rapidjson_simd | #define RAPIDJSON_NAMESPACE rapidjson_simd | |||
#include "unittest.h" | #include "unittest.h" | |||
#include "rapidjson/reader.h" | #include "rapidjson/reader.h" | |||
#include "rapidjson/writer.h" | ||||
#ifdef __GNUC__ | ||||
RAPIDJSON_DIAG_PUSH | ||||
RAPIDJSON_DIAG_OFF(effc++) | ||||
#endif | ||||
using namespace rapidjson_simd; | using namespace rapidjson_simd; | |||
#ifdef RAPIDJSON_SSE2 | #ifdef RAPIDJSON_SSE2 | |||
#define SIMD_SUFFIX(name) name##_SSE2 | #define SIMD_SUFFIX(name) name##_SSE2 | |||
#elif defined(RAPIDJSON_SSE42) | #elif defined(RAPIDJSON_SSE42) | |||
#define SIMD_SUFFIX(name) name##_SSE42 | #define SIMD_SUFFIX(name) name##_SSE42 | |||
#else | #else | |||
#define SIMD_SUFFIX(name) name | #define SIMD_SUFFIX(name) name | |||
#endif | #endif | |||
template <typename StreamType> | template <typename StreamType> | |||
void TestSkipWhitespace() { | void TestSkipWhitespace() { | |||
for (int step = 1; step < 32; step++) { | for (size_t step = 1; step < 32; step++) { | |||
char buffer[1025]; | char buffer[1025]; | |||
for (size_t i = 0; i < 1024; i++) | for (size_t i = 0; i < 1024; i++) | |||
buffer[i] = " \t\r\n"[i % 4]; | buffer[i] = " \t\r\n"[i % 4]; | |||
for (size_t i = 0; i < 1024; i += step) | for (size_t i = 0; i < 1024; i += step) | |||
buffer[i] = 'X'; | buffer[i] = 'X'; | |||
buffer[1024] = '\0'; | buffer[1024] = '\0'; | |||
StreamType s(buffer); | StreamType s(buffer); | |||
size_t i = 0; | size_t i = 0; | |||
for (;;) { | for (;;) { | |||
skipping to change at line 69 | skipping to change at line 75 | |||
EXPECT_EQ('X', s.Take()); | EXPECT_EQ('X', s.Take()); | |||
i += step; | i += step; | |||
} | } | |||
} | } | |||
} | } | |||
TEST(SIMD, SIMD_SUFFIX(SkipWhitespace)) { | TEST(SIMD, SIMD_SUFFIX(SkipWhitespace)) { | |||
TestSkipWhitespace<StringStream>(); | TestSkipWhitespace<StringStream>(); | |||
TestSkipWhitespace<InsituStringStream>(); | TestSkipWhitespace<InsituStringStream>(); | |||
} | } | |||
TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) { | ||||
for (size_t step = 1; step < 32; step++) { | ||||
char buffer[1024]; | ||||
for (size_t i = 0; i < 1024; i++) | ||||
buffer[i] = " \t\r\n"[i % 4]; | ||||
for (size_t i = 0; i < 1024; i += step) | ||||
buffer[i] = 'X'; | ||||
MemoryStream ms(buffer, 1024); | ||||
EncodedInputStream<UTF8<>, MemoryStream> s(ms); | ||||
size_t i = 0; | ||||
for (;;) { | ||||
SkipWhitespace(s); | ||||
if (s.Peek() == '\0') | ||||
break; | ||||
//EXPECT_EQ(i, s.Tell()); | ||||
EXPECT_EQ('X', s.Take()); | ||||
i += step; | ||||
} | ||||
} | ||||
} | ||||
struct ScanCopyUnescapedStringHandler : BaseReaderHandler<UTF8<>, ScanCopyUnesca | ||||
pedStringHandler> { | ||||
bool String(const char* str, size_t length, bool) { | ||||
memcpy(buffer, str, length + 1); | ||||
return true; | ||||
} | ||||
char buffer[1024 + 5 + 32]; | ||||
}; | ||||
template <unsigned parseFlags, typename StreamType> | ||||
void TestScanCopyUnescapedString() { | ||||
char buffer[1024 + 5 + 32]; | ||||
char backup[1024 + 5 + 32]; | ||||
// Test "ABCDABCD...\\" | ||||
for (size_t offset = 0; offset < 32; offset++) { | ||||
for (size_t step = 0; step < 1024; step++) { | ||||
char* json = buffer + offset; | ||||
char *p = json; | ||||
*p++ = '\"'; | ||||
for (size_t i = 0; i < step; i++) | ||||
*p++ = "ABCD"[i % 4]; | ||||
*p++ = '\\'; | ||||
*p++ = '\\'; | ||||
*p++ = '\"'; | ||||
*p++ = '\0'; | ||||
strcpy(backup, json); // insitu parsing will overwrite buffer, so ne | ||||
ed to backup first | ||||
StreamType s(json); | ||||
Reader reader; | ||||
ScanCopyUnescapedStringHandler h; | ||||
reader.Parse<parseFlags>(s, h); | ||||
EXPECT_TRUE(memcmp(h.buffer, backup + 1, step) == 0); | ||||
EXPECT_EQ('\\', h.buffer[step]); // escaped | ||||
EXPECT_EQ('\0', h.buffer[step + 1]); | ||||
} | ||||
} | ||||
// Test "\\ABCDABCD..." | ||||
for (size_t offset = 0; offset < 32; offset++) { | ||||
for (size_t step = 0; step < 1024; step++) { | ||||
char* json = buffer + offset; | ||||
char *p = json; | ||||
*p++ = '\"'; | ||||
*p++ = '\\'; | ||||
*p++ = '\\'; | ||||
for (size_t i = 0; i < step; i++) | ||||
*p++ = "ABCD"[i % 4]; | ||||
*p++ = '\"'; | ||||
*p++ = '\0'; | ||||
strcpy(backup, json); // insitu parsing will overwrite buffer, so ne | ||||
ed to backup first | ||||
StreamType s(json); | ||||
Reader reader; | ||||
ScanCopyUnescapedStringHandler h; | ||||
reader.Parse<parseFlags>(s, h); | ||||
EXPECT_TRUE(memcmp(h.buffer + 1, backup + 3, step) == 0); | ||||
EXPECT_EQ('\\', h.buffer[0]); // escaped | ||||
EXPECT_EQ('\0', h.buffer[step + 1]); | ||||
} | ||||
} | ||||
} | ||||
TEST(SIMD, SIMD_SUFFIX(ScanCopyUnescapedString)) { | ||||
TestScanCopyUnescapedString<kParseDefaultFlags, StringStream>(); | ||||
TestScanCopyUnescapedString<kParseInsituFlag, InsituStringStream>(); | ||||
} | ||||
TEST(SIMD, SIMD_SUFFIX(ScanWriteUnescapedString)) { | ||||
char buffer[2048 + 1 + 32]; | ||||
for (size_t offset = 0; offset < 32; offset++) { | ||||
for (size_t step = 0; step < 1024; step++) { | ||||
char* s = buffer + offset; | ||||
char* p = s; | ||||
for (size_t i = 0; i < step; i++) | ||||
*p++ = "ABCD"[i % 4]; | ||||
char escape = "\0\n\\\""[step % 4]; | ||||
*p++ = escape; | ||||
for (size_t i = 0; i < step; i++) | ||||
*p++ = "ABCD"[i % 4]; | ||||
StringBuffer sb; | ||||
Writer<StringBuffer> writer(sb); | ||||
writer.String(s, SizeType(step * 2 + 1)); | ||||
const char* q = sb.GetString(); | ||||
EXPECT_EQ('\"', *q++); | ||||
for (size_t i = 0; i < step; i++) | ||||
EXPECT_EQ("ABCD"[i % 4], *q++); | ||||
if (escape == '\0') { | ||||
EXPECT_EQ('\\', *q++); | ||||
EXPECT_EQ('u', *q++); | ||||
EXPECT_EQ('0', *q++); | ||||
EXPECT_EQ('0', *q++); | ||||
EXPECT_EQ('0', *q++); | ||||
EXPECT_EQ('0', *q++); | ||||
} | ||||
else if (escape == '\n') { | ||||
EXPECT_EQ('\\', *q++); | ||||
EXPECT_EQ('n', *q++); | ||||
} | ||||
else if (escape == '\\') { | ||||
EXPECT_EQ('\\', *q++); | ||||
EXPECT_EQ('\\', *q++); | ||||
} | ||||
else if (escape == '\"') { | ||||
EXPECT_EQ('\\', *q++); | ||||
EXPECT_EQ('\"', *q++); | ||||
} | ||||
for (size_t i = 0; i < step; i++) | ||||
EXPECT_EQ("ABCD"[i % 4], *q++); | ||||
EXPECT_EQ('\"', *q++); | ||||
EXPECT_EQ('\0', *q++); | ||||
} | ||||
} | ||||
} | ||||
#ifdef __GNUC__ | ||||
RAPIDJSON_DIAG_POP | ||||
#endif | ||||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 7 lines changed or added |