Bug 1551981. Add an nsTArray version of NS_ConsumeStream. r=froydnj
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 15 May 2019 18:29:28 +0000
changeset 532805 03289d31269dd6a6bcf5adf9e236d4363a70f2ac
parent 532804 3300402f42393d2682e2143b886776df57c95abf
child 532806 cf653553acfad30ab9cc9c57b8f420768c98d997
push id11272
push userapavel@mozilla.com
push dateThu, 16 May 2019 15:28:22 +0000
treeherdermozilla-beta@2265bfc5920d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1551981
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1551981. Add an nsTArray version of NS_ConsumeStream. r=froydnj Differential Revision: https://phabricator.services.mozilla.com/D31299
xpcom/io/nsStreamUtils.cpp
xpcom/io/nsStreamUtils.h
--- a/xpcom/io/nsStreamUtils.cpp
+++ b/xpcom/io/nsStreamUtils.cpp
@@ -595,20 +595,44 @@ nsresult NS_AsyncCopy(nsIInputStream* aS
 nsresult NS_CancelAsyncCopy(nsISupports* aCopierCtx, nsresult aReason) {
   nsAStreamCopier* copier =
       static_cast<nsAStreamCopier*>(static_cast<nsIRunnable*>(aCopierCtx));
   return copier->Cancel(aReason);
 }
 
 //-----------------------------------------------------------------------------
 
-nsresult NS_ConsumeStream(nsIInputStream* aStream, uint32_t aMaxCount,
-                          nsACString& aResult) {
+namespace {
+template <typename T>
+struct ResultTraits {};
+
+template <>
+struct ResultTraits<nsACString> {
+  static void Clear(nsACString& aString) { aString.Truncate(); }
+
+  static char* GetStorage(nsACString& aString) {
+    return aString.BeginWriting();
+  }
+};
+
+template <>
+struct ResultTraits<nsTArray<uint8_t>> {
+  static void Clear(nsTArray<uint8_t>& aArray) { aArray.Clear(); }
+
+  static char* GetStorage(nsTArray<uint8_t>& aArray) {
+    return reinterpret_cast<char*>(aArray.Elements());
+  }
+};
+}  // namespace
+
+template <typename T>
+nsresult DoConsumeStream(nsIInputStream* aStream, uint32_t aMaxCount,
+                         T& aResult) {
   nsresult rv = NS_OK;
-  aResult.Truncate();
+  ResultTraits<T>::Clear(aResult);
 
   while (aMaxCount) {
     uint64_t avail64;
     rv = aStream->Available(&avail64);
     if (NS_FAILED(rv)) {
       if (rv == NS_BASE_STREAM_CLOSED) {
         rv = NS_OK;
       }
@@ -625,17 +649,17 @@ nsresult NS_ConsumeStream(nsIInputStream
     if (avail > UINT32_MAX - length) {
       return NS_ERROR_FILE_TOO_BIG;
     }
 
     aResult.SetLength(length + avail);
     if (aResult.Length() != (length + avail)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
-    char* buf = aResult.BeginWriting() + length;
+    char* buf = ResultTraits<T>::GetStorage(aResult) + length;
 
     uint32_t n;
     rv = aStream->Read(buf, avail, &n);
     if (NS_FAILED(rv)) {
       break;
     }
     if (n != avail) {
       aResult.SetLength(length + n);
@@ -644,16 +668,26 @@ nsresult NS_ConsumeStream(nsIInputStream
       break;
     }
     aMaxCount -= n;
   }
 
   return rv;
 }
 
+nsresult NS_ConsumeStream(nsIInputStream* aStream, uint32_t aMaxCount,
+                          nsACString& aResult) {
+  return DoConsumeStream(aStream, aMaxCount, aResult);
+}
+
+nsresult NS_ConsumeStream(nsIInputStream* aStream, uint32_t aMaxCount,
+                          nsTArray<uint8_t>& aResult) {
+  return DoConsumeStream(aStream, aMaxCount, aResult);
+}
+
 //-----------------------------------------------------------------------------
 
 static nsresult TestInputStream(nsIInputStream* aInStr, void* aClosure,
                                 const char* aBuffer, uint32_t aOffset,
                                 uint32_t aCount, uint32_t* aCountWritten) {
   bool* result = static_cast<bool*>(aClosure);
   *result = true;
   *aCountWritten = 0;
--- a/xpcom/io/nsStreamUtils.h
+++ b/xpcom/io/nsStreamUtils.h
@@ -121,16 +121,22 @@ extern nsresult NS_CancelAsyncCopy(nsISu
  *        The string object that will contain the stream data upon return.
  *        Note: The data copied to the string may contain null bytes and may
  *        contain non-ASCII values.
  */
 extern nsresult NS_ConsumeStream(nsIInputStream* aSource, uint32_t aMaxCount,
                                  nsACString& aBuffer);
 
 /**
+ * Just like the above, but consumes into an nsTArray<uint8_t>.
+ */
+extern nsresult NS_ConsumeStream(nsIInputStream* aSource, uint32_t aMaxCount,
+                                 nsTArray<uint8_t>& aBuffer);
+
+/**
  * This function tests whether or not the input stream is buffered. A buffered
  * input stream is one that implements readSegments.  The test for this is to
  * 1/ check whether the input stream implements nsIBufferedInputStream;
  * 2/ if not, call readSegments, without actually consuming any data from the
  * stream, to verify that it functions.
  *
  * NOTE: If the stream is non-blocking and has no data available yet, then this
  * test will fail.  In that case, we return false even though the test is not