diff --git a/mozilla/netwerk/base/public/MANIFEST b/mozilla/netwerk/base/public/MANIFEST index 372fd7e9c38..0f9d533ab3d 100644 --- a/mozilla/netwerk/base/public/MANIFEST +++ b/mozilla/netwerk/base/public/MANIFEST @@ -5,4 +5,5 @@ netCore.h nsNetUtil.h nsUnixColorPrintf.h +nsReadLine.h nsIPasswordManagerUtils.h diff --git a/mozilla/netwerk/base/public/Makefile.in b/mozilla/netwerk/base/public/Makefile.in index ccfde717e81..6d96f06595c 100644 --- a/mozilla/netwerk/base/public/Makefile.in +++ b/mozilla/netwerk/base/public/Makefile.in @@ -76,6 +76,7 @@ EXPORTS = \ netCore.h \ nsNetUtil.h \ nsUnixColorPrintf.h \ + nsReadLine.h \ $(NULL) PREF_JS_EXPORTS = $(srcdir)/security-prefs.js diff --git a/mozilla/netwerk/base/public/makefile.win b/mozilla/netwerk/base/public/makefile.win index 8b712ac763d..217e15ca406 100644 --- a/mozilla/netwerk/base/public/makefile.win +++ b/mozilla/netwerk/base/public/makefile.win @@ -28,6 +28,7 @@ EXPORTS = \ netCore.h \ nsNetUtil.h \ nsUnixColorPrintf.h \ + nsReadLine.h \ $(NULL) XPIDLSRCS = \ diff --git a/mozilla/netwerk/base/public/nsReadLine.h b/mozilla/netwerk/base/public/nsReadLine.h new file mode 100644 index 00000000000..6c17e7ccaa0 --- /dev/null +++ b/mozilla/netwerk/base/public/nsReadLine.h @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Boris Zbarsky + * Portions created by Boris Zbarsky are Copyright + * (C) 2001. All Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsReadLine_h__ +#define nsReadLine_h__ + +#include "prmem.h" +#include "nsIInputStream.h" + +/* To properly use the helper function in here (ReadLine) the caller + * needs to declare a pointer to an nsLineBuffer, call + * NS_InitLineBuffer on it, and pass it to ReadLine every time it + * wants a line out. + * + * When done, the pointer should be freed using PR_FREEIF. + */ + +#define kLineBufferSize 1024 + +typedef struct { + char buf[kLineBufferSize+1]; + char* start; + char* current; + char* end; + PRBool empty; +} nsLineBuffer; + +static nsresult +NS_InitLineBuffer (nsLineBuffer ** aBufferPtr) { + *aBufferPtr = PR_NEW(nsLineBuffer); + if (!(*aBufferPtr)) return NS_ERROR_OUT_OF_MEMORY; + (*aBufferPtr)->start = (*aBufferPtr)->current = (*aBufferPtr)->end = (*aBufferPtr)->buf; + (*aBufferPtr)->empty = PR_TRUE; + return NS_OK; +} + +static nsresult +NS_ReadLine (nsIInputStream* aStream, nsLineBuffer * aBuffer, + nsAWritableString & aLine, PRBool *more) { + nsresult rv = NS_OK; + PRUint32 bytesRead; + nsAutoString temp; + *more = PR_TRUE; + PRBool eolStarted = PR_FALSE; + char eolchar; + aLine.Truncate(); + while (1) { // will be returning out of this loop on eol or eof + if (aBuffer->empty) { // buffer is empty. Read into it. + rv = aStream->Read(aBuffer->buf, kLineBufferSize, &bytesRead); + if (NS_FAILED(rv)) // read failed + return rv; + if (bytesRead == 0) { // end of file + *more = PR_FALSE; + return NS_OK; + } + aBuffer->end = aBuffer->buf + bytesRead; + aBuffer->empty = PR_FALSE; + *(aBuffer->end) = '\0'; // null-terminate this thing + } + // walk the buffer looking for an end-of-line + while (aBuffer->current < aBuffer->end) { + if (eolStarted) { + if ((eolchar == '\n' && *(aBuffer->current) == '\r') || + (eolchar == '\r' && *(aBuffer->current) == '\n')) { // line end + (aBuffer->current)++; + aBuffer->start = aBuffer->current; + } + eolStarted = PR_FALSE; + return NS_OK; + } else if (*(aBuffer->current) == '\n' || + *(aBuffer->current) == '\r') { // line end + eolStarted = PR_TRUE; + eolchar = *(aBuffer->current); + *(aBuffer->current) = '\0'; + temp.AssignWithConversion(aBuffer->start); + aLine.Append(temp); + (aBuffer->current)++; + aBuffer->start = aBuffer->current; + } else { + eolStarted = PR_FALSE; + (aBuffer->current)++; + } + } + + // append whatever we currently have to the string + temp.AssignWithConversion(aBuffer->start); + aLine.Append(temp); + + // we've run out of buffer. Begin anew + aBuffer->current = aBuffer->start = aBuffer->buf; + aBuffer->empty = PR_TRUE; + + if (eolStarted) { // have to read another char and possibly skip over it + rv = aStream->Read(aBuffer->buf, 1, &bytesRead); + if (NS_FAILED(rv)) // read failed + return rv; + if (bytesRead == 0) { // end of file + *more = PR_FALSE; + return NS_OK; + } + if ((eolchar == '\n' && *(aBuffer->buf) == '\r') || + (eolchar == '\r' && *(aBuffer->buf) == '\n')) { + // Just return and all is good -- we've skipped the extra newline char + return NS_OK; + } else { + // we have a byte that we should look at later + aBuffer->empty = PR_FALSE; + aBuffer->end = aBuffer->buf + 1; + *(aBuffer->end) = '\0'; + } + } + } +} + +#endif // nsReadLine_h__ diff --git a/mozilla/netwerk/base/src/nsFileStreams.cpp b/mozilla/netwerk/base/src/nsFileStreams.cpp index 5c52da445e8..85f17d76e7c 100644 --- a/mozilla/netwerk/base/src/nsFileStreams.cpp +++ b/mozilla/netwerk/base/src/nsFileStreams.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -31,6 +31,7 @@ #include "nsIFile.h" #include "nsDirectoryIndexStream.h" #include "nsMimeTypes.h" +#include "nsReadLine.h" #define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067 @@ -347,10 +348,11 @@ nsFileStream::Tell(PRUint32 *result) //////////////////////////////////////////////////////////////////////////////// // nsFileInputStream -NS_IMPL_ISUPPORTS_INHERITED2(nsFileInputStream, +NS_IMPL_ISUPPORTS_INHERITED3(nsFileInputStream, nsFileStream, nsIInputStream, - nsIFileInputStream); + nsIFileInputStream, + nsILineInputStream); NS_METHOD nsFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) @@ -379,13 +381,18 @@ nsFileInputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm) ioFlags = PR_RDONLY; if (perm == -1) perm = 0; + + mLineBuffer = nsnull; + return localFile->OpenNSPRFileDesc(ioFlags, perm, &mFD); } NS_IMETHODIMP nsFileInputStream::Close() { - return nsFileStream::Close(); + PR_FREEIF(mLineBuffer); + mLineBuffer = 0; // prevents badness if Close() is called again after failing + return nsFileStream::Close(); } NS_IMETHODIMP @@ -416,6 +423,15 @@ nsFileInputStream::Read(char * buf, PRUint32 count, PRUint32 *result) return NS_OK; } +NS_IMETHODIMP +nsFileInputStream::ReadLine(nsAWritableString & aLine, PRBool *_retval) { + if (!mLineBuffer) { + nsresult rv = NS_InitLineBuffer(&mLineBuffer); + if (NS_FAILED(rv)) return rv; + } + return NS_ReadLine(this, mLineBuffer, aLine, _retval); +} + NS_IMETHODIMP nsFileInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval) { diff --git a/mozilla/netwerk/base/src/nsFileStreams.h b/mozilla/netwerk/base/src/nsFileStreams.h index f5097775ac6..3528b551ba5 100644 --- a/mozilla/netwerk/base/src/nsFileStreams.h +++ b/mozilla/netwerk/base/src/nsFileStreams.h @@ -28,8 +28,10 @@ #include "nsIChannel.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" +#include "nsILineInputStream.h" #include "nsIStreamIO.h" #include "nsCOMPtr.h" +#include "nsReadLine.h" #include "prlog.h" //////////////////////////////////////////////////////////////////////////////// @@ -77,18 +79,22 @@ protected: //////////////////////////////////////////////////////////////////////////////// class nsFileInputStream : public nsFileStream, - public nsIFileInputStream + public nsIFileInputStream, + public nsILineInputStream { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIINPUTSTREAM NS_DECL_NSIFILEINPUTSTREAM - + NS_DECL_NSILINEINPUTSTREAM + nsFileInputStream() : nsFileStream() {} virtual ~nsFileInputStream() {} static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); +protected: + nsLineBuffer * mLineBuffer; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/xpcom/io/MANIFEST_IDL b/mozilla/xpcom/io/MANIFEST_IDL index 95874e5cc56..808f0b6eae9 100644 --- a/mozilla/xpcom/io/MANIFEST_IDL +++ b/mozilla/xpcom/io/MANIFEST_IDL @@ -7,3 +7,4 @@ nsIPipe.idl nsIFile.idl nsILocalFile.idl nsIByteArrayInputStream.idl +nsILineInputStream.idl diff --git a/mozilla/xpcom/io/Makefile.in b/mozilla/xpcom/io/Makefile.in index a2d8a32cce3..805001aaeb1 100644 --- a/mozilla/xpcom/io/Makefile.in +++ b/mozilla/xpcom/io/Makefile.in @@ -98,7 +98,8 @@ XPIDLSRCS = \ nsIStorageStream.idl \ nsIDirectoryService.idl \ nsIByteArrayInputStream.idl \ - nsIInputStreamTee.idl \ + nsIInputStreamTee.idl \ + nsILineInputStream.idl \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/mozilla/xpcom/io/makefile.win b/mozilla/xpcom/io/makefile.win index befde47c20f..88eb7c89f73 100644 --- a/mozilla/xpcom/io/makefile.win +++ b/mozilla/xpcom/io/makefile.win @@ -60,6 +60,7 @@ XPIDLSRCS = \ .\nsIDirectoryService.idl \ .\nsIByteArrayInputStream.idl \ .\nsIInputStreamTee.idl \ + .\nsILineInputStream.idl \ $(NULL) ################################################################################ diff --git a/mozilla/xpcom/io/nsILineInputStream.idl b/mozilla/xpcom/io/nsILineInputStream.idl new file mode 100644 index 00000000000..5c6bac68739 --- /dev/null +++ b/mozilla/xpcom/io/nsILineInputStream.idl @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Boris Zbarsky + * Portions created by Boris Zbarsky are Copyright + * (C) 2001. All Rights Reserved. + * + * Contributor(s): + */ + +#include "nsISupports.idl" + +%{ C++ +#include "nsString.h" // needed for AString -> nsAWritableString, unfortunately +%} + +interface nsILineInputStream; + +[scriptable, uuid(e7f17108-1dd1-11b2-8b9a-fda151ea0240)] +interface nsILineInputStream : nsISupports +{ + /** + * Read a single line from the stream + * Return false for end of file, true otherwise + */ + boolean readLine(out AString aLine); +};