properly iterate through UTF-8 strings (#350)
This commit is contained in:
@@ -48,13 +48,15 @@ fn scan_for_terminator<Iter: Iterator<Item = char>>(iter: Iter) -> usize {
|
|||||||
|
|
||||||
pub struct PStrIter {
|
pub struct PStrIter {
|
||||||
buf: *const u8,
|
buf: *const u8,
|
||||||
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PStrIter {
|
impl PStrIter {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(buf: *const u8, idx: usize) -> Self {
|
fn from(buf: *const u8, len: usize, idx: usize) -> Self {
|
||||||
PStrIter {
|
PStrIter {
|
||||||
buf: (buf as usize + idx) as *const _
|
buf: (buf as usize + idx) as *const _,
|
||||||
|
len: len - idx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,27 +66,13 @@ impl Iterator for PStrIter {
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut byte_count = 0;
|
let slice = slice::from_raw_parts(self.buf, self.len);
|
||||||
|
|
||||||
for n in 0 .. mem::size_of::<char>() {
|
|
||||||
let b = ptr::read((self.buf as usize + n) as *const u8);
|
|
||||||
|
|
||||||
if b == 0u8 {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
byte_count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if byte_count == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let slice = slice::from_raw_parts(self.buf, byte_count);
|
|
||||||
let s = str::from_utf8(slice).unwrap();
|
let s = str::from_utf8(slice).unwrap();
|
||||||
|
|
||||||
if let Some(c) = s.chars().next() {
|
if let Some(c) = s.chars().next() {
|
||||||
self.buf = self.buf.offset(c.len_utf8() as isize);
|
self.buf = self.buf.offset(c.len_utf8() as isize);
|
||||||
|
self.len -= c.len_utf8();
|
||||||
|
|
||||||
Some(c)
|
Some(c)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -212,7 +200,7 @@ impl PartialString {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn range_from(&self, index: RangeFrom<usize>) -> PStrIter {
|
pub fn range_from(&self, index: RangeFrom<usize>) -> PStrIter {
|
||||||
PStrIter::from(self.buf, index.start)
|
PStrIter::from(self.buf, self.len, index.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
Reference in New Issue
Block a user