Last active
October 14, 2023 18:57
-
-
Save bqqbarbhg/78b57412e1ba00bd61fcf92f4676d605 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static const uint32_t ufbxi_number_start_mask = | |
(((1u << 10) - 1) << ((uint32_t)'0' - 32u)) | | |
(1u << ((uint32_t)'-' - 32u)) | | |
(1u << ((uint32_t)'+' - 32u)) | | |
(1u << ((uint32_t)'.' - 32u)) ; | |
ufbx_static_assert(ufbxi_number_start_codepoint, | |
((uint32_t)'9' - (uint32_t)'0') == 9 && | |
(uint32_t)'0' >= 32u && (uint32_t)'0' < 64u && | |
(uint32_t)'-' >= 32u && (uint32_t)'-' < 64u && | |
(uint32_t)'+' >= 32u && (uint32_t)'+' < 64u && | |
(uint32_t)'.' >= 32u && (uint32_t)'.' < 64u); | |
static ufbxi_forceinline bool ufbxi_is_number_start(char c) | |
{ | |
uint32_t v = (uint32_t)(uint8_t)c - 32u; | |
return v < 32 && ((ufbxi_number_start_mask >> v) & 0x1) != 0; | |
} | |
// We can safely skip over anything of the pattern: | |
// (\s*[0-9\-+\.][0-9\-+\.eE]*\s*,)* | |
#if 0 | |
uint32_t num_deferred = 0; | |
{ | |
__m128i c_digit_lo = _mm_set1_epi8('0' - 1); | |
__m128i c_digit_hi = _mm_set1_epi8('9' + 1); | |
__m128i c_minus = _mm_set1_epi8('-'); | |
__m128i c_plus = _mm_set1_epi8('+'); | |
__m128i c_dot = _mm_set1_epi8('.'); | |
__m128i c_e = _mm_set1_epi8('e'); | |
__m128i c_lowercase = _mm_set1_epi8(0x20); | |
const char *src_next = src; | |
const char *src_defer = src; | |
for (;;) { | |
while (src_defer != end && ufbxi_is_space(*src_defer)) src_defer++; | |
if (src_defer == end || *src_defer != ',') break; | |
src_defer++; | |
while (src_defer != end && ufbxi_is_space(*src_defer)) src_defer++; | |
src_next = src_defer; | |
num_deferred += 1; | |
char c = *src_defer; | |
if (!ufbxi_is_number_start(c)) break; | |
uint32_t count = 0; | |
for (;;) { | |
if (ufbxi_to_size(end - src_defer) <= 16) break; | |
__m128i a = _mm_loadu_si128((const __m128i*)src_defer); | |
__m128i eq; | |
eq = _mm_and_si128(_mm_cmpgt_epi8(a, c_digit_lo), _mm_cmplt_epi8(a, c_digit_hi)); | |
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(_mm_or_si128(a, c_lowercase), c_e)); | |
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(a, c_minus)); | |
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(a, c_plus)); | |
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(a, c_dot)); | |
uint32_t mask = _mm_movemask_epi8(eq); | |
count = ufbxi_tzcnt32(~mask); | |
if (count < 16) break; | |
src_defer += 16; | |
} | |
src_defer += count; | |
} | |
if (num_deferred > 1) { | |
if (type == 'd') { | |
double *v = ufbxi_push(&uc->tmp_stack, double, num_deferred); | |
ufbxi_check(v); | |
*v = (double)val; | |
} else if (type == 'f') { | |
float *v = ufbxi_push(&uc->tmp_stack, float, num_deferred); | |
ufbxi_check(v); | |
*v = (float)val; | |
} | |
size_t length = src_next - src; | |
ufbxi_float_span *span = ufbxi_push(&uc->tmp_ascii_spans, ufbxi_float_span, 1); | |
ufbxi_check(span); | |
span->count = num_deferred - 1; | |
span->source_length = length; | |
if (ua->src_is_retained || !uc->read_fn) { | |
span->source = src; | |
} else { | |
span->source = ufbxi_push_copy(tmp_buf, char, length, src); | |
} | |
span->offset = num_values + 1; | |
ufbxi_check(span->source); | |
ua->retain_buf = tmp_buf; | |
ua->src = src_next; | |
ufbxi_check(ufbxi_ascii_next_token(uc, &ua->token)); | |
ua->retain_buf = NULL; | |
*p_num_read = num_deferred; | |
return 1; | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment