1998-04-13 20:24:54 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2001-09-26 00:40:45 +00:00
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
1998-04-13 20:24:54 +00:00
|
|
|
*
|
2001-09-26 00:40:45 +00:00
|
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
|
|
|
*
|
|
|
|
* 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.
|
1998-04-13 20:24:54 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2001-09-26 00:40:45 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the NPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the NPL, the GPL or the LGPL.
|
1999-11-06 03:43:54 +00:00
|
|
|
*
|
2001-09-26 00:40:45 +00:00
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-05-07 07:19:47 +00:00
|
|
|
//#define __INCREMENTAL 1
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
#include "nsScanner.h"
|
|
|
|
#include "nsDebug.h"
|
1999-02-01 18:23:31 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsICharsetConverterManager.h"
|
1999-03-08 20:00:23 +00:00
|
|
|
#include "nsICharsetAlias.h"
|
1999-04-06 20:39:11 +00:00
|
|
|
#include "nsFileSpec.h"
|
2000-12-12 21:58:14 +00:00
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
|
2002-03-07 16:45:25 +00:00
|
|
|
nsScannerString::nsScannerString(PRUnichar* aStorageStart,
|
|
|
|
PRUnichar* aDataEnd,
|
|
|
|
PRUnichar* aStorageEnd) : nsSlidingString(aStorageStart, aDataEnd, aStorageEnd)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsScannerString::ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
|
|
|
|
PRUnichar aChar)
|
|
|
|
{
|
|
|
|
// XXX Casting a const to non-const. Unless the base class
|
|
|
|
// provides support for writing iterators, this is the best
|
|
|
|
// that can be done.
|
|
|
|
PRUnichar* pos = (PRUnichar*)aPosition.get();
|
|
|
|
*pos = aChar;
|
|
|
|
}
|
1999-02-01 18:23:31 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
nsReadEndCondition::nsReadEndCondition(const PRUnichar* aTerminateChars) :
|
|
|
|
mChars(aTerminateChars), mFilter(PRUnichar(~0)) // All bits set
|
|
|
|
{
|
|
|
|
// Build filter that will be used to filter out characters with
|
|
|
|
// bits that none of the terminal chars have. This works very well
|
|
|
|
// because terminal chars often have only the last 4-6 bits set and
|
|
|
|
// normal ascii letters have bit 7 set. Other letters have even higher
|
|
|
|
// bits set.
|
|
|
|
|
|
|
|
// Calculate filter
|
|
|
|
const PRUnichar *current = aTerminateChars;
|
|
|
|
PRUnichar terminalChar = *current;
|
|
|
|
while (terminalChar) {
|
|
|
|
mFilter &= ~terminalChar;
|
|
|
|
++current;
|
|
|
|
terminalChar = *current;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-07-22 05:25:17 +00:00
|
|
|
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>";
|
1998-08-29 05:08:20 +00:00
|
|
|
const char* kUnorderedStringError = "String argument must be ordered. Don't you read API's?";
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-05-07 07:19:47 +00:00
|
|
|
#ifdef __INCREMENTAL
|
|
|
|
const int kBufsize=1;
|
|
|
|
#else
|
|
|
|
const int kBufsize=64;
|
|
|
|
#endif
|
|
|
|
|
2001-01-27 23:06:33 +00:00
|
|
|
MOZ_DECL_CTOR_COUNTER(nsScanner)
|
1998-05-07 07:19:47 +00:00
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
/**
|
1998-07-24 21:57:43 +00:00
|
|
|
* Use this constructor if you want i/o to be based on
|
|
|
|
* a single string you hand in during construction.
|
|
|
|
* This short cut was added for Javascript.
|
|
|
|
*
|
|
|
|
* @update gess 5/12/98
|
|
|
|
* @param aMode represents the parser mode (nav, other)
|
|
|
|
* @return
|
|
|
|
*/
|
2002-02-12 21:17:53 +00:00
|
|
|
nsScanner::nsScanner(const nsAString& anHTMLString, const nsString& aCharset, PRInt32 aSource)
|
1998-07-24 21:57:43 +00:00
|
|
|
{
|
1999-10-14 23:37:21 +00:00
|
|
|
MOZ_COUNT_CTOR(nsScanner);
|
2002-03-07 16:45:25 +00:00
|
|
|
|
|
|
|
PRUnichar* buffer = ToNewUnicode(anHTMLString);
|
2002-03-07 15:43:12 +00:00
|
|
|
mTotalRead = anHTMLString.Length();
|
2002-03-07 16:45:25 +00:00
|
|
|
mSlidingBuffer = nsnull;
|
2000-12-12 21:58:14 +00:00
|
|
|
mCountRemaining = 0;
|
2002-03-07 16:45:25 +00:00
|
|
|
AppendToBuffer(buffer, buffer+mTotalRead, buffer+mTotalRead);
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
|
|
|
mMarkPosition = mCurrentPosition;
|
1999-07-25 17:23:24 +00:00
|
|
|
mIncremental=PR_FALSE;
|
1998-07-24 21:57:43 +00:00
|
|
|
mOwnsStream=PR_FALSE;
|
1999-04-06 20:39:11 +00:00
|
|
|
mInputStream=0;
|
1999-03-07 19:23:28 +00:00
|
|
|
mUnicodeDecoder = 0;
|
1999-03-08 20:00:23 +00:00
|
|
|
mCharsetSource = kCharsetUninitialized;
|
|
|
|
SetDocumentCharset(aCharset, aSource);
|
1999-11-13 03:53:11 +00:00
|
|
|
mNewlinesSkipped=0;
|
1998-07-24 21:57:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use this constructor if you want i/o to be based on strings
|
|
|
|
* the scanner receives. If you pass a null filename, you
|
1998-07-13 21:13:09 +00:00
|
|
|
* can still provide data to the scanner via append.
|
1998-05-14 22:19:08 +00:00
|
|
|
*
|
|
|
|
* @update gess 5/12/98
|
1998-07-13 21:13:09 +00:00
|
|
|
* @param aFilename --
|
1998-05-14 22:19:08 +00:00
|
|
|
* @return
|
|
|
|
*/
|
2001-12-26 03:17:59 +00:00
|
|
|
nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& aCharset, PRInt32 aSource) :
|
2000-04-03 08:09:23 +00:00
|
|
|
mFilename(aFilename)
|
1998-07-13 21:13:09 +00:00
|
|
|
{
|
1999-10-14 23:37:21 +00:00
|
|
|
MOZ_COUNT_CTOR(nsScanner);
|
2002-03-07 16:45:25 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
mSlidingBuffer = nsnull;
|
1998-07-24 21:57:43 +00:00
|
|
|
mIncremental=PR_TRUE;
|
2000-12-12 21:58:14 +00:00
|
|
|
mCountRemaining = 0;
|
1998-05-14 22:19:08 +00:00
|
|
|
mTotalRead=0;
|
1998-07-13 21:13:09 +00:00
|
|
|
mOwnsStream=aCreateStream;
|
1999-04-06 20:39:11 +00:00
|
|
|
mInputStream=0;
|
1998-07-13 21:13:09 +00:00
|
|
|
if(aCreateStream) {
|
1999-04-06 20:39:11 +00:00
|
|
|
mInputStream = new nsInputFileStream(nsFileSpec(aFilename));
|
1998-07-13 21:13:09 +00:00
|
|
|
} //if
|
1999-03-07 19:23:28 +00:00
|
|
|
mUnicodeDecoder = 0;
|
1999-03-08 20:00:23 +00:00
|
|
|
mCharsetSource = kCharsetUninitialized;
|
|
|
|
SetDocumentCharset(aCharset, aSource);
|
1999-11-13 03:53:11 +00:00
|
|
|
mNewlinesSkipped=0;
|
1998-05-14 22:19:08 +00:00
|
|
|
}
|
1998-05-07 07:19:47 +00:00
|
|
|
|
1998-07-10 05:35:23 +00:00
|
|
|
/**
|
1998-07-13 21:13:09 +00:00
|
|
|
* Use this constructor if you want i/o to be stream based.
|
1998-07-10 05:35:23 +00:00
|
|
|
*
|
|
|
|
* @update gess 5/12/98
|
1998-07-13 21:13:09 +00:00
|
|
|
* @param aStream --
|
|
|
|
* @param assumeOwnership --
|
|
|
|
* @param aFilename --
|
1998-07-10 05:35:23 +00:00
|
|
|
* @return
|
|
|
|
*/
|
2002-02-12 21:17:53 +00:00
|
|
|
nsScanner::nsScanner(const nsAString& aFilename,nsInputStream& aStream,const nsString& aCharset, PRInt32 aSource) :
|
2000-04-03 08:09:23 +00:00
|
|
|
mFilename(aFilename)
|
1999-10-14 23:37:21 +00:00
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(nsScanner);
|
2002-03-07 16:45:25 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
mSlidingBuffer = nsnull;
|
1999-07-25 17:23:24 +00:00
|
|
|
mIncremental=PR_FALSE;
|
2000-12-12 21:58:14 +00:00
|
|
|
mCountRemaining = 0;
|
1998-07-10 05:35:23 +00:00
|
|
|
mTotalRead=0;
|
1999-07-25 17:23:24 +00:00
|
|
|
mOwnsStream=PR_FALSE;
|
1999-04-06 20:39:11 +00:00
|
|
|
mInputStream=&aStream;
|
1999-03-07 19:23:28 +00:00
|
|
|
mUnicodeDecoder = 0;
|
1999-03-08 20:00:23 +00:00
|
|
|
mCharsetSource = kCharsetUninitialized;
|
|
|
|
SetDocumentCharset(aCharset, aSource);
|
1999-11-13 03:53:11 +00:00
|
|
|
mNewlinesSkipped=0;
|
1999-02-01 18:23:31 +00:00
|
|
|
}
|
1999-02-16 07:38:27 +00:00
|
|
|
|
1999-07-25 17:23:24 +00:00
|
|
|
|
2002-01-27 22:02:00 +00:00
|
|
|
nsresult nsScanner::SetDocumentCharset(const nsAString& aCharset , PRInt32 aSource) {
|
1999-03-08 20:00:23 +00:00
|
|
|
|
1999-02-01 18:23:31 +00:00
|
|
|
nsresult res = NS_OK;
|
1999-03-08 20:00:23 +00:00
|
|
|
|
|
|
|
if( aSource < mCharsetSource) // priority is lower the the current one , just
|
|
|
|
return res;
|
|
|
|
|
2001-07-25 07:54:28 +00:00
|
|
|
nsCOMPtr<nsICharsetAlias> calias(do_GetService(kCharsetAliasCID, &res));
|
1999-06-14 20:08:13 +00:00
|
|
|
NS_ASSERTION( nsnull != calias, "cannot find charset alias");
|
2000-04-26 01:13:55 +00:00
|
|
|
nsAutoString charsetName; charsetName.Assign(aCharset);
|
1999-03-08 20:00:23 +00:00
|
|
|
if( NS_SUCCEEDED(res) && (nsnull != calias))
|
1999-02-01 18:23:31 +00:00
|
|
|
{
|
1999-03-08 20:00:23 +00:00
|
|
|
PRBool same = PR_FALSE;
|
|
|
|
res = calias->Equals(aCharset, mCharset, &same);
|
|
|
|
if(NS_SUCCEEDED(res) && same)
|
|
|
|
{
|
|
|
|
return NS_OK; // no difference, don't change it
|
|
|
|
}
|
|
|
|
// different, need to change it
|
|
|
|
res = calias->GetPreferred(aCharset, charsetName);
|
|
|
|
|
|
|
|
if(NS_FAILED(res) && (kCharsetUninitialized == mCharsetSource) )
|
|
|
|
{
|
|
|
|
// failed - unknown alias , fallback to ISO-8859-1
|
2001-12-16 11:58:03 +00:00
|
|
|
charsetName.Assign(NS_LITERAL_STRING("ISO-8859-1"));
|
1999-03-08 20:00:23 +00:00
|
|
|
}
|
|
|
|
mCharset = charsetName;
|
|
|
|
mCharsetSource = aSource;
|
|
|
|
|
2001-07-25 07:54:28 +00:00
|
|
|
nsCOMPtr<nsICharsetConverterManager> ccm =
|
|
|
|
do_GetService(kCharsetConverterManagerCID, &res);
|
1999-02-01 18:23:31 +00:00
|
|
|
if(NS_SUCCEEDED(res) && (nsnull != ccm))
|
|
|
|
{
|
|
|
|
nsIUnicodeDecoder * decoder = nsnull;
|
1999-03-08 20:00:23 +00:00
|
|
|
res = ccm->GetUnicodeDecoder(&mCharset, &decoder);
|
1999-02-01 18:23:31 +00:00
|
|
|
if(NS_SUCCEEDED(res) && (nsnull != decoder))
|
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mUnicodeDecoder);
|
|
|
|
|
|
|
|
mUnicodeDecoder = decoder;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
1998-07-10 05:35:23 +00:00
|
|
|
}
|
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* default destructor
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsScanner::~nsScanner() {
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (mSlidingBuffer) {
|
|
|
|
delete mSlidingBuffer;
|
|
|
|
}
|
|
|
|
|
1999-10-14 23:37:21 +00:00
|
|
|
MOZ_COUNT_DTOR(nsScanner);
|
|
|
|
|
1999-04-06 20:39:11 +00:00
|
|
|
if(mInputStream) {
|
|
|
|
mInputStream->close();
|
1998-07-10 05:35:23 +00:00
|
|
|
if(mOwnsStream)
|
1999-04-06 20:39:11 +00:00
|
|
|
delete mInputStream;
|
1998-05-04 23:36:46 +00:00
|
|
|
}
|
1999-04-06 20:39:11 +00:00
|
|
|
mInputStream=0;
|
1999-02-01 18:23:31 +00:00
|
|
|
NS_IF_RELEASE(mUnicodeDecoder);
|
1998-05-14 22:19:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets current offset position of input stream to marked position.
|
|
|
|
* This allows us to back up to this point if the need should arise,
|
|
|
|
* such as when tokenization gets interrupted.
|
|
|
|
* NOTE: IT IS REALLY BAD FORM TO CALL RELEASE WITHOUT CALLING MARK FIRST!
|
|
|
|
*
|
|
|
|
* @update gess 5/12/98
|
|
|
|
* @param
|
|
|
|
* @return
|
|
|
|
*/
|
2000-12-12 21:58:14 +00:00
|
|
|
void nsScanner::RewindToMark(void){
|
2002-03-07 16:45:25 +00:00
|
|
|
mCountRemaining += (Distance(mMarkPosition, mCurrentPosition));
|
|
|
|
mCurrentPosition = mMarkPosition;
|
1998-05-14 22:19:08 +00:00
|
|
|
}
|
|
|
|
|
1998-07-28 01:08:12 +00:00
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
/**
|
|
|
|
* Records current offset position in input stream. This allows us
|
|
|
|
* to back up to this point if the need should arise, such as when
|
|
|
|
* tokenization gets interrupted.
|
|
|
|
*
|
1998-08-03 21:04:54 +00:00
|
|
|
* @update gess 7/29/98
|
1998-05-14 22:19:08 +00:00
|
|
|
* @param
|
|
|
|
* @return
|
|
|
|
*/
|
2000-12-12 21:58:14 +00:00
|
|
|
void nsScanner::Mark() {
|
|
|
|
if (mSlidingBuffer) {
|
|
|
|
mMarkPosition = mCurrentPosition;
|
|
|
|
mSlidingBuffer->DiscardPrefix(mMarkPosition);
|
1998-08-03 21:04:54 +00:00
|
|
|
}
|
1998-05-14 22:19:08 +00:00
|
|
|
}
|
1998-08-03 21:04:54 +00:00
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
|
2000-01-15 20:35:57 +00:00
|
|
|
/**
|
|
|
|
* Insert data to our underlying input buffer as
|
|
|
|
* if it were read from an input stream.
|
|
|
|
*
|
|
|
|
* @update harishd 01/12/99
|
|
|
|
* @return error code
|
|
|
|
*/
|
2001-02-13 21:26:58 +00:00
|
|
|
PRBool nsScanner::UngetReadable(const nsAReadableString& aBuffer) {
|
|
|
|
|
2002-03-07 16:45:25 +00:00
|
|
|
mSlidingBuffer->UngetReadable(aBuffer,mCurrentPosition);
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition); // Insertion invalidated our iterators
|
|
|
|
mSlidingBuffer->EndReading(mEndPosition);
|
2001-02-13 21:26:58 +00:00
|
|
|
mTotalRead += aBuffer.Length();
|
|
|
|
|
2000-01-15 20:35:57 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
/**
|
1998-07-13 21:13:09 +00:00
|
|
|
* Append data to our underlying input buffer as
|
|
|
|
* if it were read from an input stream.
|
1998-05-14 22:19:08 +00:00
|
|
|
*
|
|
|
|
* @update gess4/3/98
|
1998-08-03 21:04:54 +00:00
|
|
|
* @return error code
|
1998-05-14 22:19:08 +00:00
|
|
|
*/
|
2001-03-31 22:44:05 +00:00
|
|
|
nsresult nsScanner::Append(const nsAReadableString& aBuffer) {
|
2002-03-07 16:45:25 +00:00
|
|
|
|
|
|
|
PRUnichar* buffer = ToNewUnicode(aBuffer);
|
|
|
|
PRUint32 bufLen = aBuffer.Length();
|
|
|
|
mTotalRead += bufLen;
|
|
|
|
|
|
|
|
AppendToBuffer(buffer, buffer+bufLen, buffer+bufLen);
|
1999-12-03 00:30:29 +00:00
|
|
|
|
2001-03-31 22:44:05 +00:00
|
|
|
return NS_OK;
|
1998-05-14 22:19:08 +00:00
|
|
|
}
|
|
|
|
|
1998-05-21 20:38:32 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @update gess 5/21/98
|
|
|
|
* @param
|
|
|
|
* @return
|
|
|
|
*/
|
2001-03-31 22:44:05 +00:00
|
|
|
nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|
|
|
nsresult res=NS_OK;
|
2001-07-13 18:21:23 +00:00
|
|
|
PRUnichar *unichars, *start;
|
1999-03-07 19:23:28 +00:00
|
|
|
if(mUnicodeDecoder) {
|
2001-07-13 18:21:23 +00:00
|
|
|
PRInt32 unicharBufLen = 0;
|
|
|
|
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
|
2002-03-07 16:45:25 +00:00
|
|
|
start = unichars = (PRUnichar*)nsMemory::Alloc((unicharBufLen+1) * sizeof(PRUnichar));
|
|
|
|
NS_ENSURE_TRUE(unichars,NS_ERROR_OUT_OF_MEMORY);
|
2001-07-13 18:21:23 +00:00
|
|
|
|
|
|
|
PRInt32 totalChars = 0;
|
|
|
|
PRInt32 unicharLength = unicharBufLen;
|
|
|
|
do {
|
|
|
|
PRInt32 srcLength = aLen;
|
1999-09-01 22:50:50 +00:00
|
|
|
res = mUnicodeDecoder->Convert(aBuffer, &srcLength, unichars, &unicharLength);
|
1999-08-30 22:25:17 +00:00
|
|
|
|
2001-07-13 18:21:23 +00:00
|
|
|
totalChars += unicharLength;
|
|
|
|
// Continuation of failure case
|
2000-12-12 21:58:14 +00:00
|
|
|
if(NS_FAILED(res)) {
|
2001-07-13 18:21:23 +00:00
|
|
|
// if we failed, we consume one byte, replace it with U+FFFD
|
|
|
|
// and try the conversion again.
|
2000-12-12 21:58:14 +00:00
|
|
|
unichars[unicharLength++] = (PRUnichar)0xFFFD;
|
2001-07-13 18:21:23 +00:00
|
|
|
unichars = unichars + unicharLength;
|
|
|
|
unicharLength = unicharBufLen - (++totalChars);
|
2000-12-12 21:58:14 +00:00
|
|
|
|
1999-07-18 23:43:52 +00:00
|
|
|
mUnicodeDecoder->Reset();
|
2001-07-13 18:21:23 +00:00
|
|
|
|
|
|
|
if(((PRUint32) (srcLength + 1)) > aLen) {
|
|
|
|
srcLength = aLen;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
srcLength++;
|
|
|
|
}
|
|
|
|
|
|
|
|
aBuffer += srcLength;
|
|
|
|
aLen -= srcLength;
|
1999-07-19 05:30:49 +00:00
|
|
|
}
|
1999-07-18 23:43:52 +00:00
|
|
|
} while (NS_FAILED(res) && (aLen > 0));
|
2001-07-13 18:21:23 +00:00
|
|
|
|
|
|
|
AppendToBuffer(start,
|
|
|
|
start+totalChars,
|
|
|
|
start+unicharBufLen);
|
|
|
|
mTotalRead += totalChars;
|
|
|
|
|
|
|
|
// Don't propagate return code of unicode decoder
|
|
|
|
// since it doesn't reflect on our success or failure
|
|
|
|
// - Ref. bug 87110
|
|
|
|
res = NS_OK;
|
1999-03-07 19:23:28 +00:00
|
|
|
}
|
1999-07-19 05:30:49 +00:00
|
|
|
else {
|
2002-03-07 16:45:25 +00:00
|
|
|
nsDependentCString str(aBuffer, aLen);
|
|
|
|
unichars = ToNewUnicode(str);
|
|
|
|
AppendToBuffer(unichars, unichars+aLen, unichars+aLen);
|
1999-03-07 19:23:28 +00:00
|
|
|
mTotalRead+=aLen;
|
|
|
|
}
|
1999-02-01 18:23:31 +00:00
|
|
|
|
2001-03-31 22:44:05 +00:00
|
|
|
return res;
|
1998-05-21 20:38:32 +00:00
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1998-05-07 07:19:47 +00:00
|
|
|
/**
|
|
|
|
* Grab data from underlying stream.
|
|
|
|
*
|
1998-04-25 19:45:14 +00:00
|
|
|
* @update gess4/3/98
|
1998-05-07 07:19:47 +00:00
|
|
|
* @return error code
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::FillBuffer(void) {
|
|
|
|
nsresult result=NS_OK;
|
1998-05-07 07:19:47 +00:00
|
|
|
|
1999-04-06 20:39:11 +00:00
|
|
|
if(!mInputStream) {
|
2000-01-19 02:38:33 +00:00
|
|
|
#if 0
|
1998-04-13 20:24:54 +00:00
|
|
|
//This is DEBUG code!!!!!! XXX DEBUG XXX
|
|
|
|
//If you're here, it means someone tried to load a
|
|
|
|
//non-existent document. So as a favor, we emit a
|
|
|
|
//little bit of HTML explaining the error.
|
|
|
|
if(0==mTotalRead) {
|
1998-05-14 22:19:08 +00:00
|
|
|
mBuffer.Append((const char*)kBadHTMLText);
|
1998-07-13 21:13:09 +00:00
|
|
|
mBuffer.Append(mFilename);
|
2000-01-19 02:38:33 +00:00
|
|
|
mTotalRead+=mBuffer.Length();
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
2000-01-19 02:38:33 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
result=kEOF;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-07-13 21:13:09 +00:00
|
|
|
else {
|
1998-04-13 20:24:54 +00:00
|
|
|
PRInt32 numread=0;
|
2002-03-07 16:45:25 +00:00
|
|
|
char* buf = new char[kBufsize+1];
|
1998-05-07 07:19:47 +00:00
|
|
|
buf[kBufsize]=0;
|
|
|
|
|
1999-04-06 20:39:11 +00:00
|
|
|
if(mInputStream) {
|
|
|
|
numread = mInputStream->read(buf, kBufsize);
|
2002-03-07 16:45:25 +00:00
|
|
|
if (0 == numread) {
|
|
|
|
delete [] buf;
|
1998-08-10 21:08:21 +00:00
|
|
|
return kEOF;
|
2002-03-07 16:45:25 +00:00
|
|
|
}
|
1998-05-14 22:19:08 +00:00
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
|
1999-12-03 00:30:29 +00:00
|
|
|
if((0<numread) && (0==result)) {
|
2002-03-07 16:45:25 +00:00
|
|
|
nsDependentCString str(buf, numread);
|
|
|
|
PRUnichar* unichars = ToNewUnicode(str);
|
|
|
|
AppendToBuffer(unichars, unichars+numread, unichars+kBufsize+1);
|
1999-12-03 00:30:29 +00:00
|
|
|
}
|
2002-03-07 16:45:25 +00:00
|
|
|
delete [] buf;
|
2000-12-12 21:58:14 +00:00
|
|
|
mTotalRead+=numread;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-05-14 22:19:08 +00:00
|
|
|
|
1999-01-09 01:09:02 +00:00
|
|
|
return result;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* determine if the scanner has reached EOF
|
|
|
|
*
|
1998-05-14 22:19:08 +00:00
|
|
|
* @update gess 5/12/98
|
1998-04-13 20:24:54 +00:00
|
|
|
* @param
|
1999-01-09 01:09:02 +00:00
|
|
|
* @return 0=!eof 1=eof
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::Eof() {
|
1998-07-15 22:30:39 +00:00
|
|
|
nsresult theError=NS_OK;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
1998-05-14 22:19:08 +00:00
|
|
|
|
2000-12-18 20:44:10 +00:00
|
|
|
theError=FillBuffer();
|
2000-12-12 21:58:14 +00:00
|
|
|
|
1998-07-15 22:30:39 +00:00
|
|
|
if(NS_OK==theError) {
|
2000-12-12 21:58:14 +00:00
|
|
|
if (0==(PRUint32)mSlidingBuffer->Length()) {
|
1998-07-15 22:30:39 +00:00
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
}
|
1998-05-14 22:19:08 +00:00
|
|
|
|
|
|
|
return theError;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* retrieve next char from scanners internal input stream
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return error code reflecting read status
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::GetChar(PRUnichar& aChar) {
|
1998-07-23 21:10:19 +00:00
|
|
|
nsresult result=NS_OK;
|
1999-09-30 04:04:53 +00:00
|
|
|
aChar=0;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCurrentPosition == mEndPosition) {
|
1998-07-23 21:10:19 +00:00
|
|
|
result=Eof();
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
1998-07-23 21:10:19 +00:00
|
|
|
|
1999-12-03 00:30:29 +00:00
|
|
|
if(NS_OK == result){
|
2000-12-12 21:58:14 +00:00
|
|
|
aChar=*mCurrentPosition++;
|
|
|
|
mCountRemaining--;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-05-14 22:19:08 +00:00
|
|
|
return result;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* peek ahead to consume next char from scanner's internal
|
|
|
|
* input buffer
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
2000-12-12 21:58:14 +00:00
|
|
|
nsresult nsScanner::Peek(PRUnichar& aChar, PRUint32 aOffset) {
|
1998-07-23 21:10:19 +00:00
|
|
|
nsresult result=NS_OK;
|
1999-01-09 01:09:02 +00:00
|
|
|
aChar=0;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCurrentPosition == mEndPosition) {
|
1998-07-23 21:10:19 +00:00
|
|
|
result=Eof();
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
1998-07-23 21:10:19 +00:00
|
|
|
|
1999-12-03 00:30:29 +00:00
|
|
|
if(NS_OK == result){
|
2000-12-12 21:58:14 +00:00
|
|
|
if (aOffset) {
|
2000-12-18 20:44:10 +00:00
|
|
|
while ((NS_OK == result) && (mCountRemaining <= aOffset)) {
|
2000-12-12 21:58:14 +00:00
|
|
|
result = Eof();
|
|
|
|
}
|
2000-12-18 20:44:10 +00:00
|
|
|
|
|
|
|
if (NS_OK == result) {
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> pos = mCurrentPosition;
|
|
|
|
pos.advance(aOffset);
|
|
|
|
aChar=*pos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aChar=*mCurrentPosition;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1999-12-03 00:30:29 +00:00
|
|
|
|
1998-05-14 22:19:08 +00:00
|
|
|
return result;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
nsresult nsScanner::Peek(nsAWritableString& aStr, PRInt32 aNumChars)
|
|
|
|
{
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCurrentPosition == mEndPosition) {
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsReadingIterator<PRUnichar> start, end;
|
|
|
|
|
|
|
|
start = mCurrentPosition;
|
|
|
|
|
|
|
|
if (mCountRemaining < PRUint32(aNumChars)) {
|
|
|
|
end = mEndPosition;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
end = start;
|
|
|
|
end.advance(aNumChars);
|
|
|
|
}
|
|
|
|
|
|
|
|
CopyUnicodeTo(start, end, aStr);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 22:30:39 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* Skip whitespace on scanner input stream
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return error status
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::SkipWhitespace(void) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
nsReadingIterator<PRUnichar> current;
|
|
|
|
PRBool found;
|
|
|
|
PRBool skipped = PR_FALSE;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1999-11-13 03:53:11 +00:00
|
|
|
mNewlinesSkipped = 0;
|
2000-12-12 21:58:14 +00:00
|
|
|
current = mCurrentPosition;
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2001-08-16 21:19:33 +00:00
|
|
|
|
|
|
|
if (result == kEOF) {
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
while (current != mEndPosition) {
|
2000-12-12 21:58:14 +00:00
|
|
|
switch(theChar) {
|
|
|
|
case '\n': mNewlinesSkipped++;
|
|
|
|
case ' ' :
|
|
|
|
case '\r':
|
|
|
|
case '\b':
|
|
|
|
case '\t':
|
|
|
|
found=PR_TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
found=PR_FALSE;
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
if(!found) {
|
|
|
|
break;
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
++current;
|
|
|
|
theChar = *current;
|
|
|
|
skipped = PR_TRUE;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 21:19:33 +00:00
|
|
|
if (skipped) {
|
2001-08-16 05:24:17 +00:00
|
|
|
SetPosition(current);
|
2001-08-16 21:19:33 +00:00
|
|
|
if (current == mEndPosition) {
|
|
|
|
return Eof();
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
|
|
|
* Skip over chars as long as they equal given char
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return error code
|
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
PRUnichar ch=0;
|
1998-07-15 22:30:39 +00:00
|
|
|
nsresult result=NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 22:30:39 +00:00
|
|
|
while(NS_OK==result) {
|
2000-12-12 21:58:14 +00:00
|
|
|
result=Peek(ch);
|
1998-07-15 22:30:39 +00:00
|
|
|
if(NS_OK == result) {
|
1998-04-30 20:23:07 +00:00
|
|
|
if(ch!=aSkipChar) {
|
|
|
|
break;
|
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
GetChar(ch);
|
1998-04-30 20:23:07 +00:00
|
|
|
}
|
|
|
|
else break;
|
|
|
|
} //while
|
|
|
|
return result;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Skip over chars as long as they're in aSkipSet
|
1998-04-13 20:24:54 +00:00
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
1998-08-29 05:08:20 +00:00
|
|
|
* @param aSkipSet is an ordered string.
|
1998-04-13 20:24:54 +00:00
|
|
|
* @return error code
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::SkipOver(nsString& aSkipSet){
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
1999-01-09 01:09:02 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=NS_OK;
|
1998-04-30 20:23:07 +00:00
|
|
|
|
1998-07-15 22:30:39 +00:00
|
|
|
while(NS_OK==result) {
|
2000-12-12 21:58:14 +00:00
|
|
|
result=Peek(theChar);
|
1998-07-15 22:30:39 +00:00
|
|
|
if(NS_OK == result) {
|
1999-07-19 03:09:16 +00:00
|
|
|
PRInt32 pos=aSkipSet.FindChar(theChar);
|
1998-04-25 19:45:14 +00:00
|
|
|
if(kNotFound==pos) {
|
|
|
|
break;
|
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
GetChar(theChar);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
else break;
|
|
|
|
} //while
|
|
|
|
return result;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-29 05:13:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Skip over chars until they're in aValidSet
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
1998-08-29 05:08:20 +00:00
|
|
|
* @param aValid set is an ordered string that
|
|
|
|
* contains chars you're looking for
|
1998-07-29 05:13:35 +00:00
|
|
|
* @return error code
|
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::SkipTo(nsString& aValidSet){
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
1998-07-29 05:13:35 +00:00
|
|
|
PRUnichar ch=0;
|
|
|
|
nsresult result=NS_OK;
|
|
|
|
|
|
|
|
while(NS_OK==result) {
|
2000-12-12 21:58:14 +00:00
|
|
|
result=Peek(ch);
|
1998-07-29 05:13:35 +00:00
|
|
|
if(NS_OK == result) {
|
1999-07-19 03:09:16 +00:00
|
|
|
PRInt32 pos=aValidSet.FindChar(ch);
|
1998-07-29 05:13:35 +00:00
|
|
|
if(kNotFound!=pos) {
|
|
|
|
break;
|
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
GetChar(ch);
|
1998-07-29 05:13:35 +00:00
|
|
|
}
|
|
|
|
else break;
|
|
|
|
} //while
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-10-05 04:54:53 +00:00
|
|
|
#if 0
|
1999-09-30 04:04:53 +00:00
|
|
|
void DoErrTest(nsString& aString) {
|
|
|
|
PRInt32 pos=aString.FindChar(0);
|
|
|
|
if(kNotFound<pos) {
|
1999-10-05 04:54:53 +00:00
|
|
|
if(aString.Length()-1!=pos) {
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DoErrTest(nsCString& aString) {
|
|
|
|
PRInt32 pos=aString.FindChar(0);
|
|
|
|
if(kNotFound<pos) {
|
1999-10-05 04:54:53 +00:00
|
|
|
if(aString.Length()-1!=pos) {
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
|
|
|
}
|
1999-10-05 04:54:53 +00:00
|
|
|
#endif
|
1998-07-29 05:13:35 +00:00
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* Skip over chars as long as they're in aValidSet
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
1998-08-29 05:08:20 +00:00
|
|
|
* @param aValidSet is an ordered string containing the
|
|
|
|
* characters you want to skip
|
1998-04-13 20:24:54 +00:00
|
|
|
* @return error code
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsresult nsScanner::SkipPast(nsString& aValidSet){
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("Error: SkipPast not yet implemented.");
|
1998-07-15 22:30:39 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
2000-02-11 12:11:29 +00:00
|
|
|
/**
|
|
|
|
* Consume characters until you did not find the terminal char
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param aString - receives new data from stream
|
|
|
|
* @param aIgnore - If set ignores ':','-','_'
|
|
|
|
* @return error code
|
|
|
|
*/
|
2000-12-12 21:58:14 +00:00
|
|
|
nsresult nsScanner::GetIdentifier(nsString& aString,PRBool allowPunct) {
|
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
2000-02-11 12:11:29 +00:00
|
|
|
|
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> current, end;
|
2000-02-11 12:11:29 +00:00
|
|
|
PRBool found=PR_FALSE;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
current = mCurrentPosition;
|
|
|
|
end = mEndPosition;
|
2000-02-11 12:11:29 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
while(current != end) {
|
2000-02-11 12:11:29 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
theChar=*current;
|
2000-02-11 12:11:29 +00:00
|
|
|
if(theChar) {
|
|
|
|
found=PR_FALSE;
|
2000-03-25 03:35:50 +00:00
|
|
|
switch(theChar) {
|
|
|
|
case ':':
|
|
|
|
case '_':
|
|
|
|
case '-':
|
|
|
|
found=allowPunct;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if(('a'<=theChar) && (theChar<='z'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
else if(('A'<=theChar) && (theChar<='Z'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
else if(('0'<=theChar) && (theChar<='9'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
2000-02-11 12:11:29 +00:00
|
|
|
|
|
|
|
if(!found) {
|
2000-12-12 21:58:14 +00:00
|
|
|
// If we the current character isn't a valid character for
|
|
|
|
// the identifier, we're done. Copy the results into
|
|
|
|
// the string passed in.
|
|
|
|
CopyUnicodeTo(mCurrentPosition, current, aString);
|
2000-02-11 12:11:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2000-02-11 12:11:29 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
result = Eof();
|
|
|
|
}
|
|
|
|
|
2000-02-11 12:11:29 +00:00
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
1999-12-02 10:14:42 +00:00
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
/**
|
2000-01-27 02:27:58 +00:00
|
|
|
* Consume characters until you did not find the terminal char
|
1999-09-30 04:04:53 +00:00
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
2000-01-27 02:27:58 +00:00
|
|
|
* @param aString - receives new data from stream
|
2000-03-25 03:35:50 +00:00
|
|
|
* @param allowPunct - If set ignores ':','-','_'
|
1999-09-30 04:04:53 +00:00
|
|
|
* @return error code
|
|
|
|
*/
|
2000-03-25 03:35:50 +00:00
|
|
|
nsresult nsScanner::ReadIdentifier(nsString& aString,PRBool allowPunct) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
1999-09-30 04:04:53 +00:00
|
|
|
PRBool found=PR_FALSE;
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = mCurrentPosition;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
|
|
|
while(current != end) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
theChar=*current;
|
1999-09-30 04:04:53 +00:00
|
|
|
if(theChar) {
|
|
|
|
found=PR_FALSE;
|
|
|
|
switch(theChar) {
|
|
|
|
case ':':
|
|
|
|
case '_':
|
|
|
|
case '-':
|
2000-03-25 03:35:50 +00:00
|
|
|
found=allowPunct;
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if(('a'<=theChar) && (theChar<='z'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
else if(('A'<=theChar) && (theChar<='Z'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
else if(('0'<=theChar) && (theChar<='9'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!found) {
|
2000-12-12 21:58:14 +00:00
|
|
|
AppendUnicodeTo(mCurrentPosition, current, aString);
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsScanner::ReadIdentifier(nsReadingIterator<PRUnichar>& aStart,
|
|
|
|
nsReadingIterator<PRUnichar>& aEnd,
|
|
|
|
PRBool allowPunct) {
|
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
|
|
|
PRBool found=PR_FALSE;
|
|
|
|
|
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = mCurrentPosition;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
|
|
|
while(current != end) {
|
|
|
|
|
|
|
|
theChar=*current;
|
|
|
|
if(theChar) {
|
|
|
|
found=PR_FALSE;
|
|
|
|
switch(theChar) {
|
|
|
|
case ':':
|
|
|
|
case '_':
|
|
|
|
case '-':
|
|
|
|
found=allowPunct;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if(('a'<=theChar) && (theChar<='z'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
else if(('A'<=theChar) && (theChar<='Z'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
else if(('0'<=theChar) && (theChar<='9'))
|
|
|
|
found=PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!found) {
|
|
|
|
aStart = mCurrentPosition;
|
|
|
|
aEnd = current;
|
|
|
|
break;
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
return Eof();
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2001-07-05 22:20:34 +00:00
|
|
|
* Consume digits
|
1999-09-30 04:04:53 +00:00
|
|
|
*
|
2001-07-05 22:20:34 +00:00
|
|
|
* @param aString - should contain digits
|
1999-09-30 04:04:53 +00:00
|
|
|
* @return error code
|
|
|
|
*/
|
2001-07-05 22:20:34 +00:00
|
|
|
nsresult nsScanner::ReadNumber(nsString& aString,PRInt32 aBase) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2001-07-05 22:20:34 +00:00
|
|
|
NS_ASSERTION(aBase == 10 || aBase == 16,"base value not supported");
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
2001-07-05 22:20:34 +00:00
|
|
|
PRBool done = PR_FALSE;
|
2000-12-12 21:58:14 +00:00
|
|
|
while(current != end) {
|
|
|
|
theChar=*current;
|
1999-09-30 04:04:53 +00:00
|
|
|
if(theChar) {
|
2001-07-05 22:20:34 +00:00
|
|
|
done = (theChar < '0' || theChar > '9') &&
|
|
|
|
((aBase == 16)? (theChar < 'A' || theChar > 'F') &&
|
|
|
|
(theChar < 'a' || theChar > 'f')
|
|
|
|
:PR_TRUE);
|
|
|
|
if(done) {
|
2000-12-12 21:58:14 +00:00
|
|
|
AppendUnicodeTo(origin, current, aString);
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsScanner::ReadNumber(nsReadingIterator<PRUnichar>& aStart,
|
2001-07-05 22:20:34 +00:00
|
|
|
nsReadingIterator<PRUnichar>& aEnd,
|
|
|
|
PRInt32 aBase) {
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2001-07-05 22:20:34 +00:00
|
|
|
NS_ASSERTION(aBase == 10 || aBase == 16,"base value not supported");
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
|
|
|
|
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
2001-07-05 22:20:34 +00:00
|
|
|
PRBool done = PR_FALSE;
|
2000-12-12 21:58:14 +00:00
|
|
|
while(current != end) {
|
|
|
|
theChar=*current;
|
|
|
|
if(theChar) {
|
2001-07-05 22:20:34 +00:00
|
|
|
done = (theChar < '0' || theChar > '9') &&
|
|
|
|
((aBase == 16)? (theChar < 'A' || theChar > 'F') &&
|
|
|
|
(theChar < 'a' || theChar > 'f')
|
|
|
|
:PR_TRUE);
|
|
|
|
if(done) {
|
2000-12-12 21:58:14 +00:00
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
break;
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Consume characters until you find the terminal char
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param aString receives new data from stream
|
|
|
|
* @param addTerminal tells us whether to append terminal to aString
|
|
|
|
* @return error code
|
|
|
|
*/
|
|
|
|
nsresult nsScanner::ReadWhitespace(nsString& aString) {
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
1999-09-30 04:04:53 +00:00
|
|
|
PRBool found=PR_FALSE;
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
|
|
|
while(current != end) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
theChar=*current;
|
1999-09-30 04:04:53 +00:00
|
|
|
if(theChar) {
|
|
|
|
switch(theChar) {
|
|
|
|
case ' ':
|
|
|
|
case '\b':
|
|
|
|
case '\t':
|
2000-03-25 03:35:50 +00:00
|
|
|
case kLF:
|
|
|
|
case kCR:
|
1999-09-30 04:04:53 +00:00
|
|
|
found=PR_TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
found=PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(!found) {
|
2000-12-12 21:58:14 +00:00
|
|
|
AppendUnicodeTo(origin, current, aString);
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
nsresult nsScanner::ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
|
|
|
|
nsReadingIterator<PRUnichar>& aEnd) {
|
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
|
|
|
PRBool found=PR_FALSE;
|
|
|
|
|
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
|
|
|
while(current != end) {
|
|
|
|
|
|
|
|
theChar=*current;
|
|
|
|
if(theChar) {
|
|
|
|
switch(theChar) {
|
|
|
|
case ' ':
|
|
|
|
case '\b':
|
|
|
|
case '\t':
|
|
|
|
case kLF:
|
|
|
|
case kCR:
|
|
|
|
found=PR_TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
found=PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(!found) {
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
return Eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1999-09-19 16:51:08 +00:00
|
|
|
/**
|
|
|
|
* Consume chars as long as they are <i>in</i> the
|
|
|
|
* given validSet of input chars.
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param aString will contain the result of this method
|
|
|
|
* @param aValidSet is an ordered string that contains the
|
|
|
|
* valid characters
|
|
|
|
* @return error code
|
|
|
|
*/
|
|
|
|
nsresult nsScanner::ReadWhile(nsString& aString,
|
2000-03-12 09:14:14 +00:00
|
|
|
nsString& aValidSet,
|
1999-09-19 16:51:08 +00:00
|
|
|
PRBool addTerminal){
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current, end;
|
1999-09-19 16:51:08 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
|
|
|
while(current != end) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
theChar=*current;
|
1999-09-30 04:04:53 +00:00
|
|
|
if(theChar) {
|
2000-03-12 09:14:14 +00:00
|
|
|
PRInt32 pos=aValidSet.FindChar(theChar);
|
1999-09-19 16:51:08 +00:00
|
|
|
if(kNotFound==pos) {
|
2000-12-12 21:58:14 +00:00
|
|
|
if(addTerminal)
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2000-12-12 21:58:14 +00:00
|
|
|
AppendUnicodeTo(origin, current, aString);
|
1999-09-19 16:51:08 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
return Eof();
|
1999-09-19 16:51:08 +00:00
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
1999-09-19 16:51:08 +00:00
|
|
|
return result;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1999-09-19 16:51:08 +00:00
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-08-29 05:08:20 +00:00
|
|
|
* Consume characters until you encounter one contained in given
|
1998-04-13 20:24:54 +00:00
|
|
|
* input set.
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
1998-08-29 05:08:20 +00:00
|
|
|
* @param aString will contain the result of this method
|
|
|
|
* @param aTerminalSet is an ordered string that contains
|
|
|
|
* the set of INVALID characters
|
1998-04-13 20:24:54 +00:00
|
|
|
* @return error code
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
2001-04-11 02:28:17 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsAWritableString& aString,
|
2001-08-16 05:24:17 +00:00
|
|
|
const nsReadEndCondition& aEndCondition,
|
2001-04-11 02:28:17 +00:00
|
|
|
PRBool addTerminal)
|
|
|
|
{
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current;
|
|
|
|
const PRUnichar* setstart = aEndCondition.mChars;
|
2001-04-28 02:03:18 +00:00
|
|
|
const PRUnichar* setcurrent;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2001-08-16 21:19:33 +00:00
|
|
|
|
|
|
|
if (result == kEOF) {
|
|
|
|
return Eof();
|
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
|
|
|
while (current != mEndPosition) {
|
|
|
|
// Filter out completely wrong characters
|
|
|
|
// Check if all bits are in the required area
|
|
|
|
if(!(theChar & aEndCondition.mFilter)) {
|
|
|
|
// They were. Do a thorough check.
|
2000-12-12 21:58:14 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
setcurrent = setstart;
|
2001-04-28 02:03:18 +00:00
|
|
|
while (*setcurrent) {
|
|
|
|
if (*setcurrent == theChar) {
|
|
|
|
goto found;
|
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++setcurrent;
|
1999-09-19 16:51:08 +00:00
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2001-08-16 05:24:17 +00:00
|
|
|
theChar = *current;
|
1999-09-19 16:51:08 +00:00
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
// If we are here, we didn't find any terminator in the string and
|
|
|
|
// current = mEndPosition
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
2001-08-16 05:24:17 +00:00
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
return Eof();
|
|
|
|
|
|
|
|
found:
|
|
|
|
if(addTerminal)
|
|
|
|
++current;
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
SetPosition(current);
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
//DoErrTest(aString);
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
return NS_OK;
|
1999-09-19 16:51:08 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsReadingIterator<PRUnichar>& aStart,
|
|
|
|
nsReadingIterator<PRUnichar>& aEnd,
|
2001-08-16 05:24:17 +00:00
|
|
|
const nsReadEndCondition &aEndCondition,
|
2001-04-11 02:28:17 +00:00
|
|
|
PRBool addTerminal)
|
|
|
|
{
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current;
|
|
|
|
const PRUnichar* setstart = aEndCondition.mChars;
|
2001-04-28 02:03:18 +00:00
|
|
|
const PRUnichar* setcurrent;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
PRUnichar theChar=0;
|
|
|
|
nsresult result=Peek(theChar);
|
2001-08-16 21:19:33 +00:00
|
|
|
|
|
|
|
if (result == kEOF) {
|
|
|
|
aStart = aEnd = current;
|
|
|
|
return Eof();
|
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
|
|
|
while (current != mEndPosition) {
|
|
|
|
// Filter out completely wrong characters
|
|
|
|
// Check if all bits are in the required area
|
|
|
|
if(!(theChar & aEndCondition.mFilter)) {
|
|
|
|
// They were. Do a thorough check.
|
|
|
|
setcurrent = setstart;
|
2001-04-28 02:03:18 +00:00
|
|
|
while (*setcurrent) {
|
|
|
|
if (*setcurrent == theChar) {
|
|
|
|
goto found;
|
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
++setcurrent;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2001-08-16 05:24:17 +00:00
|
|
|
theChar = *current;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
// If we are here, we didn't find any terminator in the string and
|
|
|
|
// current = mEndPosition
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
2001-08-16 05:24:17 +00:00
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
return Eof();
|
2000-12-12 21:58:14 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
found:
|
|
|
|
if(addTerminal)
|
|
|
|
++current;
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
SetPosition(current);
|
|
|
|
|
|
|
|
return NS_OK;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* Consumes chars until you see the given terminalChar
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return error code
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
2001-04-11 02:28:17 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsAWritableString& aString,
|
|
|
|
PRUnichar aTerminalChar,
|
|
|
|
PRBool addTerminal)
|
|
|
|
{
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
nsReadingIterator<PRUnichar> origin, current;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
PRUnichar theChar;
|
|
|
|
nsresult result=Peek(theChar);
|
|
|
|
|
|
|
|
while (current != mEndPosition) {
|
|
|
|
if (aTerminalChar == theChar) {
|
|
|
|
if(addTerminal)
|
|
|
|
++current;
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
SetPosition(current);
|
|
|
|
return NS_OK;
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
2001-06-19 22:38:45 +00:00
|
|
|
++current;
|
2001-08-16 05:24:17 +00:00
|
|
|
theChar = *current;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
// If we are here, we didn't find any terminator in the string and
|
|
|
|
// current = mEndPosition
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
2001-08-16 05:24:17 +00:00
|
|
|
return Eof();
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
void nsScanner::BindSubstring(nsSlidingSubstring& aSubstring, const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd)
|
|
|
|
{
|
|
|
|
aSubstring.Rebind(*mSlidingBuffer, aStart, aEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsScanner::CurrentPosition(nsReadingIterator<PRUnichar>& aPosition)
|
|
|
|
{
|
|
|
|
aPosition = mCurrentPosition;
|
|
|
|
}
|
1999-12-03 00:30:29 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
void nsScanner::EndReading(nsReadingIterator<PRUnichar>& aPosition)
|
|
|
|
{
|
|
|
|
aPosition = mEndPosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsScanner::SetPosition(nsReadingIterator<PRUnichar>& aPosition, PRBool aTerminate, PRBool aReverse)
|
|
|
|
{
|
|
|
|
if (mSlidingBuffer) {
|
|
|
|
if (aReverse) {
|
|
|
|
mCountRemaining += (Distance(aPosition, mCurrentPosition));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mCountRemaining -= (Distance(mCurrentPosition, aPosition));
|
|
|
|
}
|
|
|
|
mCurrentPosition = aPosition;
|
|
|
|
if (aTerminate && (mCurrentPosition == mEndPosition)) {
|
|
|
|
mMarkPosition = mCurrentPosition;
|
|
|
|
mSlidingBuffer->DiscardPrefix(mCurrentPosition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsScanner::ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
|
|
|
|
PRUnichar aChar)
|
|
|
|
{
|
|
|
|
if (mSlidingBuffer) {
|
|
|
|
mSlidingBuffer->ReplaceCharacter(aPosition, aChar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsScanner::AppendToBuffer(PRUnichar* aStorageStart,
|
|
|
|
PRUnichar* aDataEnd,
|
|
|
|
PRUnichar* aStorageEnd)
|
|
|
|
{
|
|
|
|
if (!mSlidingBuffer) {
|
2002-03-07 16:45:25 +00:00
|
|
|
mSlidingBuffer = new nsScannerString(aStorageStart, aDataEnd, aStorageEnd);
|
2000-12-12 21:58:14 +00:00
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
|
|
|
mMarkPosition = mCurrentPosition;
|
|
|
|
mSlidingBuffer->EndReading(mEndPosition);
|
|
|
|
mCountRemaining = (aDataEnd - aStorageStart);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mSlidingBuffer->AppendBuffer(aStorageStart, aDataEnd, aStorageEnd);
|
|
|
|
if (mCurrentPosition == mEndPosition) {
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
|
|
|
}
|
|
|
|
mSlidingBuffer->EndReading(mEndPosition);
|
|
|
|
mCountRemaining += (aDataEnd - aStorageStart);
|
|
|
|
}
|
1998-07-02 08:14:22 +00:00
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1999-02-01 04:24:37 +00:00
|
|
|
/**
|
2000-12-12 21:58:14 +00:00
|
|
|
* call this to copy bytes out of the scanner that have not yet been consumed
|
1999-02-01 04:24:37 +00:00
|
|
|
* by the tokenization process.
|
|
|
|
*
|
|
|
|
* @update gess 5/12/98
|
|
|
|
* @param aCopyBuffer is where the scanner buffer will be copied to
|
|
|
|
* @return nada
|
|
|
|
*/
|
|
|
|
void nsScanner::CopyUnusedData(nsString& aCopyBuffer) {
|
2000-12-12 21:58:14 +00:00
|
|
|
nsReadingIterator<PRUnichar> start, end;
|
|
|
|
start = mCurrentPosition;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
|
|
|
CopyUnicodeTo(start, end, aCopyBuffer);
|
1999-02-01 04:24:37 +00:00
|
|
|
}
|
|
|
|
|
1998-07-13 21:13:09 +00:00
|
|
|
/**
|
|
|
|
* Retrieve the name of the file that the scanner is reading from.
|
|
|
|
* In some cases, it's just a given name, because the scanner isn't
|
|
|
|
* really reading from a file.
|
|
|
|
*
|
|
|
|
* @update gess 5/12/98
|
|
|
|
* @return
|
|
|
|
*/
|
1999-01-09 01:09:02 +00:00
|
|
|
nsString& nsScanner::GetFilename(void) {
|
1998-07-13 21:13:09 +00:00
|
|
|
return mFilename;
|
|
|
|
}
|
|
|
|
|
1998-04-30 20:23:07 +00:00
|
|
|
/**
|
1998-04-13 20:24:54 +00:00
|
|
|
* Conduct self test. Actually, selftesting for this class
|
|
|
|
* occurs in the parser selftest.
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return
|
1998-04-30 20:23:07 +00:00
|
|
|
*/
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1999-01-09 01:09:02 +00:00
|
|
|
void nsScanner::SelfTest(void) {
|
1998-04-13 20:24:54 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1998-04-25 19:45:14 +00:00
|
|
|
|
|
|
|
|