diff --git a/xpcom/io/nsMultiplexInputStream.cpp b/xpcom/io/nsMultiplexInputStream.cpp index 59fbd880e963..5a605f7f8107 100644 --- a/xpcom/io/nsMultiplexInputStream.cpp +++ b/xpcom/io/nsMultiplexInputStream.cpp @@ -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 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 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;