github.com/minio/simdjson-go@v0.4.6-0.20231116094823-04d21cddf993/stage2_build_tape_amd64_test.go (about) 1 //go:build !noasm && !appengine && gc 2 // +build !noasm,!appengine,gc 3 4 /* 5 * MinIO Cloud Storage, (C) 2020 MinIO, Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package simdjson 21 22 import ( 23 "testing" 24 ) 25 26 func TestStage2BuildTape(t *testing.T) { 27 if !SupportedCPU() { 28 t.SkipNow() 29 } 30 var floatHexRepresentation1 uint64 = 0x69066666666666 31 var floatHexRepresentation2 uint64 = 0x79066666666666 32 33 const nul = '\000' 34 35 testCases := []struct { 36 input string 37 expected []struct { 38 c byte 39 val uint64 40 } 41 }{ 42 { 43 `{"a":"b","c":"dd"}`, 44 []struct { 45 c byte 46 val uint64 47 }{ 48 {'r', 0xc}, 49 {'{', 0xb}, 50 {'"', 0x2}, 51 {nul, 0x1}, 52 {'"', 0x6}, 53 {nul, 0x1}, 54 {'"', 0xa}, 55 {nul, 0x1}, 56 {'"', 0xe}, 57 {nul, 0x2}, 58 {'}', 0x1}, 59 {'r', 0x0}, 60 }, 61 }, 62 { 63 `{"a":"b","c":{"d":"e"}}`, 64 []struct { 65 c byte 66 val uint64 67 }{ 68 {'r', 0x10}, 69 {'{', 0xf}, 70 {'"', 0x2}, 71 {nul, 0x1}, 72 {'"', 0x6}, 73 {nul, 0x1}, 74 {'"', 0xa}, 75 {nul, 0x1}, 76 {'{', 0xe}, 77 {'"', 0xf}, 78 {nul, 0x1}, 79 {'"', 0x13}, 80 {nul, 0x1}, 81 {'}', 0x8}, 82 {'}', 0x1}, 83 {'r', 0x0}, 84 }, 85 }, 86 { 87 `{"a":"b","c":[{"d":"e"},{"f":"g"}]}`, 88 []struct { 89 c byte 90 val uint64 91 }{ 92 {'r', 0x18}, 93 {'{', 0x17}, 94 {'"', 0x2}, 95 {nul, 0x1}, 96 {'"', 0x6}, 97 {nul, 0x1}, 98 {'"', 0xa}, 99 {nul, 0x1}, 100 {'[', 0x16}, 101 {'{', 0xf}, 102 {'"', 0x10}, 103 {nul, 0x1}, 104 {'"', 0x14}, 105 {nul, 0x1}, 106 {'}', 0x9}, 107 {'{', 0x15}, 108 {'"', 0x1a}, 109 {nul, 0x1}, 110 {'"', 0x1e}, 111 {nul, 0x1}, 112 {'}', 0xf}, 113 {']', 0x8}, 114 {'}', 0x1}, 115 {'r', 0x0}, 116 }, 117 }, 118 { 119 `{"a":true,"b":false,"c":null} `, // without additional spaces, isValidNullAtom reads beyond buffer capacity 120 []struct { 121 c byte 122 val uint64 123 }{ 124 {'r', 0xd}, 125 {'{', 0xc}, 126 {'"', 0x2}, 127 {nul, 0x1}, 128 {'t', 0x0}, 129 {'"', 0xb}, 130 {nul, 0x1}, 131 {'f', 0x0}, 132 {'"', 0x15}, 133 {nul, 0x1}, 134 {'n', 0x0}, 135 {'}', 0x1}, 136 {'r', 0x0}, 137 }, 138 }, 139 { 140 `{"a":100,"b":200.2,"c":300,"d":400.4}`, 141 []struct { 142 c byte 143 val uint64 144 }{ 145 {'r', 0x14}, 146 {'{', 0x13}, 147 {'"', 0x2}, 148 {nul, 0x1}, 149 {'l', 0x0}, 150 {nul, 0x64}, // 100 151 {'"', 0xa}, 152 {nul, 0x1}, 153 {'d', 0x0}, 154 {'@', floatHexRepresentation1}, // 200.2 155 {'"', 0x14}, 156 {nul, 0x1}, 157 {'l', 0x0}, 158 {nul, 0x12c}, // 300 159 {'"', 0x1c}, 160 {nul, 0x1}, 161 {'d', 0x0}, 162 {'@', floatHexRepresentation2}, // 400.4 163 {'}', 0x1}, 164 {'r', 0x0}, 165 }, 166 }, 167 } 168 169 for i, tc := range testCases { 170 171 pj := internalParsedJson{} 172 173 if err := pj.parseMessage([]byte(tc.input), false); err != nil { 174 t.Errorf("TestStage2BuildTape(%d): got: %v want: nil", i, err) 175 } 176 177 if len(pj.Tape) != len(tc.expected) { 178 t.Errorf("TestStage2BuildTape(%d): got: %d want: %d", i, len(pj.Tape), len(tc.expected)) 179 } 180 181 for ii, tp := range pj.Tape { 182 //c := "'" + string(byte(tp >> 56)) + "'" 183 //if byte(tp >> 56) == 0 { 184 // c = "nul" 185 //} 186 //fmt.Printf("{%s, 0x%x},\n", c, tp&0xffffffffffffff) 187 expected := tc.expected[ii].val | (uint64(tc.expected[ii].c) << 56) 188 if !pj.copyStrings && tp != expected { 189 t.Errorf("TestStage2BuildTape(%d): got: %d want: %d", ii, tp, expected) 190 } 191 } 192 } 193 } 194 195 func TestIsValidTrueAtom(t *testing.T) { 196 197 testCases := []struct { 198 input string 199 expected bool 200 }{ 201 {"true ", true}, 202 {"true, ", true}, 203 {"true} ", true}, 204 {"true] ", true}, 205 {"treu ", false}, // French for true, so perhaps should be true 206 {"true1 ", false}, 207 {"truea ", false}, 208 } 209 210 for _, tc := range testCases { 211 same := isValidTrueAtom([]byte(tc.input)) 212 if same != tc.expected { 213 t.Errorf("TestIsValidTrueAtom: got: %v want: %v", same, tc.expected) 214 } 215 } 216 } 217 218 func TestIsValidFalseAtom(t *testing.T) { 219 220 testCases := []struct { 221 input string 222 expected bool 223 }{ 224 {"false ", true}, 225 {"false, ", true}, 226 {"false} ", true}, 227 {"false] ", true}, 228 {"flase ", false}, 229 {"false1 ", false}, 230 {"falsea ", false}, 231 } 232 233 for _, tc := range testCases { 234 same := isValidFalseAtom([]byte(tc.input)) 235 if same != tc.expected { 236 t.Errorf("TestIsValidFalseAtom: got: %v want: %v", same, tc.expected) 237 } 238 } 239 } 240 241 func TestIsValidNullAtom(t *testing.T) { 242 243 testCases := []struct { 244 input string 245 expected bool 246 }{ 247 {"null ", true}, 248 {"null, ", true}, 249 {"null} ", true}, 250 {"null] ", true}, 251 {"nul ", false}, 252 {"null1 ", false}, 253 {"nulla ", false}, 254 } 255 256 for _, tc := range testCases { 257 same := isValidNullAtom([]byte(tc.input)) 258 if same != tc.expected { 259 t.Errorf("TestIsValidNullAtom: got: %v want: %v", same, tc.expected) 260 } 261 } 262 }