1namespace simdjson {
2namespace SIMDJSON_IMPLEMENTATION {
3namespace {
4/// @private
5namespace atomparsing {
6
7// The string_to_uint32 is exclusively used to map literal strings to 32-bit values.
8// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot
9// be certain that the character pointer will be properly aligned.
10// You might think that using memcpy makes this function expensive, but you'd be wrong.
11// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false");
12// to the compile-time constant 1936482662.
13simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(dest: &val, src: str, n: sizeof(uint32_t)); return val; }
14
15
16// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive.
17// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about.
18simdjson_warn_unused
19simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) {
20 uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++)
21 static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes");
22 std::memcpy(dest: &srcval, src: src, n: sizeof(uint32_t));
23 return srcval ^ string_to_uint32(str: atom);
24}
25
26simdjson_warn_unused
27simdjson_inline bool is_valid_true_atom(const uint8_t *src) {
28 return (str4ncmp(src, atom: "true") | jsoncharutils::is_not_structural_or_whitespace(c: src[4])) == 0;
29}
30
31simdjson_warn_unused
32simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) {
33 if (len > 4) { return is_valid_true_atom(src); }
34 else if (len == 4) { return !str4ncmp(src, atom: "true"); }
35 else { return false; }
36}
37
38simdjson_warn_unused
39simdjson_inline bool is_valid_false_atom(const uint8_t *src) {
40 return (str4ncmp(src: src+1, atom: "alse") | jsoncharutils::is_not_structural_or_whitespace(c: src[5])) == 0;
41}
42
43simdjson_warn_unused
44simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) {
45 if (len > 5) { return is_valid_false_atom(src); }
46 else if (len == 5) { return !str4ncmp(src: src+1, atom: "alse"); }
47 else { return false; }
48}
49
50simdjson_warn_unused
51simdjson_inline bool is_valid_null_atom(const uint8_t *src) {
52 return (str4ncmp(src, atom: "null") | jsoncharutils::is_not_structural_or_whitespace(c: src[4])) == 0;
53}
54
55simdjson_warn_unused
56simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) {
57 if (len > 4) { return is_valid_null_atom(src); }
58 else if (len == 4) { return !str4ncmp(src, atom: "null"); }
59 else { return false; }
60}
61
62} // namespace atomparsing
63} // unnamed namespace
64} // namespace SIMDJSON_IMPLEMENTATION
65} // namespace simdjson
66