1998-04-13 20:24:54 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2007-01-25 01:25:41 +00:00
|
|
|
/* vim: set ts=2 sw=2 et tw=78: */
|
2012-05-21 12:12:37 +01:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
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
|
|
|
|
2013-10-27 00:55:19 -07:00
|
|
|
#include "mozilla/DebugOnly.h"
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
#include "nsScanner.h"
|
|
|
|
#include "nsDebug.h"
|
2000-12-12 21:58:14 +00:00
|
|
|
#include "nsReadableUtils.h"
|
2003-03-15 01:04:32 +00:00
|
|
|
#include "nsIInputStream.h"
|
2012-06-06 14:08:30 +12:00
|
|
|
#include "nsIFile.h"
|
2003-03-15 01:04:32 +00:00
|
|
|
#include "nsNetUtil.h"
|
2004-02-19 02:44:03 +00:00
|
|
|
#include "nsUTF8Utils.h" // for LossyConvertEncoding
|
2004-08-24 18:37:33 +00:00
|
|
|
#include "nsCRT.h"
|
2004-11-02 19:52:32 +00:00
|
|
|
#include "nsParser.h"
|
2012-03-22 16:42:42 +02:00
|
|
|
#include "nsCharsetSource.h"
|
2000-12-12 21:58:14 +00:00
|
|
|
|
2012-11-07 18:04:22 -05:00
|
|
|
#include "mozilla/dom/EncodingUtils.h"
|
|
|
|
|
|
|
|
using mozilla::dom::EncodingUtils;
|
|
|
|
|
2007-01-25 17:30:13 +00:00
|
|
|
// We replace NUL characters with this character.
|
2014-01-04 10:02:17 -05:00
|
|
|
static char16_t sInvalid = UCS2_REPLACEMENT_CHAR;
|
2007-01-25 17:30:13 +00:00
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
nsReadEndCondition::nsReadEndCondition(const char16_t* aTerminateChars) :
|
|
|
|
mChars(aTerminateChars), mFilter(char16_t(~0)) // All bits set
|
2001-08-16 05:24:17 +00:00
|
|
|
{
|
|
|
|
// 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
|
2014-01-04 10:02:17 -05:00
|
|
|
const char16_t *current = aTerminateChars;
|
|
|
|
char16_t terminalChar = *current;
|
2001-08-16 05:24:17 +00:00
|
|
|
while (terminalChar) {
|
|
|
|
mFilter &= ~terminalChar;
|
|
|
|
++current;
|
|
|
|
terminalChar = *current;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
*/
|
2012-11-06 13:57:51 +02:00
|
|
|
nsScanner::nsScanner(const nsAString& anHTMLString)
|
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
|
|
|
|
2012-07-30 17:20:58 +03:00
|
|
|
mSlidingBuffer = nullptr;
|
2000-12-12 21:58:14 +00:00
|
|
|
mCountRemaining = 0;
|
2004-09-22 00:03:46 +00:00
|
|
|
mFirstNonWhitespacePosition = -1;
|
2008-07-14 15:05:15 +02:00
|
|
|
if (AppendToBuffer(anHTMLString)) {
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
|
|
|
} else {
|
|
|
|
/* XXX see hack below, re: bug 182067 */
|
|
|
|
memset(&mCurrentPosition, 0, sizeof(mCurrentPosition));
|
|
|
|
mEndPosition = mCurrentPosition;
|
|
|
|
}
|
2002-03-07 16:45:25 +00:00
|
|
|
mMarkPosition = mCurrentPosition;
|
2011-10-17 10:59:28 -04:00
|
|
|
mIncremental = false;
|
1999-03-07 19:23:28 +00:00
|
|
|
mUnicodeDecoder = 0;
|
1999-03-08 20:00:23 +00:00
|
|
|
mCharsetSource = kCharsetUninitialized;
|
2011-10-17 10:59:28 -04:00
|
|
|
mHasInvalidCharacter = false;
|
2014-01-04 10:02:17 -05:00
|
|
|
mReplacementCharacter = char16_t(0x0);
|
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
|
|
|
*/
|
2012-11-06 13:57:51 +02:00
|
|
|
nsScanner::nsScanner(nsString& aFilename, bool aCreateStream)
|
2011-05-06 08:45:33 -07:00
|
|
|
: mFilename(aFilename)
|
1998-07-13 21:13:09 +00:00
|
|
|
{
|
1999-10-14 23:37:21 +00:00
|
|
|
MOZ_COUNT_CTOR(nsScanner);
|
2007-06-26 17:21:47 -07:00
|
|
|
NS_ASSERTION(!aCreateStream, "This is always true.");
|
2002-03-07 16:45:25 +00:00
|
|
|
|
2012-07-30 17:20:58 +03:00
|
|
|
mSlidingBuffer = nullptr;
|
2004-02-19 02:44:03 +00:00
|
|
|
|
|
|
|
// XXX This is a big hack. We need to initialize the iterators to something.
|
|
|
|
// What matters is that mCurrentPosition == mEndPosition, so that our methods
|
|
|
|
// believe that we are at EOF (see bug 182067). We null out mCurrentPosition
|
|
|
|
// so that we have some hope of catching null pointer dereferences associated
|
|
|
|
// with this hack. --darin
|
|
|
|
memset(&mCurrentPosition, 0, sizeof(mCurrentPosition));
|
2003-01-31 00:58:41 +00:00
|
|
|
mMarkPosition = mCurrentPosition;
|
|
|
|
mEndPosition = mCurrentPosition;
|
2004-02-19 02:44:03 +00:00
|
|
|
|
2011-10-17 10:59:28 -04:00
|
|
|
mIncremental = true;
|
2004-08-24 18:37:33 +00:00
|
|
|
mFirstNonWhitespacePosition = -1;
|
2000-12-12 21:58:14 +00:00
|
|
|
mCountRemaining = 0;
|
2003-03-15 01:04:32 +00:00
|
|
|
|
1999-03-07 19:23:28 +00:00
|
|
|
mUnicodeDecoder = 0;
|
1999-03-08 20:00:23 +00:00
|
|
|
mCharsetSource = kCharsetUninitialized;
|
2011-10-17 10:59:28 -04:00
|
|
|
mHasInvalidCharacter = false;
|
2014-01-04 10:02:17 -05:00
|
|
|
mReplacementCharacter = char16_t(0x0);
|
2012-11-06 13:57:51 +02:00
|
|
|
// XML defaults to UTF-8 and about:blank is UTF-8, too.
|
|
|
|
SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"), kCharsetFromDocTypeDefault);
|
1999-02-01 18:23:31 +00:00
|
|
|
}
|
1999-02-16 07:38:27 +00:00
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
nsresult nsScanner::SetDocumentCharset(const nsACString& aCharset , int32_t aSource)
|
2008-09-30 23:48:47 -07:00
|
|
|
{
|
2013-10-27 00:55:19 -07:00
|
|
|
if (aSource < mCharsetSource) // priority is lower than the current one
|
2008-09-30 23:48:47 -07:00
|
|
|
return NS_OK;
|
1999-03-08 20:00:23 +00:00
|
|
|
|
2013-10-27 00:55:19 -07:00
|
|
|
mCharsetSource = aSource;
|
|
|
|
|
2012-11-07 18:04:22 -05:00
|
|
|
nsCString charsetName;
|
2013-10-27 00:55:19 -07:00
|
|
|
mozilla::DebugOnly<bool> valid =
|
|
|
|
EncodingUtils::FindEncodingForLabel(aCharset, charsetName);
|
2012-11-07 18:04:22 -05:00
|
|
|
MOZ_ASSERT(valid, "Should never call with a bogus aCharset.");
|
2013-10-27 00:55:19 -07:00
|
|
|
|
|
|
|
if (!mCharset.IsEmpty() && charsetName.Equals(mCharset)) {
|
|
|
|
return NS_OK; // no difference, don't change it
|
2008-01-29 14:12:22 -08:00
|
|
|
}
|
1999-03-08 20:00:23 +00:00
|
|
|
|
2008-01-29 14:12:22 -08:00
|
|
|
// different, need to change it
|
1999-03-08 20:00:23 +00:00
|
|
|
|
2012-11-06 13:57:51 +02:00
|
|
|
mCharset.Assign(charsetName);
|
2008-01-29 14:12:22 -08:00
|
|
|
|
2013-11-26 09:31:52 +02:00
|
|
|
mUnicodeDecoder = EncodingUtils::DecoderForEncoding(mCharset);
|
|
|
|
mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal);
|
2008-01-29 14:12:22 -08:00
|
|
|
|
2013-11-26 09:31:52 +02:00
|
|
|
return NS_OK;
|
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
|
|
|
|
2011-05-17 16:01:36 +02:00
|
|
|
delete mSlidingBuffer;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
1999-10-14 23:37:21 +00:00
|
|
|
MOZ_COUNT_DTOR(nsScanner);
|
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){
|
2004-06-08 18:54:57 +00:00
|
|
|
if (mSlidingBuffer) {
|
|
|
|
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
|
|
|
|
*/
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t nsScanner::Mark() {
|
|
|
|
int32_t distance = 0;
|
2000-12-12 21:58:14 +00:00
|
|
|
if (mSlidingBuffer) {
|
2008-09-30 23:48:47 -07:00
|
|
|
nsScannerIterator oldStart;
|
|
|
|
mSlidingBuffer->BeginReading(oldStart);
|
|
|
|
|
|
|
|
distance = Distance(oldStart, mCurrentPosition);
|
|
|
|
|
2002-03-16 03:03:45 +00:00
|
|
|
mSlidingBuffer->DiscardPrefix(mCurrentPosition);
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
2000-12-12 21:58:14 +00:00
|
|
|
mMarkPosition = mCurrentPosition;
|
1998-08-03 21:04:54 +00:00
|
|
|
}
|
2008-09-30 23:48:47 -07:00
|
|
|
|
|
|
|
return distance;
|
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
|
|
|
|
*/
|
2011-09-28 23:19:26 -07:00
|
|
|
bool nsScanner::UngetReadable(const nsAString& aBuffer) {
|
2004-06-08 18:54:57 +00:00
|
|
|
if (!mSlidingBuffer) {
|
2011-10-17 10:59:28 -04:00
|
|
|
return false;
|
2004-06-08 18:54:57 +00:00
|
|
|
}
|
2001-02-13 21:26:58 +00:00
|
|
|
|
2002-03-07 16:45:25 +00:00
|
|
|
mSlidingBuffer->UngetReadable(aBuffer,mCurrentPosition);
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition); // Insertion invalidated our iterators
|
|
|
|
mSlidingBuffer->EndReading(mEndPosition);
|
2002-05-15 20:20:55 +00:00
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
uint32_t length = aBuffer.Length();
|
2002-05-15 20:20:55 +00:00
|
|
|
mCountRemaining += length; // Ref. bug 117441
|
2011-10-17 10:59:28 -04:00
|
|
|
return true;
|
2000-01-15 20:35:57 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
*/
|
2002-03-24 00:16:18 +00:00
|
|
|
nsresult nsScanner::Append(const nsAString& aBuffer) {
|
2008-07-14 15:05:15 +02:00
|
|
|
if (!AppendToBuffer(aBuffer))
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
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
|
|
|
|
*/
|
2012-08-22 11:56:38 -04:00
|
|
|
nsresult nsScanner::Append(const char* aBuffer, uint32_t aLen,
|
2004-11-05 06:50:27 +00:00
|
|
|
nsIRequest *aRequest)
|
|
|
|
{
|
2011-06-24 01:50:25 -07:00
|
|
|
nsresult res = NS_OK;
|
2007-06-26 17:21:47 -07:00
|
|
|
if (mUnicodeDecoder) {
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t unicharBufLen = 0;
|
2001-07-13 18:21:23 +00:00
|
|
|
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerString::Buffer* buffer = nsScannerString::AllocBuffer(unicharBufLen + 1);
|
|
|
|
NS_ENSURE_TRUE(buffer,NS_ERROR_OUT_OF_MEMORY);
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t *unichars = buffer->DataStart();
|
2004-12-22 00:21:13 +00:00
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t totalChars = 0;
|
|
|
|
int32_t unicharLength = unicharBufLen;
|
|
|
|
int32_t errorPos = -1;
|
2009-02-16 04:22:47 -08:00
|
|
|
|
2001-07-13 18:21:23 +00:00
|
|
|
do {
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t srcLength = aLen;
|
2004-12-22 00:21:13 +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
|
2004-12-22 00:21:13 +00:00
|
|
|
if(NS_FAILED(res)) {
|
2009-02-16 04:22:47 -08:00
|
|
|
// if we failed, we consume one byte, replace it with the replacement
|
|
|
|
// character and try the conversion again.
|
2004-10-27 20:19:11 +00:00
|
|
|
|
|
|
|
// This is only needed because some decoders don't follow the
|
|
|
|
// nsIUnicodeDecoder contract: they return a failure when *aDestLength
|
|
|
|
// is 0 rather than the correct NS_OK_UDEC_MOREOUTPUT. See bug 244177
|
|
|
|
if ((unichars + unicharLength) >= buffer->DataEnd()) {
|
|
|
|
NS_ERROR("Unexpected end of destination buffer");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-02-16 04:22:47 -08:00
|
|
|
if (mReplacementCharacter == 0x0 && errorPos == -1) {
|
|
|
|
errorPos = totalChars;
|
|
|
|
}
|
|
|
|
unichars[unicharLength++] = mReplacementCharacter == 0x0 ?
|
|
|
|
mUnicodeDecoder->GetCharacterForUnMapped() :
|
|
|
|
mReplacementCharacter;
|
|
|
|
|
2001-07-13 18:21:23 +00:00
|
|
|
unichars = unichars + unicharLength;
|
|
|
|
unicharLength = unicharBufLen - (++totalChars);
|
2000-12-12 21:58:14 +00:00
|
|
|
|
2004-12-22 00:21:13 +00:00
|
|
|
mUnicodeDecoder->Reset();
|
2001-07-13 18:21:23 +00:00
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
if(((uint32_t) (srcLength + 1)) > aLen) {
|
2001-07-13 18:21:23 +00:00
|
|
|
srcLength = aLen;
|
|
|
|
}
|
|
|
|
else {
|
2002-09-03 22:23:22 +00:00
|
|
|
++srcLength;
|
2001-07-13 18:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
aBuffer += srcLength;
|
|
|
|
aLen -= srcLength;
|
2004-12-22 00:21:13 +00:00
|
|
|
}
|
|
|
|
} while (NS_FAILED(res) && (aLen > 0));
|
2001-07-13 18:21:23 +00:00
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
buffer->SetDataLength(totalChars);
|
2001-07-13 18:21:23 +00:00
|
|
|
// Don't propagate return code of unicode decoder
|
|
|
|
// since it doesn't reflect on our success or failure
|
|
|
|
// - Ref. bug 87110
|
|
|
|
res = NS_OK;
|
2009-02-16 04:22:47 -08:00
|
|
|
if (!AppendToBuffer(buffer, aRequest, errorPos))
|
2008-07-14 15:05:15 +02:00
|
|
|
res = NS_ERROR_OUT_OF_MEMORY;
|
1999-03-07 19:23:28 +00:00
|
|
|
}
|
1999-07-19 05:30:49 +00:00
|
|
|
else {
|
2007-06-26 17:21:47 -07:00
|
|
|
NS_WARNING("No decoder found.");
|
|
|
|
res = NS_ERROR_FAILURE;
|
1999-03-07 19:23:28 +00:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
*/
|
2014-01-04 10:02:17 -05:00
|
|
|
nsresult nsScanner::GetChar(char16_t& aChar) {
|
2007-06-26 17:21:47 -07:00
|
|
|
if (!mSlidingBuffer || mCurrentPosition == mEndPosition) {
|
|
|
|
aChar = 0;
|
2000-12-12 21:58:14 +00:00
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2007-06-26 17:21:47 -07:00
|
|
|
aChar = *mCurrentPosition++;
|
|
|
|
--mCountRemaining;
|
1998-07-23 21:10:19 +00:00
|
|
|
|
2007-06-26 17:21:47 -07: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
|
|
|
* 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
|
|
|
*/
|
2014-01-04 10:02:17 -05:00
|
|
|
nsresult nsScanner::Peek(char16_t& aChar, uint32_t aOffset) {
|
2007-06-26 17:21:47 -07:00
|
|
|
aChar = 0;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
2007-06-26 17:21:47 -07:00
|
|
|
if (!mSlidingBuffer || mCurrentPosition == mEndPosition) {
|
|
|
|
return kEOF;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
1998-07-23 21:10:19 +00:00
|
|
|
|
2007-06-26 17:21:47 -07:00
|
|
|
if (aOffset > 0) {
|
|
|
|
if (mCountRemaining <= aOffset)
|
|
|
|
return kEOF;
|
2000-12-18 20:44:10 +00:00
|
|
|
|
2007-06-26 17:21:47 -07:00
|
|
|
nsScannerIterator 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
|
|
|
|
2007-06-26 17:21:47 -07:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
nsresult nsScanner::Peek(nsAString& aStr, int32_t aNumChars, int32_t aOffset)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
2007-06-26 17:21:47 -07:00
|
|
|
if (!mSlidingBuffer || mCurrentPosition == mEndPosition) {
|
2000-12-12 21:58:14 +00:00
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator start, end;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
start = mCurrentPosition;
|
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
if ((int32_t)mCountRemaining <= aOffset) {
|
2004-08-24 18:37:33 +00:00
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aOffset > 0) {
|
|
|
|
start.advance(aOffset);
|
|
|
|
}
|
|
|
|
|
2012-08-22 11:56:38 -04:00
|
|
|
if (mCountRemaining < uint32_t(aNumChars + aOffset)) {
|
2000-12-12 21:58:14 +00:00
|
|
|
end = mEndPosition;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
end = start;
|
2004-08-26 04:03:48 +00:00
|
|
|
end.advance(aNumChars);
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
*/
|
2012-08-22 11:56:38 -04:00
|
|
|
nsresult nsScanner::SkipWhitespace(int32_t& aNewlinesSkipped) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar = 0;
|
2002-04-10 22:16:46 +00:00
|
|
|
nsresult result = Peek(theChar);
|
2001-08-16 21:19:33 +00:00
|
|
|
|
2005-01-03 22:06:27 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
2001-08-16 21:19:33 +00:00
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator current = mCurrentPosition;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool done = false;
|
|
|
|
bool skipped = false;
|
2002-04-10 22:16:46 +00:00
|
|
|
|
|
|
|
while (!done && current != mEndPosition) {
|
2000-12-12 21:58:14 +00:00
|
|
|
switch(theChar) {
|
2002-04-10 22:16:46 +00:00
|
|
|
case '\n':
|
2002-09-03 22:23:22 +00:00
|
|
|
case '\r': ++aNewlinesSkipped;
|
2000-12-12 21:58:14 +00:00
|
|
|
case ' ' :
|
|
|
|
case '\t':
|
2002-04-10 22:16:46 +00:00
|
|
|
{
|
2011-10-17 10:59:28 -04:00
|
|
|
skipped = true;
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t thePrevChar = theChar;
|
2002-04-10 22:16:46 +00:00
|
|
|
theChar = (++current != mEndPosition) ? *current : '\0';
|
|
|
|
if ((thePrevChar == '\r' && theChar == '\n') ||
|
|
|
|
(thePrevChar == '\n' && theChar == '\r')) {
|
|
|
|
theChar = (++current != mEndPosition) ? *current : '\0'; // CRLF == LFCR => LF
|
|
|
|
}
|
|
|
|
}
|
2000-12-12 21:58:14 +00:00
|
|
|
break;
|
|
|
|
default:
|
2011-10-17 10:59:28 -04:00
|
|
|
done = true;
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
}
|
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) {
|
2007-06-26 17:21:47 -07:00
|
|
|
result = kEOF;
|
2001-08-16 21:19:33 +00:00
|
|
|
}
|
1999-09-30 04:04:53 +00:00
|
|
|
}
|
|
|
|
|
2002-04-10 22:16:46 +00:00
|
|
|
return result;
|
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
|
|
|
|
*/
|
2014-01-04 10:02:17 -05:00
|
|
|
nsresult nsScanner::SkipOver(char16_t aSkipChar){
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t 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
|
|
|
}
|
|
|
|
|
1999-10-05 04:54:53 +00:00
|
|
|
#if 0
|
1999-09-30 04:04:53 +00:00
|
|
|
void DoErrTest(nsString& aString) {
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t pos=aString.FindChar(0);
|
1999-09-30 04:04:53 +00:00
|
|
|
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) {
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t pos=aString.FindChar(0);
|
1999-09-30 04:04:53 +00:00
|
|
|
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
|
|
|
|
2000-02-11 12:11:29 +00:00
|
|
|
/**
|
2004-05-02 11:16:26 +00:00
|
|
|
* Consume characters until you run into space, a '<', a '>', or a '/'.
|
2000-02-11 12:11:29 +00:00
|
|
|
*
|
|
|
|
* @param aString - receives new data from stream
|
|
|
|
* @return error code
|
|
|
|
*/
|
2004-11-25 07:03:20 +00:00
|
|
|
nsresult nsScanner::ReadTagIdentifier(nsScannerSharedSubstring& aString) {
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
2000-02-11 12:11:29 +00:00
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar=0;
|
2000-02-11 12:11:29 +00:00
|
|
|
nsresult result=Peek(theChar);
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator current, end;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool found=false;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
current = mCurrentPosition;
|
|
|
|
end = mEndPosition;
|
2000-02-11 12:11:29 +00:00
|
|
|
|
2004-11-11 03:41:52 +00:00
|
|
|
// Loop until we find an illegal character. Everything is then appended
|
|
|
|
// later.
|
|
|
|
while(current != end && !found) {
|
2000-12-12 21:58:14 +00:00
|
|
|
theChar=*current;
|
2000-02-11 12:11:29 +00:00
|
|
|
|
2004-10-19 01:34:53 +00:00
|
|
|
switch(theChar) {
|
|
|
|
case '\n':
|
|
|
|
case '\r':
|
|
|
|
case ' ' :
|
|
|
|
case '\t':
|
|
|
|
case '\v':
|
|
|
|
case '\f':
|
|
|
|
case '<':
|
|
|
|
case '>':
|
|
|
|
case '/':
|
2011-10-17 10:59:28 -04:00
|
|
|
found = true;
|
2000-02-11 12:11:29 +00:00
|
|
|
break;
|
2007-01-25 01:25:41 +00:00
|
|
|
|
|
|
|
case '\0':
|
2007-01-25 17:30:13 +00:00
|
|
|
ReplaceCharacter(current, sInvalid);
|
2007-01-25 01:25:41 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-19 01:34:53 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-11-11 03:41:52 +00:00
|
|
|
if (!found) {
|
|
|
|
++current;
|
2000-02-11 12:11:29 +00:00
|
|
|
}
|
2004-11-11 03:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Don't bother appending nothing.
|
|
|
|
if (current != mCurrentPosition) {
|
|
|
|
AppendUnicodeTo(mCurrentPosition, current, aString);
|
2000-02-11 12:11:29 +00:00
|
|
|
}
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
2007-06-26 17:21:47 -07:00
|
|
|
result = kEOF;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
/**
|
2004-05-02 11:16:26 +00:00
|
|
|
* Consume characters until you run into a char that's not valid in an
|
|
|
|
* entity name
|
1999-09-30 04:04:53 +00:00
|
|
|
*
|
2000-01-27 02:27:58 +00:00
|
|
|
* @param aString - receives new data from stream
|
1999-09-30 04:04:53 +00:00
|
|
|
* @return error code
|
|
|
|
*/
|
2004-05-02 11:16:26 +00:00
|
|
|
nsresult nsScanner::ReadEntityIdentifier(nsString& aString) {
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar=0;
|
1999-09-30 04:04:53 +00:00
|
|
|
nsresult result=Peek(theChar);
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator origin, current, end;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool found=false;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
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) {
|
2011-10-17 10:59:28 -04:00
|
|
|
found=false;
|
1999-09-30 04:04:53 +00:00
|
|
|
switch(theChar) {
|
|
|
|
case '_':
|
|
|
|
case '-':
|
2004-01-27 04:50:56 +00:00
|
|
|
case '.':
|
2004-05-02 11:16:26 +00:00
|
|
|
// Don't allow ':' in entity names. See bug 23791
|
2011-10-17 10:59:28 -04:00
|
|
|
found = true;
|
1999-09-30 04:04:53 +00:00
|
|
|
break;
|
|
|
|
default:
|
2004-01-27 04:50:56 +00:00
|
|
|
found = ('a'<=theChar && theChar<='z') ||
|
|
|
|
('A'<=theChar && theChar<='Z') ||
|
|
|
|
('0'<=theChar && theChar<='9');
|
1999-09-30 04:04:53 +00:00
|
|
|
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);
|
2007-06-26 17:21:47 -07:00
|
|
|
return kEOF;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
/**
|
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
|
|
|
|
*/
|
2012-08-22 11:56:38 -04:00
|
|
|
nsresult nsScanner::ReadNumber(nsString& aString,int32_t 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");
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar=0;
|
1999-09-30 04:04:53 +00:00
|
|
|
nsresult result=Peek(theChar);
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator 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;
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool done = 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')
|
2011-10-17 10:59:28 -04:00
|
|
|
:true);
|
2001-07-05 22:20:34 +00:00
|
|
|
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);
|
2007-06-26 17:21:47 -07:00
|
|
|
return kEOF;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-09-30 04:04:53 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2004-11-25 07:03:20 +00:00
|
|
|
nsresult nsScanner::ReadWhitespace(nsScannerSharedSubstring& aString,
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t& aNewlinesSkipped,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool& aHaveCR) {
|
2004-11-25 07:03:20 +00:00
|
|
|
|
2011-10-17 10:59:28 -04:00
|
|
|
aHaveCR = false;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar = 0;
|
2002-04-10 22:16:46 +00:00
|
|
|
nsresult result = Peek(theChar);
|
|
|
|
|
2005-01-03 22:06:27 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
2002-04-10 22:16:46 +00:00
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator origin, current, end;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool done = false;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool haveCR = false;
|
2004-11-25 07:03:20 +00:00
|
|
|
|
2002-04-10 22:16:46 +00:00
|
|
|
while(!done && current != end) {
|
|
|
|
switch(theChar) {
|
|
|
|
case '\n':
|
2004-05-02 11:17:44 +00:00
|
|
|
case '\r':
|
2002-04-10 22:16:46 +00:00
|
|
|
{
|
2004-05-02 11:17:44 +00:00
|
|
|
++aNewlinesSkipped;
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t thePrevChar = theChar;
|
2002-04-10 22:16:46 +00:00
|
|
|
theChar = (++current != end) ? *current : '\0';
|
|
|
|
if ((thePrevChar == '\r' && theChar == '\n') ||
|
|
|
|
(thePrevChar == '\n' && theChar == '\r')) {
|
|
|
|
theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
|
2011-10-17 10:59:28 -04:00
|
|
|
haveCR = true;
|
2004-05-02 11:17:44 +00:00
|
|
|
} else if (thePrevChar == '\r') {
|
|
|
|
// Lone CR becomes CRLF; callers should know to remove extra CRs
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
2014-01-04 10:02:17 -05:00
|
|
|
aString.writable().Append(char16_t('\n'));
|
2004-05-02 11:17:44 +00:00
|
|
|
origin = current;
|
2011-10-17 10:59:28 -04:00
|
|
|
haveCR = true;
|
2002-04-10 22:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-05-02 11:17:44 +00:00
|
|
|
case ' ' :
|
|
|
|
case '\t':
|
|
|
|
theChar = (++current != end) ? *current : '\0';
|
|
|
|
break;
|
2002-04-10 22:16:46 +00:00
|
|
|
default:
|
2011-10-17 10:59:28 -04:00
|
|
|
done = true;
|
2002-04-09 00:43:00 +00:00
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
break;
|
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);
|
2007-06-26 17:21:47 -07:00
|
|
|
result = kEOF;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
2004-11-25 07:03:20 +00:00
|
|
|
aHaveCR = haveCR;
|
1999-09-30 04:04:53 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2004-05-02 11:17:44 +00:00
|
|
|
//XXXbz callers of this have to manage their lone '\r' themselves if they want
|
|
|
|
//it to work. Good thing they're all in view-source and it deals.
|
2004-02-19 02:44:03 +00:00
|
|
|
nsresult nsScanner::ReadWhitespace(nsScannerIterator& aStart,
|
|
|
|
nsScannerIterator& aEnd,
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t& aNewlinesSkipped) {
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar = 0;
|
2002-04-10 22:16:46 +00:00
|
|
|
nsresult result = Peek(theChar);
|
|
|
|
|
2005-01-03 22:06:27 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
2002-04-10 22:16:46 +00:00
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator origin, current, end;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool done = false;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
end = mEndPosition;
|
|
|
|
|
2002-04-10 22:16:46 +00:00
|
|
|
while(!done && current != end) {
|
|
|
|
switch(theChar) {
|
|
|
|
case '\n':
|
2002-09-03 22:23:22 +00:00
|
|
|
case '\r': ++aNewlinesSkipped;
|
2002-04-10 22:16:46 +00:00
|
|
|
case ' ' :
|
|
|
|
case '\t':
|
|
|
|
{
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t thePrevChar = theChar;
|
2002-04-10 22:16:46 +00:00
|
|
|
theChar = (++current != end) ? *current : '\0';
|
|
|
|
if ((thePrevChar == '\r' && theChar == '\n') ||
|
|
|
|
(thePrevChar == '\n' && theChar == '\r')) {
|
|
|
|
theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2011-10-17 10:59:28 -04:00
|
|
|
done = true;
|
2002-04-09 00:43:00 +00:00
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
break;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SetPosition(current);
|
|
|
|
if (current == end) {
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
2007-06-26 17:21:47 -07:00
|
|
|
result = kEOF;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
|
1999-09-19 16:51:08 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
*/
|
2002-03-24 00:16:18 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsAString& aString,
|
2001-08-16 05:24:17 +00:00
|
|
|
const nsReadEndCondition& aEndCondition,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool addTerminal)
|
2001-04-11 02:28:17 +00:00
|
|
|
{
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator origin, current;
|
2014-01-04 10:02:17 -05:00
|
|
|
const char16_t* setstart = aEndCondition.mChars;
|
|
|
|
const char16_t* setcurrent;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar=0;
|
1999-09-30 04:04:53 +00:00
|
|
|
nsresult result=Peek(theChar);
|
2001-08-16 21:19:33 +00:00
|
|
|
|
2005-01-03 22:06:27 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
2001-08-16 21:19:33 +00:00
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
|
|
|
while (current != mEndPosition) {
|
2004-05-12 08:07:06 +00:00
|
|
|
theChar = *current;
|
2007-01-25 01:25:41 +00:00
|
|
|
if (theChar == '\0') {
|
2007-01-25 17:30:13 +00:00
|
|
|
ReplaceCharacter(current, sInvalid);
|
|
|
|
theChar = sInvalid;
|
2007-01-25 01:25:41 +00:00
|
|
|
}
|
2004-05-12 08:07:06 +00:00
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
// 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) {
|
2004-11-25 07:03:20 +00:00
|
|
|
if(addTerminal)
|
|
|
|
++current;
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
SetPosition(current);
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return NS_OK;
|
2001-04-28 02:03:18 +00:00
|
|
|
}
|
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;
|
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);
|
2007-06-26 17:21:47 -07:00
|
|
|
return kEOF;
|
2004-11-25 07:03:20 +00:00
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
2004-11-25 07:03:20 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsScannerSharedSubstring& aString,
|
|
|
|
const nsReadEndCondition& aEndCondition,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool addTerminal)
|
2004-11-25 07:03:20 +00:00
|
|
|
{
|
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
2004-11-25 07:03:20 +00:00
|
|
|
nsScannerIterator origin, current;
|
2014-01-04 10:02:17 -05:00
|
|
|
const char16_t* setstart = aEndCondition.mChars;
|
|
|
|
const char16_t* setcurrent;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
2004-11-25 07:03:20 +00:00
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar=0;
|
2004-11-25 07:03:20 +00:00
|
|
|
nsresult result=Peek(theChar);
|
|
|
|
|
2005-01-03 22:06:27 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
2004-11-25 07:03:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
while (current != mEndPosition) {
|
|
|
|
theChar = *current;
|
2007-01-25 01:25:41 +00:00
|
|
|
if (theChar == '\0') {
|
2007-01-25 17:30:13 +00:00
|
|
|
ReplaceCharacter(current, sInvalid);
|
|
|
|
theChar = sInvalid;
|
2007-01-25 01:25:41 +00:00
|
|
|
}
|
2004-11-25 07:03:20 +00:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
while (*setcurrent) {
|
|
|
|
if (*setcurrent == theChar) {
|
|
|
|
if(addTerminal)
|
|
|
|
++current;
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
|
|
|
SetPosition(current);
|
|
|
|
|
|
|
|
//DoErrTest(aString);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
++setcurrent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++current;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we are here, we didn't find any terminator in the string and
|
|
|
|
// current = mEndPosition
|
|
|
|
SetPosition(current);
|
|
|
|
AppendUnicodeTo(origin, current, aString);
|
2007-06-26 17:21:47 -07:00
|
|
|
return kEOF;
|
1999-09-19 16:51:08 +00:00
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsScannerIterator& aStart,
|
|
|
|
nsScannerIterator& aEnd,
|
2001-08-16 05:24:17 +00:00
|
|
|
const nsReadEndCondition &aEndCondition,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool addTerminal)
|
2001-04-11 02:28:17 +00:00
|
|
|
{
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator origin, current;
|
2014-01-04 10:02:17 -05:00
|
|
|
const char16_t* setstart = aEndCondition.mChars;
|
|
|
|
const char16_t* setcurrent;
|
2000-12-12 21:58:14 +00:00
|
|
|
|
|
|
|
origin = mCurrentPosition;
|
|
|
|
current = origin;
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar=0;
|
2001-08-16 05:24:17 +00:00
|
|
|
nsresult result=Peek(theChar);
|
2001-08-16 21:19:33 +00:00
|
|
|
|
2005-01-03 22:06:27 +00:00
|
|
|
if (NS_FAILED(result)) {
|
2001-08-16 21:19:33 +00:00
|
|
|
aStart = aEnd = current;
|
2005-01-03 22:06:27 +00:00
|
|
|
return result;
|
2001-08-16 21:19:33 +00:00
|
|
|
}
|
2001-08-16 05:24:17 +00:00
|
|
|
|
|
|
|
while (current != mEndPosition) {
|
2009-09-30 15:15:51 -07:00
|
|
|
theChar = *current;
|
2007-01-25 01:25:41 +00:00
|
|
|
if (theChar == '\0') {
|
2007-01-25 17:30:13 +00:00
|
|
|
ReplaceCharacter(current, sInvalid);
|
|
|
|
theChar = sInvalid;
|
2007-01-25 01:25:41 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
// 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) {
|
2004-11-25 07:03:20 +00:00
|
|
|
if(addTerminal)
|
|
|
|
++current;
|
|
|
|
aStart = origin;
|
|
|
|
aEnd = current;
|
|
|
|
SetPosition(current);
|
|
|
|
|
|
|
|
return NS_OK;
|
2001-04-28 02:03:18 +00:00
|
|
|
}
|
2007-01-25 01:25:41 +00:00
|
|
|
++setcurrent;
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-30 15:15:51 -07:00
|
|
|
|
2001-06-19 22:38:45 +00:00
|
|
|
++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;
|
2007-06-26 17:21:47 -07:00
|
|
|
return kEOF;
|
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
|
|
|
*/
|
2002-03-24 00:16:18 +00:00
|
|
|
nsresult nsScanner::ReadUntil(nsAString& aString,
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t aTerminalChar,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool addTerminal)
|
2001-04-11 02:28:17 +00:00
|
|
|
{
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
return kEOF;
|
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator 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
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t theChar;
|
2005-01-03 22:06:27 +00:00
|
|
|
nsresult result = Peek(theChar);
|
|
|
|
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
while (current != mEndPosition) {
|
2009-09-30 15:15:51 -07:00
|
|
|
theChar = *current;
|
2007-01-25 01:25:41 +00:00
|
|
|
if (theChar == '\0') {
|
2007-01-25 17:30:13 +00:00
|
|
|
ReplaceCharacter(current, sInvalid);
|
|
|
|
theChar = sInvalid;
|
2007-01-25 01:25:41 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 05:24:17 +00:00
|
|
|
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;
|
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);
|
2007-06-26 17:21:47 -07:00
|
|
|
return kEOF;
|
1999-09-30 04:04:53 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
void nsScanner::BindSubstring(nsScannerSubstring& aSubstring, const nsScannerIterator& aStart, const nsScannerIterator& aEnd)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
|
|
|
aSubstring.Rebind(*mSlidingBuffer, aStart, aEnd);
|
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
void nsScanner::CurrentPosition(nsScannerIterator& aPosition)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
|
|
|
aPosition = mCurrentPosition;
|
|
|
|
}
|
1999-12-03 00:30:29 +00:00
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
void nsScanner::EndReading(nsScannerIterator& aPosition)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
|
|
|
aPosition = mEndPosition;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
void nsScanner::SetPosition(nsScannerIterator& aPosition, bool aTerminate, bool aReverse)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
|
|
|
if (mSlidingBuffer) {
|
2005-02-02 02:04:09 +00:00
|
|
|
#ifdef DEBUG
|
2012-08-22 11:56:38 -04:00
|
|
|
uint32_t origRemaining = mCountRemaining;
|
2005-02-02 02:04:09 +00:00
|
|
|
#endif
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
if (aReverse) {
|
|
|
|
mCountRemaining += (Distance(aPosition, mCurrentPosition));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mCountRemaining -= (Distance(mCurrentPosition, aPosition));
|
|
|
|
}
|
2005-02-02 02:04:09 +00:00
|
|
|
|
|
|
|
NS_ASSERTION((mCountRemaining >= origRemaining && aReverse) ||
|
|
|
|
(mCountRemaining <= origRemaining && !aReverse),
|
|
|
|
"Improper use of nsScanner::SetPosition. Make sure to set the"
|
|
|
|
" aReverse parameter correctly");
|
|
|
|
|
2000-12-12 21:58:14 +00:00
|
|
|
mCurrentPosition = aPosition;
|
|
|
|
if (aTerminate && (mCurrentPosition == mEndPosition)) {
|
|
|
|
mMarkPosition = mCurrentPosition;
|
|
|
|
mSlidingBuffer->DiscardPrefix(mCurrentPosition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
void nsScanner::ReplaceCharacter(nsScannerIterator& aPosition,
|
2014-01-04 10:02:17 -05:00
|
|
|
char16_t aChar)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
|
|
|
if (mSlidingBuffer) {
|
|
|
|
mSlidingBuffer->ReplaceCharacter(aPosition, aChar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool nsScanner::AppendToBuffer(nsScannerString::Buffer* aBuf,
|
2009-02-16 04:22:47 -08:00
|
|
|
nsIRequest *aRequest,
|
2012-08-22 11:56:38 -04:00
|
|
|
int32_t aErrorPos)
|
2000-12-12 21:58:14 +00:00
|
|
|
{
|
2012-08-22 11:56:38 -04:00
|
|
|
uint32_t countRemaining = mCountRemaining;
|
2000-12-12 21:58:14 +00:00
|
|
|
if (!mSlidingBuffer) {
|
2004-02-19 02:44:03 +00:00
|
|
|
mSlidingBuffer = new nsScannerString(aBuf);
|
2008-07-14 15:05:15 +02:00
|
|
|
if (!mSlidingBuffer)
|
2011-10-17 10:59:28 -04:00
|
|
|
return false;
|
2000-12-12 21:58:14 +00:00
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
|
|
|
mMarkPosition = mCurrentPosition;
|
|
|
|
mSlidingBuffer->EndReading(mEndPosition);
|
2004-02-19 02:44:03 +00:00
|
|
|
mCountRemaining = aBuf->DataLength();
|
2000-12-12 21:58:14 +00:00
|
|
|
}
|
|
|
|
else {
|
2004-02-19 02:44:03 +00:00
|
|
|
mSlidingBuffer->AppendBuffer(aBuf);
|
2000-12-12 21:58:14 +00:00
|
|
|
if (mCurrentPosition == mEndPosition) {
|
|
|
|
mSlidingBuffer->BeginReading(mCurrentPosition);
|
|
|
|
}
|
|
|
|
mSlidingBuffer->EndReading(mEndPosition);
|
2004-02-19 02:44:03 +00:00
|
|
|
mCountRemaining += aBuf->DataLength();
|
|
|
|
}
|
2004-08-24 18:37:33 +00:00
|
|
|
|
2009-02-16 04:22:47 -08:00
|
|
|
if (aErrorPos != -1 && !mHasInvalidCharacter) {
|
2011-10-17 10:59:28 -04:00
|
|
|
mHasInvalidCharacter = true;
|
2009-02-16 04:22:47 -08:00
|
|
|
mFirstInvalidPosition = mCurrentPosition;
|
2010-03-30 12:45:59 +02:00
|
|
|
mFirstInvalidPosition.advance(countRemaining + aErrorPos);
|
2009-02-16 04:22:47 -08:00
|
|
|
}
|
|
|
|
|
2004-08-24 18:37:33 +00:00
|
|
|
if (mFirstNonWhitespacePosition == -1) {
|
|
|
|
nsScannerIterator iter(mCurrentPosition);
|
|
|
|
nsScannerIterator end(mEndPosition);
|
|
|
|
|
|
|
|
while (iter != end) {
|
|
|
|
if (!nsCRT::IsAsciiSpace(*iter)) {
|
|
|
|
mFirstNonWhitespacePosition = Distance(mCurrentPosition, iter);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
}
|
2011-10-17 10:59:28 -04:00
|
|
|
return true;
|
2004-02-19 02:44:03 +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) {
|
2004-06-08 18:54:57 +00:00
|
|
|
if (!mSlidingBuffer) {
|
|
|
|
aCopyBuffer.Truncate();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-19 02:44:03 +00:00
|
|
|
nsScannerIterator start, end;
|
2000-12-12 21:58:14 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2014-01-04 10:02:17 -05:00
|
|
|
void nsScanner::OverrideReplacementCharacter(char16_t aReplacementCharacter)
|
2009-02-16 04:22:47 -08:00
|
|
|
{
|
|
|
|
mReplacementCharacter = aReplacementCharacter;
|
1998-04-25 19:45:14 +00:00
|
|
|
|
2009-02-16 04:22:47 -08:00
|
|
|
if (mHasInvalidCharacter) {
|
|
|
|
ReplaceCharacter(mFirstInvalidPosition, mReplacementCharacter);
|
|
|
|
}
|
|
|
|
}
|
1998-04-25 19:45:14 +00:00
|
|
|
|