Skip to content

Commit

Permalink
Bug 1514664 - Implement TextEncoder.encodeInto(). r=emk.
Browse files Browse the repository at this point in the history
  • Loading branch information
hsivonen committed Jan 11, 2019
1 parent f3c496f commit 2daf725
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
11 changes: 11 additions & 0 deletions dom/encoding/TextEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ void TextEncoder::Encode(JSContext* aCx, JS::Handle<JSObject*> aObj,
aRetval.set(outView);
}

void TextEncoder::EncodeInto(const nsAString& aSrc, const Uint8Array& aDst,
TextEncoderEncodeIntoResult& aResult) {
aDst.ComputeLengthAndData();
size_t read;
size_t written;
Tie(read, written) = ConvertUTF16toUTF8Partial(
aSrc, MakeSpan(reinterpret_cast<char*>(aDst.Data()), aDst.Length()));
aResult.mRead.Construct() = read;
aResult.mWritten.Construct() = written;
}

void TextEncoder::GetEncoding(nsAString& aEncoding) {
aEncoding.AssignLiteral("utf-8");
}
Expand Down
3 changes: 3 additions & 0 deletions dom/encoding/TextEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class TextEncoder final : public NonRefcountedDOMObject {
void Encode(JSContext* aCx, JS::Handle<JSObject*> aObj,
const nsAString& aString, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);

void EncodeInto(const nsAString& aSrc, const Uint8Array& aDst,
TextEncoderEncodeIntoResult& aResult);
};

} // namespace dom
Expand Down
10 changes: 10 additions & 0 deletions dom/webidl/TextEncoder.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/

dictionary TextEncoderEncodeIntoResult {
unsigned long long read;
unsigned long long written;
};

[Constructor, Exposed=(Window,Worker)]
interface TextEncoder {
[Constant]
Expand All @@ -24,4 +29,9 @@ interface TextEncoder {
*/
[NewObject]
Uint8Array encode(optional DOMString input = "");

/*
* The same comment about USVString as above applies here.
*/
TextEncoderEncodeIntoResult encodeInto(DOMString source, Uint8Array destination);
};
15 changes: 15 additions & 0 deletions intl/encoding_glue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,21 @@ pub unsafe extern "C" fn encoding_mem_convert_utf16_to_utf8(
)
}

#[no_mangle]
pub unsafe extern "C" fn encoding_mem_convert_utf16_to_utf8_partial(
src: *const u16,
src_len: *mut usize,
dst: *mut u8,
dst_len: *mut usize,
) {
let (read, written) = encoding_rs::mem::convert_utf16_to_utf8_partial(
::std::slice::from_raw_parts(src, *src_len),
::std::slice::from_raw_parts_mut(dst, *dst_len),
);
*src_len = read;
*dst_len = written;
}

#[no_mangle]
pub unsafe extern "C" fn encoding_mem_convert_utf8_to_utf16(
src: *const u8,
Expand Down
26 changes: 26 additions & 0 deletions xpcom/string/nsReadableUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "mozilla/Assertions.h"
#include "nsAString.h"
#include "mozilla/Tuple.h"

#include "nsTArrayForwardDeclare.h"

Expand Down Expand Up @@ -52,6 +53,10 @@ void encoding_mem_convert_latin1_to_utf16(const char* src, size_t src_len,
size_t encoding_mem_convert_utf16_to_utf8(const char16_t* src, size_t src_len,
char* dst, size_t dst_len);

void encoding_mem_convert_utf16_to_utf8_partial(const char16_t* src,
size_t* src_len, char* dst,
size_t* dst_len);

size_t encoding_mem_convert_utf8_to_utf16(const char* src, size_t src_len,
char16_t* dst, size_t dst_len);
}
Expand Down Expand Up @@ -139,6 +144,27 @@ inline size_t ConvertUTF16toUTF8(mozilla::Span<const char16_t> aSource,
aSource.Elements(), aSource.Length(), aDest.Elements(), aDest.Length());
}

/**
* Lone surrogates are replaced with the REPLACEMENT CHARACTER.
*
* The conversion is guaranteed to be complete if the length of aDest is
* at least the length of aSource times three.
*
* The output is always valid UTF-8 ending on scalar value boundary
* even in the case of partial conversion.
*
* Returns the number of code units read and the number of code
* units written.
*/
inline mozilla::Tuple<size_t, size_t> ConvertUTF16toUTF8Partial(
mozilla::Span<const char16_t> aSource, mozilla::Span<char> aDest) {
size_t srcLen = aSource.Length();
size_t dstLen = aDest.Length();
encoding_mem_convert_utf16_to_utf8_partial(aSource.Elements(), &srcLen,
aDest.Elements(), &dstLen);
return mozilla::MakeTuple(srcLen, dstLen);
}

/**
* Malformed byte sequences are replaced with the REPLACEMENT CHARACTER.
*
Expand Down

0 comments on commit 2daf725

Please sign in to comment.