Added stream buffering. Made file transport use it. Bug #19233 r=dougt

This commit is contained in:
warren%netscape.com 2000-02-04 07:31:43 +00:00
parent be979f653a
commit 9e08bb8519
12 changed files with 395 additions and 113 deletions

View File

@ -37,7 +37,7 @@ interface nsIFileOutputStream : nsIOutputStream
};
[scriptable, uuid(e9de5df0-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsIRandomAccessStore : nsISupports
interface nsISeekableStream : nsISupports
{
// correspond to PRSeekWhence values
const long NS_SEEK_SET = 0;
@ -45,12 +45,26 @@ interface nsIRandomAccessStore : nsISupports
const long NS_SEEK_END = 2;
void seek(in long whence, in long offset);
long tell();
unsigned long tell();
};
[scriptable, uuid(616f5b48-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedInputStream : nsIInputStream
{
void init(in nsIInputStream fillFromStream,
in unsigned long bufferSize);
};
[scriptable, uuid(6476378a-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedOutputStream : nsIOutputStream
{
void init(in nsIOutputStream sinkToStream,
in unsigned long bufferSize);
};
%{C++
#include "prio.h" // for read/write modes, etc.
////////////////////////////////////////////////////////////////////////////////
#define NS_FILEINPUTSTREAM_CLASSNAME "File Input Stream"
#define NS_FILEINPUTSTREAM_PROGID "component://netscape/network/file-input-stream"
@ -74,6 +88,31 @@ interface nsIRandomAccessStore : nsISupports
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
#define NS_BUFFEREDINPUTSTREAM_CLASSNAME "Buffered Input Stream"
#define NS_BUFFEREDINPUTSTREAM_PROGID "component://netscape/network/buffered-input-stream"
#define NS_BUFFEREDINPUTSTREAM_CID \
{ /* 9226888e-da08-11d3-8cda-0060b0fc14a3 */ \
0x9226888e, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_BUFFEREDOUTPUTSTREAM_CLASSNAME "Buffered Output Stream"
#define NS_BUFFEREDOUTPUTSTREAM_PROGID "component://netscape/network/buffered-output-stream"
#define NS_BUFFEREDOUTPUTSTREAM_CID \
{ /* 9868b4ce-da08-11d3-8cda-0060b0fc14a3 */ \
0x9868b4ce, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
// move to nsNetUtil.h later...
#include "nsILoadGroup.h"
@ -84,6 +123,7 @@ interface nsIRandomAccessStore : nsISupports
#include "nsILocalFile.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "prio.h" // for read/write modes, etc.
inline nsresult
NS_NewFileChannel(nsIFile* file,
@ -159,4 +199,46 @@ NS_NewFileOutputStream(nsIFile* file, PRInt32 flags, PRInt32 mode,
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
inline nsresult
NS_NewBufferedInputStream(nsIInputStream* str, PRUint32 bufferSize,
nsIInputStream* *result)
{
nsresult rv;
nsCOMPtr<nsIBufferedInputStream> in;
static NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedInputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(str, bufferSize);
if (NS_FAILED(rv)) return rv;
*result = in;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewBufferedOutputStream(nsIOutputStream* str, PRUint32 bufferSize,
nsIOutputStream* *result)
{
nsresult rv;
nsCOMPtr<nsIBufferedOutputStream> out;
static NS_DEFINE_CID(kBufferedOutputStreamCID, NS_BUFFEREDOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedOutputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(str, bufferSize);
if (NS_FAILED(rv)) return rv;
*result = out;
NS_ADDREF(*result);
return NS_OK;
}
%}

View File

@ -32,6 +32,7 @@ LIBRARY_NAME = neckobase_s
CPPSRCS = \
nsURLHelper.cpp \
nsFileStreams.cpp \
nsBufferedStreams.cpp \
nsAsyncStreamListener.cpp \
nsSyncStreamListener.cpp \
nsIOService.cpp \

View File

@ -21,6 +21,7 @@
*/
#include "nsBufferedStreams.h"
#include "nsCRT.h"
////////////////////////////////////////////////////////////////////////////////
// nsBufferedStream
@ -28,7 +29,9 @@
nsBufferedStream::nsBufferedStream()
: mBuffer(nsnull),
mBufferStartOffset(0),
mCursor(0)
mCursor(0),
mFillPoint(0),
mStream(nsnull)
{
NS_INIT_REFCNT();
}
@ -40,18 +43,19 @@ nsBufferedStream::~nsBufferedStream()
NS_IMPL_ISUPPORTS2(nsBufferedStream,
nsIBaseStream,
nsIRandomAccessStore);
nsISeekableStream);
nsresult
nsBufferedStream::Init(PRUint32 BufferedSize, nsIBaseStream* stream)
nsBufferedStream::Init(nsIBaseStream* stream, PRUint32 bufferSize)
{
NS_ASSERTION(stream, "need to supply a stream");
NS_ASSERTION(mStream == nsnull, "already inited");
mStream = stream;
mBufferSize = BufferedSize;
NS_ADDREF(mStream);
mBufferSize = bufferSize;
mBufferStartOffset = 0;
mCursor = 0;
mBuffer = new char[BufferedSize];
mBuffer = new char[bufferSize];
if (mBuffer == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -60,8 +64,10 @@ nsBufferedStream::Init(PRUint32 BufferedSize, nsIBaseStream* stream)
NS_IMETHODIMP
nsBufferedStream::Close()
{
nsresult rv = NS_OK;
if (mStream) {
return mStream->Close();
rv = mStream->Close();
NS_RELEASE(mStream);
mStream = nsnull;
delete mBuffer;
mBuffer = nsnull;
@ -69,7 +75,7 @@ nsBufferedStream::Close()
mBufferStartOffset = 0;
mCursor = 0;
}
return NS_OK;
return rv;
}
NS_IMETHODIMP
@ -78,30 +84,72 @@ nsBufferedStream::Seek(PRInt32 whence, PRInt32 offset)
if (mStream == nsnull)
return NS_BASE_STREAM_CLOSED;
if (whence == nsIRandomAccessStore::NS_SEEK_CUR &&
mCursor + offset < mBufferStartOffset + mBufferSize) {
mCursor += offset;
// If the underlying stream isn't a random access store, then fail early.
// We could possibly succeed for the case where the seek position denotes
// something that happens to be read into the buffer, but that would make
// the failure data-dependent.
nsresult rv;
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mStream, &rv);
if (NS_FAILED(rv)) return rv;
PRInt32 absPos;
switch (whence) {
case nsISeekableStream::NS_SEEK_SET:
absPos = offset;
break;
case nsISeekableStream::NS_SEEK_CUR:
absPos = mBufferStartOffset + mCursor + offset;
break;
case nsISeekableStream::NS_SEEK_END:
absPos = -1;
break;
default:
NS_NOTREACHED("bogus seek whence parameter");
return NS_ERROR_UNEXPECTED;
}
if ((PRInt32)mBufferStartOffset <= absPos
&& absPos < (PRInt32)(mBufferStartOffset + mFillPoint)) {
mCursor = absPos - mBufferStartOffset;
return NS_OK;
}
// XXX more...
return NS_ERROR_NOT_IMPLEMENTED;
rv = Flush();
if (NS_FAILED(rv)) return rv;
rv = ras->Seek(whence, offset);
if (NS_FAILED(rv)) return rv;
if (absPos == -1) {
// then we had the SEEK_END case, above
rv = ras->Tell(&mBufferStartOffset);
if (NS_FAILED(rv)) return rv;
}
else {
mBufferStartOffset = absPos;
}
mCursor = 0;
mFillPoint = 0;
return Fill();
}
NS_IMETHODIMP
nsBufferedStream::Tell(PRInt32 *result)
nsBufferedStream::Tell(PRUint32 *result)
{
if (mStream == nsnull)
return NS_BASE_STREAM_CLOSED;
return NS_ERROR_NOT_IMPLEMENTED;
*result = mBufferStartOffset + mCursor;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsBufferedInputStream
NS_IMPL_ISUPPORTS_INHERITED1(nsBufferedInputStream,
NS_IMPL_ISUPPORTS_INHERITED2(nsBufferedInputStream,
nsBufferedStream,
nsIInputStream);
nsIInputStream,
nsIBufferedInputStream);
NS_METHOD
nsBufferedInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
@ -117,6 +165,12 @@ nsBufferedInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult
return rv;
}
NS_IMETHODIMP
nsBufferedInputStream::Init(nsIInputStream* stream, PRUint32 bufferSize)
{
return nsBufferedStream::Init(stream, bufferSize);
}
NS_IMETHODIMP
nsBufferedInputStream::Close()
{
@ -126,21 +180,62 @@ nsBufferedInputStream::Close()
NS_IMETHODIMP
nsBufferedInputStream::Available(PRUint32 *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
*result = mFillPoint - mCursor;
return NS_OK;
}
NS_IMETHODIMP
nsBufferedInputStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv = NS_OK;
PRUint32 read = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
nsCRT::memcpy(buf, mBuffer + mCursor, amt);
read += amt;
count -= amt;
mCursor += amt;
}
else {
rv = Fill();
if (NS_FAILED(rv)) break;
}
}
*result = read;
return (read > 0 || rv == NS_BASE_STREAM_CLOSED) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedInputStream::Fill()
{
nsresult rv;
PRUint32 rem = mFillPoint - mCursor;
if (rem > 0) {
// slide the remainder down to the start of the buffer
// |<------------->|<--rem-->|<--->|
// b c f s
nsCRT::memcpy(mBuffer, mBuffer + mCursor, rem);
mBufferStartOffset += mCursor;
mFillPoint = rem;
mCursor = 0;
}
PRUint32 amt;
rv = Source()->Read(mBuffer + mFillPoint, mBufferSize - mFillPoint, &amt);
if (NS_FAILED(rv)) return rv;
mFillPoint += amt;
return amt > 0 ? NS_OK : NS_BASE_STREAM_CLOSED;
}
////////////////////////////////////////////////////////////////////////////////
// nsBufferedOutputStream
NS_IMPL_ISUPPORTS_INHERITED1(nsBufferedOutputStream,
NS_IMPL_ISUPPORTS_INHERITED2(nsBufferedOutputStream,
nsBufferedStream,
nsIOutputStream);
nsIOutputStream,
nsIBufferedOutputStream);
NS_METHOD
nsBufferedOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
@ -156,22 +251,68 @@ nsBufferedOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResul
return rv;
}
NS_IMETHODIMP
nsBufferedOutputStream::Init(nsIOutputStream* stream, PRUint32 bufferSize)
{
mFillPoint = bufferSize; // always fill to the end for buffered output streams
return nsBufferedStream::Init(stream, bufferSize);
}
NS_IMETHODIMP
nsBufferedOutputStream::Close()
{
return nsBufferedStream::Close();
nsresult rv1, rv2;
rv1 = Flush();
// If we fail to Flush all the data, then we close anyway and drop the
// remaining data in the buffer. We do this because it's what Unix does
// for fclose and close. However, we report the error from Flush anyway.
rv2 = nsBufferedStream::Close();
if (NS_FAILED(rv1)) return rv1;
return rv2;
}
NS_IMETHODIMP
nsBufferedOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv = NS_OK;
PRUint32 written = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
nsCRT::memcpy(mBuffer + mCursor, buf, amt);
written += amt;
count -= amt;
mCursor += amt;
}
else {
rv = Flush();
if (NS_FAILED(rv)) break;
}
}
*result = written;
return (written > 0) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedOutputStream::Flush(void)
{
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv;
PRUint32 amt;
rv = Sink()->Write(mBuffer, mCursor, &amt);
if (NS_FAILED(rv)) return rv;
mBufferStartOffset += amt;
if (mCursor == amt) {
mCursor = 0;
return NS_OK; // flushed everything
}
// slide the remainder down to the start of the buffer
// |<-------------->|<---|----->|
// b a c s
PRUint32 rem = mCursor - amt;
nsCRT::memcpy(mBuffer, mBuffer + amt, rem);
mCursor = rem;
return NS_ERROR_FAILURE; // didn't flush all
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -31,36 +31,46 @@
////////////////////////////////////////////////////////////////////////////////
class nsBufferedStream : public nsIBaseStream,
public nsIRandomAccessStore
public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIBASESTREAM
NS_DECL_NSIRANDOMACCESSSTORE
NS_DECL_NSISEEKABLESTREAM
nsBufferedStream();
virtual ~nsBufferedStream();
nsresult Init(PRUint32 bufferSize, nsIBaseStream* stream);
protected:
nsresult Init(nsIBaseStream* stream, PRUint32 bufferSize);
NS_IMETHOD Fill() = 0;
NS_IMETHOD Flush() = 0;
protected:
PRUint32 mBufferSize;
char* mBuffer;
// mBufferStartOffset is the offset relative to the start of mStream:
PRUint32 mBufferStartOffset;
// mCursor is the read cursor for input streams, or write cursor for
// output streams, and is relative to mBufferStartOffset:
PRUint32 mCursor;
nsCOMPtr<nsIBaseStream> mStream;
// mFillPoint is the amount available in the buffer for input streams,
// or the end of the buffer for output streams, and is relative to
// mBufferStartOffset:
PRUint32 mFillPoint;
nsIBaseStream* mStream; // cast to appropriate subclass
};
////////////////////////////////////////////////////////////////////////////////
class nsBufferedInputStream : public nsBufferedStream,
public nsIInputStream
public nsIBufferedInputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIBASESTREAM
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIRANDOMACCESSSTORE
NS_DECL_NSIBUFFEREDINPUTSTREAM
nsBufferedInputStream() : nsBufferedStream() {}
virtual ~nsBufferedInputStream() {}
@ -69,20 +79,24 @@ public:
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsIInputStream* Source() {
return (nsIInputStream*)mStream.get();
return (nsIInputStream*)mStream;
}
protected:
NS_IMETHOD Fill();
NS_IMETHOD Flush() { return NS_OK; } // no-op for input streams
};
////////////////////////////////////////////////////////////////////////////////
class nsBufferedOutputStream : public nsBufferedStream,
public nsIOutputStream
public nsIBufferedOutputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIBASESTREAM
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIRANDOMACCESSSTORE
NS_DECL_NSIBUFFEREDOUTPUTSTREAM
nsBufferedOutputStream() : nsBufferedStream() {}
virtual ~nsBufferedOutputStream() {}
@ -91,8 +105,11 @@ public:
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsIOutputStream* Sink() {
return (nsIOutputStream*)mStream.get();
return (nsIOutputStream*)mStream;
}
protected:
NS_IMETHOD Fill() { return NS_OK; } // no-op for output streams
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -40,7 +40,7 @@ nsFileStream::~nsFileStream()
NS_IMPL_ISUPPORTS2(nsFileStream,
nsIBaseStream,
nsIRandomAccessStore);
nsISeekableStream);
NS_IMETHODIMP
nsFileStream::Close()
@ -66,7 +66,7 @@ nsFileStream::Seek(PRInt32 whence, PRInt32 offset)
}
NS_IMETHODIMP
nsFileStream::Tell(PRInt32 *result)
nsFileStream::Tell(PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
@ -168,6 +168,8 @@ NS_IMETHODIMP
nsFileOutputStream::Init(nsILocalFile* file, PRInt32 flags, PRInt32 mode)
{
NS_ASSERTION(mFD == nsnull, "already inited");
if (mFD != nsnull)
return NS_ERROR_FAILURE;
return file->OpenNSPRFileDesc(flags, mode, &mFD);
}

View File

@ -32,12 +32,12 @@
////////////////////////////////////////////////////////////////////////////////
class nsFileStream : public nsIBaseStream,
public nsIRandomAccessStore
public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIBASESTREAM
NS_DECL_NSIRANDOMACCESSSTORE
NS_DECL_NSISEEKABLESTREAM
nsFileStream();
virtual ~nsFileStream();

View File

@ -46,6 +46,11 @@
#include "nsNetUtil.h"
#include "nsInt64.h"
#define NS_INPUT_STREAM_BUFFER_SIZE (16 * 1024)
#define NS_OUTPUT_STREAM_BUFFER_SIZE (64 * 1024)
//#define NO_BUFFERING 1
static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
@ -89,9 +94,12 @@ public:
// just do the right thing.)
PRInt64 size;
rv = mFile->GetFileSize(&size);
if (NS_FAILED(rv)) return rv;
*contentLength = nsInt64(size);
if (! *contentLength)
if (NS_SUCCEEDED(rv)) {
*contentLength = nsInt64(size);
if (! *contentLength)
*contentLength = -1;
}
else
*contentLength = -1;
PRBool isDir;
@ -162,7 +170,20 @@ public:
(const char*)mSpec, rv));
return rv;
}
rv = NS_NewFileInputStream(mFile, aInputStream);
nsCOMPtr<nsIInputStream> fileIn;
rv = NS_NewFileInputStream(mFile, getter_AddRefs(fileIn));
if (NS_FAILED(rv)) return rv;
#ifdef NO_BUFFERING
*aInputStream = fileIn;
NS_ADDREF(*aInputStream);
#else
rv = NS_NewBufferedInputStream(fileIn, NS_OUTPUT_STREAM_BUFFER_SIZE,
aInputStream);
#endif
// printf("opening %s for reading\n", (const char*)mSpec);
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
("nsFileTransport: opening local file %s for input (%x)",
(const char*)mSpec, rv));
@ -177,10 +198,27 @@ public:
if (isDir) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIOutputStream> fileOut;
rv = NS_NewFileOutputStream(mFile,
PR_CREATE_FILE | PR_WRONLY,
0664,
aOutputStream);
getter_AddRefs(fileOut));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIOutputStream> bufStr;
#ifdef NO_BUFFERING
bufStr = fileOut;
#else
rv = NS_NewBufferedOutputStream(fileOut, NS_OUTPUT_STREAM_BUFFER_SIZE,
getter_AddRefs(bufStr));
if (NS_FAILED(rv)) return rv;
#endif
*aOutputStream = bufStr;
NS_ADDREF(*aOutputStream);
// printf("opening %s for writing\n", (const char*)mSpec);
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
("nsFileTransport: opening local file %s for output (%x)",
(const char*)mSpec, rv));
@ -189,15 +227,15 @@ public:
nsLocalFileSystem(nsIFile* file) : mFile(file) {
NS_INIT_REFCNT();
#ifdef PR_LOGGING
//#ifdef PR_LOGGING
(void)mFile->GetPath(&mSpec);
#endif
//#endif
}
virtual ~nsLocalFileSystem() {
#ifdef PR_LOGGING
//#ifdef PR_LOGGING
if (mSpec) nsCRT::free(mSpec);
#endif
//#endif
}
static nsresult Create(nsIFile* file, nsIFileSystem* *result) {
@ -211,9 +249,9 @@ public:
protected:
nsCOMPtr<nsIFile> mFile;
#ifdef PR_LOGGING
//#ifdef PR_LOGGING
char* mSpec;
#endif
//#endif
};
NS_IMPL_ISUPPORTS1(nsLocalFileSystem, nsIFileSystem);
@ -577,20 +615,29 @@ nsFileTransport::OpenOutputStream(PRUint32 startPosition, nsIOutputStream **resu
if (mState != CLOSED)
return NS_ERROR_IN_PROGRESS;
nsCOMPtr<nsIOutputStream> str;
nsCOMPtr<nsIOutputStream> fileOut;
rv = NS_NewFileOutputStream(mFile,
PR_CREATE_FILE | PR_WRONLY,
0664,
getter_AddRefs(str));
getter_AddRefs(fileOut));
if (NS_FAILED(rv)) return rv;
*result = str;
nsCOMPtr<nsIOutputStream> bufStr;
#ifdef NO_BUFFERING
bufStr = fileOut;
#else
rv = NS_NewBufferedOutputStream(fileOut, NS_OUTPUT_STREAM_BUFFER_SIZE,
getter_AddRefs(bufStr));
if (NS_FAILED(rv)) return rv;
#endif
*result = bufStr;
NS_ADDREF(*result);
mOffset = startPosition;
if (mOffset > 0) {
// if we need to set a starting offset, QI for nsIRandomAccessStore
nsCOMPtr<nsIRandomAccessStore> ras =
// if we need to set a starting offset, QI for nsISeekableStream
nsCOMPtr<nsISeekableStream> ras =
do_QueryInterface(*result, &mStatus);
if (NS_FAILED(mStatus))
return NS_ERROR_IN_PROGRESS;
@ -802,8 +849,8 @@ nsFileTransport::Process(void)
}
if (mOffset > 0) {
// if we need to set a starting offset, QI for the nsIRandomAccessStore and set it
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(mSource, &mStatus);
// if we need to set a starting offset, QI for the nsISeekableStream and set it
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mSource, &mStatus);
if (NS_FAILED(mStatus)) {
mState = END_READ;
return;
@ -927,8 +974,8 @@ nsFileTransport::Process(void)
}
if (mOffset > 0) {
// if we need to set a starting offset, QI for the nsIRandomAccessStore and set it
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(mSink, &mStatus);
// if we need to set a starting offset, QI for the nsISeekableStream and set it
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mSink, &mStatus);
if (NS_FAILED(mStatus)) {
mState = END_WRITE;
return;

View File

@ -42,6 +42,7 @@
#include "nsAsyncStreamListener.h"
#include "nsSyncStreamListener.h"
#include "nsFileStreams.h"
#include "nsBufferedStreams.h"
///////////////////////////////////////////////////////////////////////////////
// Module implementation for the net library
@ -123,6 +124,14 @@ static nsModuleComponentInfo gNetModuleInfo[] = {
NS_NOAUTHORITYURLPARSER_CID,
"component://netscape/network/no-authority-urlparser",
nsNoAuthURLParser::Create },
{ NS_BUFFEREDINPUTSTREAM_CLASSNAME,
NS_BUFFEREDINPUTSTREAM_CID,
NS_BUFFEREDINPUTSTREAM_PROGID,
nsBufferedInputStream::Create },
{ NS_BUFFEREDOUTPUTSTREAM_CLASSNAME,
NS_BUFFEREDOUTPUTSTREAM_CID,
NS_BUFFEREDOUTPUTSTREAM_PROGID,
nsBufferedOutputStream::Create }
};
NS_IMPL_NSGETMODULE("net", gNetModuleInfo)

View File

@ -45,7 +45,7 @@ nsHTTPEncodeStream::~nsHTTPEncodeStream()
{
}
NS_IMPL_ISUPPORTS2(nsHTTPEncodeStream, nsIInputStream, nsIRandomAccessStore);
NS_IMPL_ISUPPORTS2(nsHTTPEncodeStream, nsIInputStream, nsISeekableStream);
NS_METHOD
nsHTTPEncodeStream::Create(nsIInputStream *rawStream, PRUint32 flags,
@ -158,13 +158,13 @@ nsHTTPEncodeStream::Read(char* outBuf, PRUint32 outBufCnt, PRUint32 *result)
}
////////////////////////////////////////////////////////////////////////////////
// nsIRandomAccessStore methods:
// nsISeekableStream methods:
NS_IMETHODIMP
nsHTTPEncodeStream::Seek(PRInt32 whence, PRInt32 offset)
{
nsresult rv;
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(mInput, &rv);
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mInput, &rv);
if (NS_FAILED(rv)) return rv;
mPushBackBuffer.SetLength(0);
@ -172,35 +172,13 @@ nsHTTPEncodeStream::Seek(PRInt32 whence, PRInt32 offset)
}
NS_IMETHODIMP
nsHTTPEncodeStream::Tell(PRInt32* outWhere)
nsHTTPEncodeStream::Tell(PRUint32* outWhere)
{
nsresult rv;
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(mInput, &rv);
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mInput, &rv);
if (NS_FAILED(rv)) return rv;
return ras->Tell(outWhere);
}
#if 0
NS_IMETHODIMP
nsHTTPEncodeStream::GetAtEOF(PRBool* outAtEOF)
{
nsresult rv;
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(mInput, &rv);
if (NS_FAILED(rv)) return rv;
return ras->GetAtEOF(outAtEOF);
}
NS_IMETHODIMP
nsHTTPEncodeStream::SetAtEOF(PRBool inAtEOF)
{
nsresult rv;
nsCOMPtr<nsIRandomAccessStore> ras = do_QueryInterface(mInput, &rv);
if (NS_FAILED(rv)) return rv;
return ras->SetAtEOF(inAtEOF);
}
#endif
////////////////////////////////////////////////////////////////////////////////

View File

@ -29,21 +29,13 @@
#include "nsIFileStreams.h"
class nsHTTPEncodeStream : public nsIInputStream,
public nsIRandomAccessStore
public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIBASESTREAM
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIRANDOMACCESSSTORE
#if 0
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset);
NS_IMETHOD Tell(PRIntn* outWhere);
// XXX supposedly "protected":
NS_IMETHOD GetAtEOF(PRBool* outAtEOF);
NS_IMETHOD SetAtEOF(PRBool inAtEOF);
#endif
NS_DECL_NSISEEKABLESTREAM
// nsHTTPEncodeStream methods:
nsHTTPEncodeStream();

View File

@ -155,14 +155,22 @@ public:
PRUint32 copyCount = 0;
// Open the input stream:
rv = NS_NewFileInputStream(mInPath, getter_AddRefs(inStr));
nsCOMPtr<nsIInputStream> fileIn;
rv = NS_NewFileInputStream(mInPath, getter_AddRefs(fileIn));
if (NS_FAILED(rv)) return rv;
rv = NS_NewBufferedInputStream(fileIn, 65535, getter_AddRefs(inStr));
if (NS_FAILED(rv)) return rv;
// Open the output stream:
nsCOMPtr<nsIOutputStream> fileOut;
rv = NS_NewFileOutputStream(mOutPath,
PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
0664,
getter_AddRefs(outStr));
getter_AddRefs(fileOut));
if (NS_FAILED(rv)) return rv;
rv = NS_NewBufferedOutputStream(fileOut, 65535, getter_AddRefs(outStr));
if (NS_FAILED(rv)) return rv;
// Copy from one to the other

View File

@ -26,11 +26,6 @@
#include <stdio.h>
#include <math.h>
#define MIN_SIZE 4096
#define MAX_SIZE (512 * 1024)
#define SIZE_INCREMENT 4096
#define ITERATIONS 10
void
NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues,
double *meanResult, double *stdDevResult)
@ -51,10 +46,11 @@ NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues,
}
int
Test(const char* filename)
Test(const char* filename, PRInt32 minSize, PRInt32 maxSize,
PRInt32 sizeIncrement, PRInt32 iterations)
{
fprintf(stdout, " size write: mean stddev iters total: mean stddev iters\n");
for (PRInt32 size = MIN_SIZE; size <= MAX_SIZE; size += SIZE_INCREMENT) {
for (PRInt32 size = minSize; size <= maxSize; size += sizeIncrement) {
// create a buffer of stuff to write
char* buf = (char*)PR_Malloc(size);
if (buf == NULL)
@ -69,10 +65,12 @@ Test(const char* filename)
double writeCount = 0, writeRate = 0, writeRateSquared = 0;
double totalCount = 0, totalRate = 0, totalRateSquared = 0;
for (i = 0; i < ITERATIONS; i++) {
for (i = 0; i < iterations; i++) {
PRIntervalTime start = PR_IntervalNow();
PRFileDesc* fd = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664);
char name[1024];
sprintf(name, "%s_%d", filename, i);
PRFileDesc* fd = PR_Open(name, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664);
if (fd == NULL)
return -1;
@ -119,10 +117,17 @@ Test(const char* filename)
return 0;
}
void
main()
int
main(int argc, char* argv[])
{
Test("y:\\foo");
if (argc != 5) {
printf("usage: %s <min buf size (K)> <max buf size (K)> <size increment (K)> <iterations>\n", argv[0]);
return -1;
}
Test("y:\\foo",
atoi(argv[1]) * 1024,
atoi(argv[2]) * 1024,
atoi(argv[3]) * 1024,
atoi(argv[4]));
return 0;
}