зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1636823 - nsMultiplexInputStream should not be blocking and nsIAsyncInputStream at the same time - part 4 - support Seek(END) correctly, r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D77100
This commit is contained in:
Родитель
8c01ca65b0
Коммит
acd3fa5467
|
@ -701,76 +701,61 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset) {
|
|||
if (aOffset > 0) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
int64_t remaining = aOffset;
|
||||
for (uint32_t i = mStreams.Length() - 1; i != (uint32_t)-1; --i) {
|
||||
int32_t i;
|
||||
for (i = mStreams.Length() - 1; i >= 0; --i) {
|
||||
nsCOMPtr<nsISeekableStream> stream = mStreams[i].mSeekableStream;
|
||||
|
||||
// See if all remaining streams should be seeked to end
|
||||
if (remaining == 0) {
|
||||
if (i >= oldCurrentStream) {
|
||||
uint64_t avail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = stream->Seek(NS_SEEK_END, 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mStreams[i].mCurrentPos += avail;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
uint64_t avail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get position in current stream
|
||||
int64_t streamPos;
|
||||
if (i < oldCurrentStream) {
|
||||
streamPos = 0;
|
||||
} else {
|
||||
streamPos = mStreams[i].mCurrentPos;
|
||||
}
|
||||
int64_t streamLength = avail + mStreams[i].mCurrentPos;
|
||||
|
||||
// See if we have enough data in the current stream.
|
||||
if (DeprecatedAbs(remaining) < streamPos) {
|
||||
// The seek(END) can be completed in the current stream.
|
||||
if (streamLength >= DeprecatedAbs(remaining)) {
|
||||
rv = stream->Seek(NS_SEEK_END, remaining);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// remaining is negative.
|
||||
mStreams[i].mCurrentPos = streamPos + remaining;
|
||||
mStreams[i].mCurrentPos = streamLength + remaining;
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = true;
|
||||
|
||||
remaining = 0;
|
||||
} else if (DeprecatedAbs(remaining) > streamPos) {
|
||||
if (i > oldCurrentStream ||
|
||||
(i == oldCurrentStream && !oldStartedReadingCurrent)) {
|
||||
// We're already at start so no need to seek this stream
|
||||
remaining += streamPos;
|
||||
} else {
|
||||
int64_t diff =
|
||||
XPCOM_MIN((int64_t)streamPos, DeprecatedAbs(remaining));
|
||||
int64_t newPos = streamPos + diff;
|
||||
|
||||
rv = stream->Seek(NS_SEEK_END, -newPos);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentStream = i;
|
||||
mStartedReadingCurrent = true;
|
||||
mStreams[i].mCurrentPos += diff;
|
||||
|
||||
remaining += newPos;
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(remaining == streamPos, "Huh?");
|
||||
remaining = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// We are at the beginning of this stream.
|
||||
rv = stream->Seek(NS_SEEK_SET, 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
remaining += streamLength;
|
||||
mStreams[i].mCurrentPos = 0;
|
||||
}
|
||||
|
||||
// Any other stream must be set to the end.
|
||||
for (--i; i >= 0; --i) {
|
||||
nsCOMPtr<nsISeekableStream> stream = mStreams[i].mSeekableStream;
|
||||
|
||||
uint64_t avail;
|
||||
rv = AvailableMaybeSeek(mStreams[i], &avail);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t streamLength = avail + mStreams[i].mCurrentPos;
|
||||
|
||||
rv = stream->Seek(NS_SEEK_END, 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mStreams[i].mCurrentPos = streamLength;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче