Skip to content

Commit

Permalink
Add String::new_from_one_byte (denoland#654)
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Apr 2, 2021
1 parent 3a5ce45 commit d520fe8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 19 deletions.
51 changes: 32 additions & 19 deletions src/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
28 changes: 28 additions & 0 deletions src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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],
Expand All @@ -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<Local<'s, String>> {
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 }
Expand Down
9 changes: 9 additions & 0 deletions tests/test_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit d520fe8

Please sign in to comment.