diff --git a/dom/base/test/bug457746.sjs b/dom/base/test/bug457746.sjs index d014df2cee06..02135c0a5c23 100644 --- a/dom/base/test/bug457746.sjs +++ b/dom/base/test/bug457746.sjs @@ -6,6 +6,6 @@ function handleRequest(request, response) .createInstance(Components.interfaces.nsIBinaryOutputStream); bos.setOutputStream(response.bodyOutputStream); - bos.writeByteArray(body, body.length); + bos.writeByteArray(body); } diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index 1937ab223e11..13d490d29ac5 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -7,6 +7,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/BasicEvents.h" #include "mozilla/CheckedInt.h" +#include "mozilla/Span.h" #include "DataTransfer.h" @@ -1104,8 +1105,12 @@ already_AddRefed DataTransfer::GetTransferable( totalCustomLength = 0; continue; } - rv = stream->WriteBytes((const char*)type.get(), - formatLength.value()); + MOZ_ASSERT(formatLength.isValid() && + formatLength.value() == + type.Length() * sizeof(nsString::char_type), + "Why is formatLength off?"); + rv = stream->WriteBytes( + AsBytes(MakeSpan(type.BeginReading(), type.Length()))); if (NS_WARN_IF(NS_FAILED(rv))) { totalCustomLength = 0; continue; @@ -1115,7 +1120,13 @@ already_AddRefed DataTransfer::GetTransferable( totalCustomLength = 0; continue; } - rv = stream->WriteBytes((const char*)data.get(), lengthInBytes); + // XXXbz it's not obvious to me that lengthInBytes is the actual + // length of "data" if the variant contained an nsISupportsString + // as VTYPE_INTERFACE, say. We used lengthInBytes above for + // sizing, so just keep doing that. + rv = stream->WriteBytes(MakeSpan( + reinterpret_cast(data.BeginReading()), + lengthInBytes)); if (NS_WARN_IF(NS_FAILED(rv))) { totalCustomLength = 0; continue; diff --git a/dom/ipc/tests/blob_verify.sjs b/dom/ipc/tests/blob_verify.sjs index 62b82359e593..cf50371c8a95 100644 --- a/dom/ipc/tests/blob_verify.sjs +++ b/dom/ipc/tests/blob_verify.sjs @@ -15,6 +15,6 @@ function handleRequest(request, response) { var bos = new BinaryOutputStream(response.bodyOutputStream); response.processAsync(); - bos.writeByteArray(bodyBytes, bodyBytes.length); + bos.writeByteArray(bodyBytes); response.finish(); } diff --git a/dom/serviceworkers/test/fetch/deliver-gzip.sjs b/dom/serviceworkers/test/fetch/deliver-gzip.sjs index abacdd2adb8c..30c9e69ce7e1 100644 --- a/dom/serviceworkers/test/fetch/deliver-gzip.sjs +++ b/dom/serviceworkers/test/fetch/deliver-gzip.sjs @@ -13,5 +13,5 @@ function handleRequest(request, response) { .createInstance(Components.interfaces.nsIBinaryOutputStream); bos.setOutputStream(response.bodyOutputStream); - bos.writeByteArray(bytes, bytes.length); + bos.writeByteArray(bytes); } diff --git a/dom/xhr/tests/temporaryFileBlob.sjs b/dom/xhr/tests/temporaryFileBlob.sjs index ff3410c78c8a..814c06d1ed4e 100644 --- a/dom/xhr/tests/temporaryFileBlob.sjs +++ b/dom/xhr/tests/temporaryFileBlob.sjs @@ -21,10 +21,10 @@ function handleRequest(request, response) { response.processAsync(); var part = bodyBytes.splice(0, 256); - bos.writeByteArray(part, part.length); + bos.writeByteArray(part); response.timer1 = new Timer(function(timer) { - bos.writeByteArray(bodyBytes, bodyBytes.length); + bos.writeByteArray(bodyBytes); }, 1000, Components.interfaces.nsITimer.TYPE_ONE_SHOT); response.timer2 = new Timer(function(timer) { diff --git a/image/test/reftest/generic/check-header.sjs b/image/test/reftest/generic/check-header.sjs index 9e905bc1cf0d..afc39cb550b4 100644 --- a/image/test/reftest/generic/check-header.sjs +++ b/image/test/reftest/generic/check-header.sjs @@ -62,7 +62,7 @@ function handleRequest(request, response) response.setHeader("Content-Type", "image/png", false); var stream = new BinaryOutputStream(response.bodyOutputStream); - stream.writeByteArray(IMAGE_DATA, IMAGE_DATA.length); + stream.writeByteArray(IMAGE_DATA); } else { diff --git a/image/test/unit/test_imgtools.js b/image/test/unit/test_imgtools.js index eaab4b915ff9..89810d22b42d 100644 --- a/image/test/unit/test_imgtools.js +++ b/image/test/unit/test_imgtools.js @@ -25,7 +25,7 @@ function dumpToFile(aData) { ); bos.setOutputStream(outputStream); - bos.writeByteArray(aData, aData.length); + bos.writeByteArray(aData); outputStream.close(); } diff --git a/intl/uconv/tests/unit/test_charset_conversion.js b/intl/uconv/tests/unit/test_charset_conversion.js index e32656f9160f..2b800bfce470 100644 --- a/intl/uconv/tests/unit/test_charset_conversion.js +++ b/intl/uconv/tests/unit/test_charset_conversion.js @@ -89,7 +89,7 @@ function test_cross_conversion() while ((av = fin.available()) > 0) { var data = fin.readByteArray(av); - bos.writeByteArray(data, data.length); + bos.writeByteArray(data); } fin.close(); bos.close(); diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index b4bb8d1b4460..794d2066a171 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -973,7 +973,8 @@ static nsresult WriteScriptOrFunction(nsIObjectOutputStream* stream, } rv = stream->Write32(size); if (NS_SUCCEEDED(rv)) { - rv = stream->WriteBytes(reinterpret_cast(buffer.begin()), size); + // Ideally we could just pass "buffer" here. See bug 1566574. + rv = stream->WriteBytes(MakeSpan(buffer.begin(), size)); } return rv; diff --git a/layout/reftests/backgrounds/background-referrer.sjs b/layout/reftests/backgrounds/background-referrer.sjs index 7ead6e20efea..a00a71ebd844 100644 --- a/layout/reftests/backgrounds/background-referrer.sjs +++ b/layout/reftests/backgrounds/background-referrer.sjs @@ -62,7 +62,7 @@ function handleRequest(request, response) response.setHeader("Content-Type", "image/png", false); var stream = new BinaryOutputStream(response.bodyOutputStream); - stream.writeByteArray(IMAGE_DATA, IMAGE_DATA.length); + stream.writeByteArray(IMAGE_DATA); } else { diff --git a/layout/reftests/backgrounds/delay-image-response.sjs b/layout/reftests/backgrounds/delay-image-response.sjs index f3117f8d5452..418eaa24a976 100644 --- a/layout/reftests/backgrounds/delay-image-response.sjs +++ b/layout/reftests/backgrounds/delay-image-response.sjs @@ -43,7 +43,7 @@ function handleRequest(request, response) { function imageWrite() { var stream = new BinaryOutputStream(response.bodyOutputStream); - stream.writeByteArray(IMAGE_DATA, IMAGE_DATA.length); + stream.writeByteArray(IMAGE_DATA); } // If there is no delay, we write the image and leave. diff --git a/layout/reftests/font-face/bug-1481905-cancel-load.sjs b/layout/reftests/font-face/bug-1481905-cancel-load.sjs index 85f8b89fc8ba..69c650217719 100644 --- a/layout/reftests/font-face/bug-1481905-cancel-load.sjs +++ b/layout/reftests/font-face/bug-1481905-cancel-load.sjs @@ -205,7 +205,7 @@ function handleRequest(request, response) { function fontWrite(data) { var stream = new BinaryOutputStream(response.bodyOutputStream); - stream.writeByteArray(data, data.length); + stream.writeByteArray(data); } const nsITimer = Components.interfaces.nsITimer; diff --git a/layout/reftests/fonts/Chunkfive.sjs b/layout/reftests/fonts/Chunkfive.sjs index fe3077cc598d..fe09ccbe5fb7 100644 --- a/layout/reftests/fonts/Chunkfive.sjs +++ b/layout/reftests/fonts/Chunkfive.sjs @@ -19,7 +19,7 @@ function handleRequest(request, response) response.setHeader("Cache-Control", "no-cache", false); var stream = new BinaryOutputStream(response.bodyOutputStream); - stream.writeByteArray(FONT_DATA, FONT_DATA.length); + stream.writeByteArray(FONT_DATA); } /** diff --git a/layout/reftests/fonts/markfonts-delay.sjs b/layout/reftests/fonts/markfonts-delay.sjs index 574b1404dc21..1d3a43e47c22 100644 --- a/layout/reftests/fonts/markfonts-delay.sjs +++ b/layout/reftests/fonts/markfonts-delay.sjs @@ -37,7 +37,7 @@ function handleRequest(request, response) { function fontWrite(data) { var stream = new BinaryOutputStream(response.bodyOutputStream); - stream.writeByteArray(data, data.length); + stream.writeByteArray(data); } var f; diff --git a/layout/style/test/redundant_font_download.sjs b/layout/style/test/redundant_font_download.sjs index 7eb7d8f8df54..a28fc081d24d 100644 --- a/layout/style/test/redundant_font_download.sjs +++ b/layout/style/test/redundant_font_download.sjs @@ -39,11 +39,11 @@ function handleRequest(request, response) if (query["q"] == "init") { log = "init"; // initialize the log, and return a PNG image response.setHeader("Content-Type", "image/png", false); - stream.writeByteArray(RED_SQUARE, RED_SQUARE.length); + stream.writeByteArray(RED_SQUARE); } else if (query["q"] == "image") { log = log + ";" + query["q"]; response.setHeader("Content-Type", "image/png", false); - stream.writeByteArray(RED_SQUARE, RED_SQUARE.length); + stream.writeByteArray(RED_SQUARE); } else if (query["q"] == "font") { log = log + ";" + query["q"]; // we don't provide a real font; that's ok, OTS will just reject it diff --git a/netwerk/test/httpserver/httpd.js b/netwerk/test/httpserver/httpd.js index 777a99e0f41c..95f39cf604b6 100644 --- a/netwerk/test/httpserver/httpd.js +++ b/netwerk/test/httpserver/httpd.js @@ -1532,9 +1532,10 @@ RequestReader.prototype = { " excess=" + (data.length - count) ); + data.length = count; var bos = new BinaryOutputStream(this._metadata._bodyOutputStream); - bos.writeByteArray(data, count); + bos.writeByteArray(data); this._contentLength -= count; } @@ -2861,7 +2862,7 @@ ServerHandler.prototype = { ", expected " + chunkSize ); - output.writeByteArray(data, data.length); + output.writeByteArray(data); if (count === 0) { fis.close(); response.finish(); diff --git a/netwerk/test/httpserver/test/test_async_response_sending.js b/netwerk/test/httpserver/test/test_async_response_sending.js index 0013d2e9b54d..780f3e1a41a4 100644 --- a/netwerk/test/httpserver/test/test_async_response_sending.js +++ b/netwerk/test/httpserver/test/test_async_response_sending.js @@ -867,19 +867,9 @@ function CustomPipe(name) { // // see nsIBinaryOutputStream.writeByteArray // - writeByteArray: function writeByteArray(bytes, length) { - dumpn( - "*** [" + - this.name + - "].writeByteArray" + - "([" + - bytes + - "], " + - length + - ")" - ); + writeByteArray: function writeByteArray(bytes) { + dumpn(`*** [${this.name}].writeByteArray([${bytes}])`); - Assert.equal(bytes.length, length, "sanity"); if (!Components.isSuccessCode(self._status)) { throw self._status; } @@ -890,12 +880,12 @@ function CustomPipe(name) { "writeByteArray can't support specified-length writes" ); - if (this._writable < length) { + if (this._writable < bytes.length) { throw Cr.NS_BASE_STREAM_WOULD_BLOCK; } self._data.push.apply(self._data, bytes); - this._writable -= length; + this._writable -= bytes.length; if ( input._readable === Infinity && @@ -1164,7 +1154,7 @@ CopyTest.prototype = { try { self._copyableDataStream.makeWritable(bytes.length); - self._copyableDataStream.writeByteArray(bytes, bytes.length); + self._copyableDataStream.writeByteArray(bytes); } finally { self._stageNextTask(); } diff --git a/netwerk/test/httpserver/test/test_processasync.js b/netwerk/test/httpserver/test/test_processasync.js index 3effd1ec1570..33bc10069820 100644 --- a/netwerk/test/httpserver/test/test_processasync.js +++ b/netwerk/test/httpserver/test/test_processasync.js @@ -240,7 +240,7 @@ function handleAsyncOrdering(request, response) { } try { - out.writeByteArray(data, data.length); + out.writeByteArray(data); step(); } catch (e) { try { diff --git a/netwerk/test/unit/test_bug1279246.js b/netwerk/test/unit/test_bug1279246.js index c33f5c2e0970..b3742b1e2bd7 100644 --- a/netwerk/test/unit/test_bug1279246.js +++ b/netwerk/test/unit/test_bug1279246.js @@ -91,6 +91,6 @@ function handler(metadata, response) { bos.setOutputStream(response.bodyOutputStream); response.processAsync(); - bos.writeByteArray(responseBody, responseBody.length); + bos.writeByteArray(responseBody); response.finish(); } diff --git a/netwerk/test/unit/test_content_encoding_gzip.js b/netwerk/test/unit/test_content_encoding_gzip.js index cb4412ef817d..60e5838d6a4b 100644 --- a/netwerk/test/unit/test_content_encoding_gzip.js +++ b/netwerk/test/unit/test_content_encoding_gzip.js @@ -203,6 +203,6 @@ function handler(metadata, response) { bos.setOutputStream(response.bodyOutputStream); response.processAsync(); - bos.writeByteArray(tests[index].body, tests[index].body.length); + bos.writeByteArray(tests[index].body); response.finish(); } diff --git a/netwerk/test/unit/test_gzipped_206.js b/netwerk/test/unit/test_gzipped_206.js index a0f56a36e87c..0f7e2d266ee7 100644 --- a/netwerk/test/unit/test_gzipped_206.js +++ b/netwerk/test/unit/test_gzipped_206.js @@ -118,7 +118,7 @@ function cachedHandler(metadata, response) { bos.setOutputStream(response.bodyOutputStream); response.processAsync(); - bos.writeByteArray(body, body.length); + bos.writeByteArray(body); response.finish(); } diff --git a/netwerk/test/unit/test_range_requests.js b/netwerk/test/unit/test_range_requests.js index 8a6d9f9c7bef..6d8e36bc5944 100644 --- a/netwerk/test/unit/test_range_requests.js +++ b/netwerk/test/unit/test_range_requests.js @@ -261,7 +261,7 @@ function handler_4(metadata, response) { ); bos.setOutputStream(response.bodyOutputStream); response.processAsync(); - bos.writeByteArray(body, body.length); + bos.writeByteArray(body); response.finish(); break; case 1: diff --git a/netwerk/test/unit/test_reply_without_content_type.js b/netwerk/test/unit/test_reply_without_content_type.js index 4a99389e2819..2c48c16a8c89 100644 --- a/netwerk/test/unit/test_reply_without_content_type.js +++ b/netwerk/test/unit/test_reply_without_content_type.js @@ -129,7 +129,7 @@ function serverHandler_GZip(metadata, response) { Ci.nsIBinaryOutputStream ); bos.setOutputStream(response.bodyOutputStream); - bos.writeByteArray(httpbodyGZip, httpbodyGZip.length); + bos.writeByteArray(httpbodyGZip); if (dbg) { print("============== serverHandler GZip: out"); } diff --git a/security/manager/ssl/nsNSSCertificate.cpp b/security/manager/ssl/nsNSSCertificate.cpp index f09f456abe48..a82b78fe3591 100644 --- a/security/manager/ssl/nsNSSCertificate.cpp +++ b/security/manager/ssl/nsNSSCertificate.cpp @@ -13,6 +13,7 @@ #include "mozilla/Base64.h" #include "mozilla/Casting.h" #include "mozilla/NotNull.h" +#include "mozilla/Span.h" #include "mozilla/Unused.h" #include "nsArray.h" #include "nsCOMPtr.h" @@ -1194,7 +1195,7 @@ nsNSSCertificate::Write(nsIObjectOutputStream* aStream) { if (NS_FAILED(rv)) { return rv; } - return aStream->WriteByteArray(mCert->derCert.data, mCert->derCert.len); + return aStream->WriteBytes(AsBytes(MakeSpan(mCert->derCert.data, mCert->derCert.len))); } NS_IMETHODIMP diff --git a/toolkit/components/downloads/test/unit/common_test_Download.js b/toolkit/components/downloads/test/unit/common_test_Download.js index e88d571da988..6227a0abaf31 100644 --- a/toolkit/components/downloads/test/unit/common_test_Download.js +++ b/toolkit/components/downloads/test/unit/common_test_Download.js @@ -1809,10 +1809,7 @@ add_task(async function test_with_content_encoding() { ); let bos = new BinaryOutputStream(aResponse.bodyOutputStream); - bos.writeByteArray( - TEST_DATA_SHORT_GZIP_ENCODED, - TEST_DATA_SHORT_GZIP_ENCODED.length - ); + bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED); }); let download = await promiseStartDownload(sourceUrl); @@ -1849,10 +1846,7 @@ add_task(async function test_with_content_encoding_ignore_extension() { ); let bos = new BinaryOutputStream(aResponse.bodyOutputStream); - bos.writeByteArray( - TEST_DATA_SHORT_GZIP_ENCODED, - TEST_DATA_SHORT_GZIP_ENCODED.length - ); + bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED); }); let download = await promiseStartDownload(sourceUrl); diff --git a/toolkit/components/downloads/test/unit/head.js b/toolkit/components/downloads/test/unit/head.js index 42cdbb7549df..7cbc9b669283 100644 --- a/toolkit/components/downloads/test/unit/head.js +++ b/toolkit/components/downloads/test/unit/head.js @@ -870,17 +870,11 @@ add_task(function test_common_initialize() { ); let bos = new BinaryOutputStream(aResponse.bodyOutputStream); - bos.writeByteArray( - TEST_DATA_SHORT_GZIP_ENCODED_FIRST, - TEST_DATA_SHORT_GZIP_ENCODED_FIRST.length - ); + bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED_FIRST); }, function secondPart(aRequest, aResponse) { let bos = new BinaryOutputStream(aResponse.bodyOutputStream); - bos.writeByteArray( - TEST_DATA_SHORT_GZIP_ENCODED_SECOND, - TEST_DATA_SHORT_GZIP_ENCODED_SECOND.length - ); + bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED_SECOND); } ); diff --git a/toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js b/toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js index ce22947be611..1083c427dee8 100644 --- a/toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js +++ b/toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js @@ -111,7 +111,7 @@ function handler(metadata, response) { response.setHeader("Content-Type", "", false); var body = getFileContents(do_get_file(tests[testRan].path)); var bos = new BinaryOutputStream(response.bodyOutputStream); - bos.writeByteArray(body, body.length); + bos.writeByteArray(body); } function run_test() { diff --git a/toolkit/components/places/PageIconProtocolHandler.jsm b/toolkit/components/places/PageIconProtocolHandler.jsm index 9758a47fcf10..63bf446c51d0 100644 --- a/toolkit/components/places/PageIconProtocolHandler.jsm +++ b/toolkit/components/places/PageIconProtocolHandler.jsm @@ -49,13 +49,13 @@ function streamDefaultFavicon(uri, loadInfo, outputStream, originalChannel) { } } -function serveIcon(pipe, data, len) { +function serveIcon(pipe, data) { // Pass the icon data to the output stream. let stream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance( Ci.nsIBinaryOutputStream ); stream.setOutputStream(pipe.outputStream); - stream.writeByteArray(data, len); + stream.writeByteArray(data); stream.close(); pipe.outputStream.close(); } @@ -109,7 +109,10 @@ PageIconProtocolHandler.prototype = { try { channel.contentType = mimeType; channel.contentLength = len; - serveIcon(pipe, data, len); + if (len != data.length) { + throw new Error("Unexpected data length"); + } + serveIcon(pipe, data); } catch (ex) { streamDefaultFavicon(uri, loadInfo, pipe.outputStream, channel); } diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js b/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js index 22a0f75c5375..4dcae48ea138 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js @@ -48,7 +48,7 @@ function write_string_to_file(file, contents) { bos.setOutputStream(ostream); let utf8 = new TextEncoder("utf-8").encode(contents); - bos.writeByteArray(utf8, utf8.length); + bos.writeByteArray(utf8); ostream.QueryInterface(Ci.nsISafeOutputStream).finish(); ostream.close(); } diff --git a/xpcom/io/nsBinaryStream.cpp b/xpcom/io/nsBinaryStream.cpp index 2bf7cb36a93d..3995bda228b1 100644 --- a/xpcom/io/nsBinaryStream.cpp +++ b/xpcom/io/nsBinaryStream.cpp @@ -26,6 +26,7 @@ #include "mozilla/EndianUtils.h" #include "mozilla/PodOperations.h" #include "mozilla/RefPtr.h" +#include "mozilla/Span.h" #include "mozilla/UniquePtr.h" #include "nsCRT.h" @@ -41,8 +42,11 @@ #include "js/RootingAPI.h" // JS::{Handle,Rooted} #include "js/Value.h" // JS::Value +using mozilla::AsBytes; +using mozilla::MakeSpan; using mozilla::MakeUnique; using mozilla::PodCopy; +using mozilla::Span; using mozilla::UniquePtr; already_AddRefed NS_NewObjectOutputStream( @@ -206,11 +210,8 @@ nsBinaryOutputStream::WriteStringZ(const char* aString) { NS_IMETHODIMP nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) { - uint32_t length, byteCount; - nsresult rv; - - length = NS_strlen(aString); - rv = Write32(length); + uint32_t length = NS_strlen(aString); + nsresult rv = Write32(length); if (NS_FAILED(rv)) { return rv; } @@ -218,10 +219,9 @@ nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) { if (length == 0) { return NS_OK; } - byteCount = length * sizeof(char16_t); #ifdef IS_BIG_ENDIAN - rv = WriteBytes(reinterpret_cast(aString), byteCount); + rv = WriteBytes(AsBytes(MakeSpan(aString, length))); #else // XXX use WriteSegments here to avoid copy! char16_t* copy; @@ -229,14 +229,14 @@ nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) { if (length <= 64) { copy = temp; } else { - copy = reinterpret_cast(malloc(byteCount)); + copy = static_cast(malloc(length * sizeof(char16_t))); if (!copy) { return NS_ERROR_OUT_OF_MEMORY; } } NS_ASSERTION((uintptr_t(aString) & 0x1) == 0, "aString not properly aligned"); mozilla::NativeEndian::copyAndSwapToBigEndian(copy, aString, length); - rv = WriteBytes(reinterpret_cast(copy), byteCount); + rv = WriteBytes(AsBytes(MakeSpan(copy, length))); if (copy != temp) { free(copy); } @@ -250,24 +250,29 @@ nsBinaryOutputStream::WriteUtf8Z(const char16_t* aString) { return WriteStringZ(NS_ConvertUTF16toUTF8(aString).get()); } -NS_IMETHODIMP -nsBinaryOutputStream::WriteBytes(const char* aString, uint32_t aLength) { +nsresult nsBinaryOutputStream::WriteBytes(Span aBytes) { nsresult rv; uint32_t bytesWritten; - rv = Write(aString, aLength, &bytesWritten); + rv = Write(reinterpret_cast(aBytes.Elements()), aBytes.Length(), + &bytesWritten); if (NS_FAILED(rv)) { return rv; } - if (bytesWritten != aLength) { + if (bytesWritten != aBytes.Length()) { return NS_ERROR_FAILURE; } return rv; } NS_IMETHODIMP -nsBinaryOutputStream::WriteByteArray(uint8_t* aBytes, uint32_t aLength) { - return WriteBytes(reinterpret_cast(aBytes), aLength); +nsBinaryOutputStream::WriteBytesFromJS(const char* aString, uint32_t aLength) { + return WriteBytes(AsBytes(MakeSpan(aString, aLength))); +} + +NS_IMETHODIMP +nsBinaryOutputStream::WriteByteArray(const nsTArray& aByteArray) { + return WriteBytes(aByteArray); } NS_IMETHODIMP @@ -340,7 +345,7 @@ nsBinaryOutputStream::WriteID(const nsIID& aIID) { return rv; } - rv = WriteBytes(reinterpret_cast(&aIID.m3[0]), sizeof(aIID.m3)); + rv = WriteBytes(aIID.m3); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/xpcom/io/nsIBinaryOutputStream.idl b/xpcom/io/nsIBinaryOutputStream.idl index 4081f51fb365..ae9c5062f1ef 100644 --- a/xpcom/io/nsIBinaryOutputStream.idl +++ b/xpcom/io/nsIBinaryOutputStream.idl @@ -5,6 +5,13 @@ #include "nsIOutputStream.idl" +%{C++ +namespace mozilla { +template class Span; +} +%} +native Bytes(mozilla::Span); + /** * This interface allows writing of primitive data types (integers, * floating-point values, booleans, etc.) to a stream in a binary, untagged, @@ -55,15 +62,20 @@ interface nsIBinaryOutputStream : nsIOutputStream { /** * Write an opaque byte array to the stream. */ + [binaryname(WriteBytesFromJS)] void writeBytes([size_is(aLength)] in string aString, [optional] in uint32_t aLength); + /** + * Non-scriptable and saner-signature version of the same. + */ + [noscript, nostdcall, binaryname(WriteBytes)] + void writeBytesNative(in Bytes aBytes); + /** * Write an opaque byte array to the stream. */ - void writeByteArray([array, size_is(aLength)] in uint8_t aBytes, - [optional] in uint32_t aLength); - + void writeByteArray(in Array aBytes); }; %{C++ diff --git a/xpcom/tests/unit/test_storagestream.js b/xpcom/tests/unit/test_storagestream.js index 95e0c7f4fc45..2a0fb1b5696d 100644 --- a/xpcom/tests/unit/test_storagestream.js +++ b/xpcom/tests/unit/test_storagestream.js @@ -117,7 +117,7 @@ function test4() { ); bos.setOutputStream(outStream); - bos.writeByteArray(bytes, bytes.length); + bos.writeByteArray(bytes); bos.close(); var inp = ss.newInputStream(0); diff --git a/xpcom/tests/unit/test_streams.js b/xpcom/tests/unit/test_streams.js index 6ec1c8dd6323..212b41cc8ebc 100644 --- a/xpcom/tests/unit/test_streams.js +++ b/xpcom/tests/unit/test_streams.js @@ -67,13 +67,13 @@ function test_binary_streams() { Assert.equal(msg, HelloStr); msg = null; countObj.value = -1; - os.writeByteArray(HelloArray, HelloArray.length); + os.writeByteArray(HelloArray); Assert.equal(is.available(), HelloStr.length); msg = is.readByteArray(HelloStr.length); Assert.equal(typeof msg, typeof HelloArray); Assert.equal(msg.toSource(), HelloArray.toSource()); Assert.equal(is.available(), 0); - os.writeByteArray(HelloArray, HelloArray.length); + os.writeByteArray(HelloArray); Assert.equal( is.readArrayBuffer(buffer.byteLength, buffer), HelloArray.length @@ -96,7 +96,7 @@ function test_binary_streams() { os.writeStringZ("Mozilla"); os.writeWStringZ("Gecko"); os.writeBytes(HelloStr, HelloStr.length); - os.writeByteArray(HelloArray, HelloArray.length); + os.writeByteArray(HelloArray); // Available should not be zero after a long write like this. Assert.notEqual(is.available(), 0);