From d520fe85bdf428259b7187b09863baabad7bc314 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 2 Apr 2021 16:23:05 -0400 Subject: [PATCH] Add String::new_from_one_byte (#654) --- src/binding.cc | 51 +++++++++++++++++++++++++++++------------------ src/string.rs | 28 ++++++++++++++++++++++++++ tests/test_api.rs | 9 +++++++++ 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 3298734c..e5cd2505 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -828,6 +828,14 @@ const v8::String* v8__String__NewFromUtf8(v8::Isolate* isolate, v8::String::NewFromUtf8(isolate, data, new_type, length)); } +const v8::String* v8__String__NewFromOneByte(v8::Isolate* isolate, + const uint8_t* data, + v8::NewStringType new_type, + int length) { + return maybe_local_to_ptr( + v8::String::NewFromOneByte(isolate, data, new_type, length)); +} + int v8__String__Length(const v8::String& self) { return self.Length(); } int v8__String__Utf8Length(const v8::String& self, v8::Isolate* isolate) { @@ -840,30 +848,35 @@ int v8__String__WriteUtf8(const v8::String& self, v8::Isolate* isolate, return self.WriteUtf8(isolate, buffer, length, nchars_ref, options); } -class ExternalStaticOneByteStringResource: public v8::String::ExternalOneByteStringResource { - public: - ExternalStaticOneByteStringResource(const char *data, int length): - _data(data), _length(length) {} - const char* data() const override { return _data; } - size_t length() const override { return _length; } +class ExternalStaticOneByteStringResource + : public v8::String::ExternalOneByteStringResource { + public: + ExternalStaticOneByteStringResource(const char* data, int length) + : _data(data), _length(length) {} + const char* data() const override { return _data; } + size_t length() const override { return _length; } - private: - const char* _data; - const int _length; + private: + const char* _data; + const int _length; }; -const v8::String* v8__String__NewExternalOneByteStatic(v8::Isolate *isolate, - const char *data, int length) { - return maybe_local_to_ptr( - v8::String::NewExternalOneByte( - isolate, new ExternalStaticOneByteStringResource(data, length) - ) - ); +const v8::String* v8__String__NewExternalOneByteStatic(v8::Isolate* isolate, + const char* data, + int length) { + return maybe_local_to_ptr(v8::String::NewExternalOneByte( + isolate, new ExternalStaticOneByteStringResource(data, length))); } -bool v8__String__IsExternal(const v8::String& self) { return self.IsExternal(); } -bool v8__String__IsExternalOneByte(const v8::String& self) { return self.IsExternalOneByte(); } -bool v8__String__IsExternalTwoByte(const v8::String& self) { return self.IsExternalTwoByte(); } +bool v8__String__IsExternal(const v8::String& self) { + return self.IsExternal(); +} +bool v8__String__IsExternalOneByte(const v8::String& self) { + return self.IsExternalOneByte(); +} +bool v8__String__IsExternalTwoByte(const v8::String& self) { + return self.IsExternalTwoByte(); +} bool v8__String__IsOneByte(const v8::String& self) { return self.IsOneByte(); } const v8::Symbol* v8__Symbol__New(v8::Isolate* isolate, diff --git a/src/string.rs b/src/string.rs index 2ca96f2b..30a07615 100644 --- a/src/string.rs +++ b/src/string.rs @@ -20,6 +20,13 @@ extern "C" { length: int, ) -> *const String; + fn v8__String__NewFromOneByte( + isolate: *mut Isolate, + data: *const u8, + new_type: NewStringType, + length: int, + ) -> *const String; + fn v8__String__Length(this: *const String) -> int; fn v8__String__Utf8Length(this: *const String, isolate: *mut Isolate) -> int; @@ -81,6 +88,8 @@ impl String { .unwrap() } + /// Allocates a new string from UTF-8 data. Only returns an empty value when + /// length > kMaxLength pub fn new_from_utf8<'s>( scope: &mut HandleScope<'s, ()>, buffer: &[u8], @@ -102,6 +111,25 @@ impl String { } } + /// Allocates a new string from Latin-1 data. Only returns an empty value when + /// length > kMaxLength. + pub fn new_from_one_byte<'s>( + scope: &mut HandleScope<'s, ()>, + buffer: &[u8], + new_type: NewStringType, + ) -> Option> { + unsafe { + scope.cast_local(|sd| { + v8__String__NewFromOneByte( + sd.get_isolate_ptr(), + buffer.as_ptr(), + new_type, + buffer.len() as int, + ) + }) + } + } + /// Returns the number of characters (UTF-16 code units) in this string. pub fn length(&self) -> usize { unsafe { v8__String__Length(self) as usize } diff --git a/tests/test_api.rs b/tests/test_api.rs index ec09dd60..3897fbdf 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -177,6 +177,15 @@ fn test_string() { assert_eq!(0, local.utf8_length(scope)); assert_eq!("", local.to_rust_string_lossy(scope)); } + { + let scope = &mut v8::HandleScope::new(isolate); + let local = + v8::String::new_from_one_byte(scope, b"foo", v8::NewStringType::Normal) + .unwrap(); + assert_eq!(3, local.length()); + assert_eq!(3, local.utf8_length(scope)); + assert_eq!("foo", local.to_rust_string_lossy(scope)); + } } #[test]