mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Added stream buffering. Made file transport use it. Bug #19233 r=dougt
This commit is contained in:
parent
be979f653a
commit
9e08bb8519
@ -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;
|
||||
}
|
||||
|
||||
%}
|
||||
|
@ -32,6 +32,7 @@ LIBRARY_NAME = neckobase_s
|
||||
CPPSRCS = \
|
||||
nsURLHelper.cpp \
|
||||
nsFileStreams.cpp \
|
||||
nsBufferedStreams.cpp \
|
||||
nsAsyncStreamListener.cpp \
|
||||
nsSyncStreamListener.cpp \
|
||||
nsIOService.cpp \
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user