mirror of
https://github.com/oven-sh/bun
synced 2026-02-14 21:01:52 +00:00
Most of Buffer.toString
This commit is contained in:
@@ -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> {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user