use super::{estimate_float_count, estimate_int_count, is_number_start, parse_index_value};
#[inline]
pub(super) fn may_contain_step_comment(bytes: &[u8]) -> bool {
memchr::memchr(b'/', bytes).is_some()
}
fn next_value_start(bytes: &[u8], mut pos: usize, starts_value: fn(u8) -> bool) -> Option<usize> {
loop {
let b = *bytes.get(pos)?;
if starts_value(b) {
return Some(pos);
}
pos = if b == b'/' && bytes.get(pos + 1) == Some(&b'*') {
crate::parser::skip_step_comment(bytes, pos)?
} else {
pos + 1
};
}
}
#[cold]
pub(super) fn parse_coordinates(bytes: &[u8]) -> Vec<f32> {
#[cfg(test)]
super::tests::mark_comment_aware_call();
let mut result = Vec::with_capacity(estimate_float_count(bytes));
let mut pos = 0;
while let Some(start) = next_value_start(bytes, pos, is_number_start) {
pos = start;
match fast_float2::parse_partial::<f32, _>(&bytes[pos..]) {
Ok((value, consumed)) if consumed > 0 => {
result.push(value);
pos += consumed;
}
_ => pos += 1,
}
}
result
}
#[cold]
pub(super) fn parse_coordinates_f64(bytes: &[u8]) -> Vec<f64> {
#[cfg(test)]
super::tests::mark_comment_aware_call();
let mut result = Vec::with_capacity(estimate_float_count(bytes));
let mut pos = 0;
while let Some(start) = next_value_start(bytes, pos, is_number_start) {
pos = start;
match fast_float2::parse_partial::<f64, _>(&bytes[pos..]) {
Ok((value, consumed)) if consumed > 0 => {
result.push(value);
pos += consumed;
}
_ => pos += 1,
}
}
result
}
#[cold]
pub(super) fn parse_indices(bytes: &[u8]) -> Vec<u32> {
#[cfg(test)]
super::tests::mark_comment_aware_call();
let mut result = Vec::with_capacity(estimate_int_count(bytes));
let mut pos = 0;
while let Some(start) = next_value_start(bytes, pos, |b| b.is_ascii_digit()) {
pos = start;
parse_index_value(bytes, &mut pos, &mut result);
}
result
}