зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1815987 - Rewrite data-read loop in OnDataAvailable r=yjuglaret
The read-loop in OnDataAvailable is needlessly baroque and uses a very strange dialect of Hungarian notation. Factor out the zero-element case for simplicity (of explication, if nothing else), and add justificatory comments as appropriate. Differential Revision: https://phabricator.services.mozilla.com/D171001
This commit is contained in:
Родитель
65ff891284
Коммит
68184463ff
|
@ -125,25 +125,49 @@ nsDataObj::CStream::OnDataAvailable(
|
||||||
uint64_t aOffset, // offset within the stream
|
uint64_t aOffset, // offset within the stream
|
||||||
uint32_t aCount) // bytes available on this call
|
uint32_t aCount) // bytes available on this call
|
||||||
{
|
{
|
||||||
|
// If we've been asked to read zero bytes, call `Read` once, just to ensure
|
||||||
|
// any side-effects take place, and return immediately.
|
||||||
|
if (aCount == 0) {
|
||||||
|
char buffer[1] = {0};
|
||||||
|
uint32_t bytesReadByCall = 0;
|
||||||
|
nsresult rv = aInputStream->Read(buffer, 0, &bytesReadByCall);
|
||||||
|
MOZ_ASSERT(bytesReadByCall == 0);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Extend the write buffer for the incoming data.
|
// Extend the write buffer for the incoming data.
|
||||||
uint8_t* buffer = mChannelData.AppendElements(aCount, fallible);
|
size_t oldLength = mChannelData.Length();
|
||||||
|
char* buffer =
|
||||||
|
reinterpret_cast<char*>(mChannelData.AppendElements(aCount, fallible));
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
NS_ASSERTION((mChannelData.Length() == (aOffset + aCount)),
|
MOZ_ASSERT(mChannelData.Length() == (aOffset + aCount),
|
||||||
"stream length mismatch w/write buffer");
|
"stream length mismatch w/write buffer");
|
||||||
|
|
||||||
// Read() may not return aCount on a single call, so loop until we've
|
// Read() may not return aCount on a single call, so loop until we've
|
||||||
// accumulated all the data OnDataAvailable has promised.
|
// accumulated all the data OnDataAvailable has promised.
|
||||||
nsresult rv;
|
uint32_t bytesRead = 0;
|
||||||
uint32_t odaBytesReadTotal = 0;
|
while (bytesRead < aCount) {
|
||||||
do {
|
|
||||||
uint32_t bytesReadByCall = 0;
|
uint32_t bytesReadByCall = 0;
|
||||||
rv = aInputStream->Read((char*)(buffer + odaBytesReadTotal), aCount,
|
nsresult rv = aInputStream->Read(buffer + bytesRead, aCount - bytesRead,
|
||||||
&bytesReadByCall);
|
&bytesReadByCall);
|
||||||
odaBytesReadTotal += bytesReadByCall;
|
bytesRead += bytesReadByCall;
|
||||||
} while (aCount < odaBytesReadTotal && NS_SUCCEEDED(rv));
|
|
||||||
return rv;
|
if (bytesReadByCall == 0) {
|
||||||
|
// A `bytesReadByCall` of zero indicates EOF without failure... but we
|
||||||
|
// were promised `aCount` elements and haven't gotten them. Return a
|
||||||
|
// generic failure.
|
||||||
|
rv = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
// Drop any trailing uninitialized elements before erroring out.
|
||||||
|
mChannelData.RemoveElementsAt(oldLength + bytesRead, aCount - bytesRead);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsDataObj::CStream::OnStartRequest(nsIRequest* aRequest) {
|
NS_IMETHODIMP nsDataObj::CStream::OnStartRequest(nsIRequest* aRequest) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче