Most of Buffer.toString

This commit is contained in:
Jarred Sumner
2022-04-26 01:12:28 -07:00
parent 6590d1f8bf
commit 77fbfb3fbb
10 changed files with 288 additions and 11 deletions

View File

@@ -10,6 +10,14 @@
#include "BufferEncodingType.h"
#include "JavaScriptCore/GenericTypedArrayView.h"
extern "C" JSC__JSValue Bun__encoding__toStringUTF16(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
extern "C" JSC__JSValue Bun__encoding__toStringUTF8(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
extern "C" JSC__JSValue Bun__encoding__toStringASCII(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
extern "C" JSC__JSValue Bun__encoding__toStringLatin1(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
extern "C" JSC__JSValue Bun__encoding__toStringHex(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
extern "C" JSC__JSValue Bun__encoding__toStringBase64(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
extern "C" JSC__JSValue Bun__encoding__toStringURLSafeBase64(const uint8_t* input, size_t len, JSC__JSGlobalObject* globalObject);
namespace WebCore {
class Buffer final : public RefCounted<Buffer> {

View File

@@ -568,7 +568,107 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap64Body(JSC::JSGl
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
return JSC::JSValue::encode(jsUndefined());
uint32_t offset = 0;
uint32_t length = castedThis->length();
WebCore::BufferEncodingType encoding = WebCore::BufferEncodingType::utf8;
if (length == 0)
return JSC::JSValue::encode(JSC::jsEmptyString(vm));
auto scope = DECLARE_THROW_SCOPE(vm);
switch (callFrame->argumentCount()) {
case 0: {
break;
}
case 2:
case 3:
case 1: {
JSC::JSValue arg1 = callFrame->uncheckedArgument(0);
std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg1);
if (!encoded) {
throwTypeError(lexicalGlobalObject, scope, "Invalid encoding");
return JSC::JSValue::encode(jsUndefined());
}
encoding = encoded.value();
if (callFrame->argumentCount() == 1)
break;
}
// any
case 5: {
JSC::JSValue arg2 = callFrame->uncheckedArgument(1);
int32_t ioffset = arg2.toInt32(lexicalGlobalObject);
if (ioffset < 0) {
throwTypeError(lexicalGlobalObject, scope, "Offset must be a positive integer");
return JSC::JSValue::encode(jsUndefined());
}
offset = static_cast<uint32_t>(ioffset);
if (callFrame->argumentCount() == 2)
break;
}
default: {
length = static_cast<uint32_t>(callFrame->argument(2).toInt32(lexicalGlobalObject));
break;
}
}
length -= std::min(offset, length);
if (UNLIKELY(length == 0)) {
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsEmptyString(vm)));
}
JSC::EncodedJSValue ret = 0;
switch (encoding) {
case WebCore::BufferEncodingType::buffer:
case WebCore::BufferEncodingType::utf8: {
ret = Bun__encoding__toStringUTF8(castedThis->typedVector() + offset, length, lexicalGlobalObject);
break;
}
case WebCore::BufferEncodingType::latin1:
case WebCore::BufferEncodingType::ascii: {
ret = Bun__encoding__toStringASCII(castedThis->typedVector() + offset, length, lexicalGlobalObject);
break;
}
case WebCore::BufferEncodingType::ucs2:
case WebCore::BufferEncodingType::utf16le: {
ret = Bun__encoding__toStringUTF16(castedThis->typedVector() + offset, length, lexicalGlobalObject);
break;
}
case WebCore::BufferEncodingType::base64: {
ret = Bun__encoding__toStringBase64(castedThis->typedVector() + offset, length, lexicalGlobalObject);
break;
}
case WebCore::BufferEncodingType::base64url: {
ret = Bun__encoding__toStringURLSafeBase64(castedThis->typedVector() + offset, length, lexicalGlobalObject);
break;
}
case WebCore::BufferEncodingType::hex: {
ret = Bun__encoding__toStringHex(castedThis->typedVector() + offset, length, lexicalGlobalObject);
break;
}
default: {
throwTypeError(lexicalGlobalObject, scope, "Unsupported encoding? This shouldn't happen");
break;
}
}
JSC::JSValue retValue = JSC::JSValue::decode(ret);
if (UNLIKELY(!retValue.isString())) {
scope.throwException(lexicalGlobalObject, retValue);
return JSC::JSValue::encode(jsUndefined());
}
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(retValue));
}
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis)
{

View File

@@ -3463,6 +3463,7 @@ pub const StringView = extern struct {
pub const WTF = struct {
extern fn WTF__copyLCharsFromUCharSource(dest: [*]u8, source: *const anyopaque, len: usize) void;
extern fn WTF__toBase64URLStringValue(bytes: [*]const u8, length: usize, globalObject: *JSGlobalObject) JSValue;
/// This uses SSE2 instructions and/or ARM NEON to copy 16-bit characters efficiently
/// See wtf/Text/ASCIIFastPath.h for details
@@ -3472,6 +3473,12 @@ pub const WTF = struct {
// This is any alignment
WTF__copyLCharsFromUCharSource(destination, source.ptr, source.len);
}
/// Encode a byte array to a URL-safe base64 string for use with JS
/// Memory is managed by JavaScriptCore instead of us
pub fn toBase64URLStringValue(bytes: []const u8, globalObject: *JSGlobalObject) JSValue {
return WTF__toBase64URLStringValue(bytes.ptr, bytes.len, globalObject);
}
};
pub const Callback = struct {

View File

@@ -217,4 +217,5 @@ extern "C" int64_t Bun__encoding__writeLatin1AsUTF8(const unsigned char* ptr, si
extern "C" int64_t Bun__encoding__writeUTF16AsUTF8(const UChar* ptr, size_t len, unsigned char* to, size_t other_len);
extern "C" int64_t Bun__encoding__writeLatin1AsASCII(const unsigned char* ptr, size_t len, unsigned char* to, size_t other_len);
extern "C" int64_t Bun__encoding__writeUTF16AsASCII(const UChar* ptr, size_t len, unsigned char* to, size_t other_len);
#endif

View File

@@ -1,6 +1,14 @@
#include "wtf-bindings.h"
#include "wtf/text/Base64.h"
extern "C" void WTF__copyLCharsFromUCharSource(LChar* destination, const UChar* source, size_t length)
{
WTF::copyLCharsFromUCharSource(destination, source, length);
}
extern "C" JSC::EncodedJSValue WTF__toBase64URLStringValue(const uint8_t* bytes, size_t length, JSC::JSGlobalObject* globalObject)
{
WTF::String string = WTF::base64URLEncodeToString(reinterpret_cast<const LChar*>(bytes), static_cast<unsigned int>(length));
string.impl()->ref();
return JSC::JSValue::encode(JSC::jsString(globalObject->vm(), string.impl()));
}

View File

@@ -3,4 +3,5 @@
#include "root.h"
#include "wtf/text/ASCIIFastPath.h"
extern "C" void WTF__copyLCharsFromUCharSource(LChar* destination, const UChar* source, size_t length);
extern "C" void WTF__copyLCharsFromUCharSource(LChar* destination, const UChar* source, size_t length);
extern "C" JSC::EncodedJSValue WTF__toBase64URLStringValue(const uint8_t* bytes, size_t length, JSC::JSGlobalObject* globalObject);