Split blob write into write_utf8 and write_ascii.

This commit is contained in:
Stephen Chung 2021-12-31 17:49:38 +08:00
parent ce93f56813
commit f3a8364936
2 changed files with 62 additions and 11 deletions

View File

@ -645,8 +645,8 @@ pub mod blob_functions {
pub fn write_be_float(blob: &mut Blob, start: INT, len: INT, value: FLOAT) { pub fn write_be_float(blob: &mut Blob, start: INT, len: INT, value: FLOAT) {
write_float(blob, start, len, value, false) write_float(blob, start, len, value, false)
} }
#[rhai_fn(name = "write")] #[inline]
pub fn write_string(blob: &mut Blob, start: INT, len: INT, string: &str) { fn write_string(blob: &mut Blob, start: INT, len: INT, string: &str, ascii_only: bool) {
if len <= 0 || blob.is_empty() || string.is_empty() { if len <= 0 || blob.is_empty() || string.is_empty() {
return; return;
} }
@ -670,18 +670,52 @@ pub mod blob_functions {
let len = usize::min(len, string.len()); let len = usize::min(len, string.len());
blob[start..][..len].copy_from_slice(string[..len].as_bytes()); if ascii_only {
string
.chars()
.filter(char::is_ascii)
.take(len)
.map(|ch| ch as u8)
.enumerate()
.for_each(|(i, x)| blob[start + i] = x);
} else {
blob[start..][..len].copy_from_slice(&string.as_bytes()[..len]);
} }
#[rhai_fn(name = "write")] }
pub fn write_string_range(blob: &mut Blob, range: ExclusiveRange, string: &str) { #[rhai_fn(name = "write_utf8")]
pub fn write_utf8_string(blob: &mut Blob, start: INT, len: INT, string: &str) {
write_string(blob, start, len, string, false)
}
#[rhai_fn(name = "write_utf8")]
pub fn write_utf8_string_range(blob: &mut Blob, range: ExclusiveRange, string: &str) {
let start = INT::max(range.start, 0); let start = INT::max(range.start, 0);
let end = INT::max(range.end, start); let end = INT::max(range.end, start);
write_string(blob, start, end - start, string) write_string(blob, start, end - start, string, false)
} }
#[rhai_fn(name = "write")] #[rhai_fn(name = "write_utf8")]
pub fn write_string_range_inclusive(blob: &mut Blob, range: InclusiveRange, string: &str) { pub fn write_utf8_string_range_inclusive(blob: &mut Blob, range: InclusiveRange, string: &str) {
let start = INT::max(*range.start(), 0); let start = INT::max(*range.start(), 0);
let end = INT::max(*range.end(), start); let end = INT::max(*range.end(), start);
write_string(blob, start, end - start + 1, string) write_string(blob, start, end - start + 1, string, false)
}
#[rhai_fn(name = "write_ascii")]
pub fn write_ascii_string(blob: &mut Blob, start: INT, len: INT, string: &str) {
write_string(blob, start, len, string, true)
}
#[rhai_fn(name = "write_ascii")]
pub fn write_ascii_string_range(blob: &mut Blob, range: ExclusiveRange, string: &str) {
let start = INT::max(range.start, 0);
let end = INT::max(range.end, start);
write_string(blob, start, end - start, string, true)
}
#[rhai_fn(name = "write_ascii")]
pub fn write_ascii_string_range_inclusive(
blob: &mut Blob,
range: InclusiveRange,
string: &str,
) {
let start = INT::max(*range.start(), 0);
let end = INT::max(*range.end(), start);
write_string(blob, start, end - start + 1, string, true)
} }
} }

View File

@ -170,15 +170,32 @@ fn test_blobs_parse() -> Result<(), Box<EvalAltResult>> {
); );
assert_eq!( assert_eq!(
engine.eval::<Blob>(r#"let x = blob(16, 0); write(x, 0, 14, "hello, world!"); x"#)?, engine.eval::<Blob>(r#"let x = blob(16, 0); write_ascii(x, 0, 14, "hello, world!"); x"#)?,
"hello, world!\0\0\0".as_bytes() "hello, world!\0\0\0".as_bytes()
); );
assert_eq!( assert_eq!(
engine.eval::<Blob>(r#"let x = blob(10, 0); write(x, 3, 5, "hello, world!"); x"#)?, engine.eval::<Blob>(r#"let x = blob(10, 0); write_ascii(x, 3..8, "hello, world!"); x"#)?,
"\0\0\0hello\0\0".as_bytes() "\0\0\0hello\0\0".as_bytes()
); );
assert_eq!(
engine.eval::<Blob>(
r#"let x = blob(10, 0); write_ascii(x, 0..9, "❤ hello, ❤ world! ❤❤❤"); x"#
)?,
" hello, \0".as_bytes()
);
assert_eq!(
engine.eval::<Blob>(r#"let x = blob(10, 0); write_utf8(x, 3..9, "❤❤❤❤"); x"#)?,
"\0\0\0\u{2764}\u{2764}\0".as_bytes()
);
assert_eq!(
engine.eval::<Blob>(r#"let x = blob(10, 0); write_utf8(x, 3..7, "❤❤❤❤"); x"#)?,
vec![0, 0, 0, 226, 157, 164, 226, 0, 0, 0]
);
Ok(()) Ok(())
} }