parser/htmlparser/public/nsScannerString.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef nsScannerString_h___
michael@0 8 #define nsScannerString_h___
michael@0 9
michael@0 10 #include "nsString.h"
michael@0 11 #include "nsUnicharUtils.h" // for nsCaseInsensitiveStringComparator
michael@0 12 #include "mozilla/LinkedList.h"
michael@0 13 #include <algorithm>
michael@0 14
michael@0 15
michael@0 16 /**
michael@0 17 * NOTE: nsScannerString (and the other classes defined in this file) are
michael@0 18 * not related to nsAString or any of the other xpcom/string classes.
michael@0 19 *
michael@0 20 * nsScannerString is based on the nsSlidingString implementation that used
michael@0 21 * to live in xpcom/string. Now that nsAString is limited to representing
michael@0 22 * only single fragment strings, nsSlidingString can no longer be used.
michael@0 23 *
michael@0 24 * An advantage to this design is that it does not employ any virtual
michael@0 25 * functions.
michael@0 26 *
michael@0 27 * This file uses SCC-style indenting in deference to the nsSlidingString
michael@0 28 * code from which this code is derived ;-)
michael@0 29 */
michael@0 30
michael@0 31 class nsScannerIterator;
michael@0 32 class nsScannerSubstring;
michael@0 33 class nsScannerString;
michael@0 34
michael@0 35
michael@0 36 /**
michael@0 37 * nsScannerBufferList
michael@0 38 *
michael@0 39 * This class maintains a list of heap-allocated Buffer objects. The buffers
michael@0 40 * are maintained in a circular linked list. Each buffer has a usage count
michael@0 41 * that is decremented by the owning nsScannerSubstring.
michael@0 42 *
michael@0 43 * The buffer list itself is reference counted. This allows the buffer list
michael@0 44 * to be shared by multiple nsScannerSubstring objects. The reference
michael@0 45 * counting is not threadsafe, which is not at all a requirement.
michael@0 46 *
michael@0 47 * When a nsScannerSubstring releases its reference to a buffer list, it
michael@0 48 * decrements the usage count of the first buffer in the buffer list that it
michael@0 49 * was referencing. It informs the buffer list that it can discard buffers
michael@0 50 * starting at that prefix. The buffer list will do so if the usage count of
michael@0 51 * that buffer is 0 and if it is the first buffer in the list. It will
michael@0 52 * continue to prune buffers starting from the front of the buffer list until
michael@0 53 * it finds a buffer that has a usage count that is non-zero.
michael@0 54 */
michael@0 55 class nsScannerBufferList
michael@0 56 {
michael@0 57 public:
michael@0 58
michael@0 59 /**
michael@0 60 * Buffer objects are directly followed by a data segment. The start
michael@0 61 * of the data segment is determined by increment the |this| pointer
michael@0 62 * by 1 unit.
michael@0 63 */
michael@0 64 class Buffer : public mozilla::LinkedListElement<Buffer>
michael@0 65 {
michael@0 66 public:
michael@0 67
michael@0 68 void IncrementUsageCount() { ++mUsageCount; }
michael@0 69 void DecrementUsageCount() { --mUsageCount; }
michael@0 70
michael@0 71 bool IsInUse() const { return mUsageCount != 0; }
michael@0 72
michael@0 73 const char16_t* DataStart() const { return (const char16_t*) (this+1); }
michael@0 74 char16_t* DataStart() { return ( char16_t*) (this+1); }
michael@0 75
michael@0 76 const char16_t* DataEnd() const { return mDataEnd; }
michael@0 77 char16_t* DataEnd() { return mDataEnd; }
michael@0 78
michael@0 79 const Buffer* Next() const { return getNext(); }
michael@0 80 Buffer* Next() { return getNext(); }
michael@0 81
michael@0 82 const Buffer* Prev() const { return getPrevious(); }
michael@0 83 Buffer* Prev() { return getPrevious(); }
michael@0 84
michael@0 85 uint32_t DataLength() const { return mDataEnd - DataStart(); }
michael@0 86 void SetDataLength(uint32_t len) { mDataEnd = DataStart() + len; }
michael@0 87
michael@0 88 private:
michael@0 89
michael@0 90 friend class nsScannerBufferList;
michael@0 91
michael@0 92 int32_t mUsageCount;
michael@0 93 char16_t* mDataEnd;
michael@0 94 };
michael@0 95
michael@0 96 /**
michael@0 97 * Position objects serve as lightweight pointers into a buffer list.
michael@0 98 * The mPosition member must be contained with mBuffer->DataStart()
michael@0 99 * and mBuffer->DataEnd().
michael@0 100 */
michael@0 101 class Position
michael@0 102 {
michael@0 103 public:
michael@0 104
michael@0 105 Position() {}
michael@0 106
michael@0 107 Position( Buffer* buffer, char16_t* position )
michael@0 108 : mBuffer(buffer)
michael@0 109 , mPosition(position)
michael@0 110 {}
michael@0 111
michael@0 112 inline
michael@0 113 Position( const nsScannerIterator& aIter );
michael@0 114
michael@0 115 inline
michael@0 116 Position& operator=( const nsScannerIterator& aIter );
michael@0 117
michael@0 118 static size_t Distance( const Position& p1, const Position& p2 );
michael@0 119
michael@0 120 Buffer* mBuffer;
michael@0 121 char16_t* mPosition;
michael@0 122 };
michael@0 123
michael@0 124 static Buffer* AllocBufferFromString( const nsAString& );
michael@0 125 static Buffer* AllocBuffer( uint32_t capacity ); // capacity = number of chars
michael@0 126
michael@0 127 nsScannerBufferList( Buffer* buf )
michael@0 128 : mRefCnt(0)
michael@0 129 {
michael@0 130 mBuffers.insertBack(buf);
michael@0 131 }
michael@0 132
michael@0 133 void AddRef() { ++mRefCnt; }
michael@0 134 void Release() { if (--mRefCnt == 0) delete this; }
michael@0 135
michael@0 136 void Append( Buffer* buf ) { mBuffers.insertBack(buf); }
michael@0 137 void InsertAfter( Buffer* buf, Buffer* prev ) { prev->setNext(buf); }
michael@0 138 void SplitBuffer( const Position& );
michael@0 139 void DiscardUnreferencedPrefix( Buffer* );
michael@0 140
michael@0 141 Buffer* Head() { return mBuffers.getFirst(); }
michael@0 142 const Buffer* Head() const { return mBuffers.getFirst(); }
michael@0 143
michael@0 144 Buffer* Tail() { return mBuffers.getLast(); }
michael@0 145 const Buffer* Tail() const { return mBuffers.getLast(); }
michael@0 146
michael@0 147 private:
michael@0 148
michael@0 149 friend class nsScannerSubstring;
michael@0 150
michael@0 151 ~nsScannerBufferList() { ReleaseAll(); }
michael@0 152 void ReleaseAll();
michael@0 153
michael@0 154 int32_t mRefCnt;
michael@0 155 mozilla::LinkedList<Buffer> mBuffers;
michael@0 156 };
michael@0 157
michael@0 158
michael@0 159 /**
michael@0 160 * nsScannerFragment represents a "slice" of a Buffer object.
michael@0 161 */
michael@0 162 struct nsScannerFragment
michael@0 163 {
michael@0 164 typedef nsScannerBufferList::Buffer Buffer;
michael@0 165
michael@0 166 const Buffer* mBuffer;
michael@0 167 const char16_t* mFragmentStart;
michael@0 168 const char16_t* mFragmentEnd;
michael@0 169 };
michael@0 170
michael@0 171
michael@0 172 /**
michael@0 173 * nsScannerSubstring is the base class for nsScannerString. It provides
michael@0 174 * access to iterators and methods to bind the substring to another
michael@0 175 * substring or nsAString instance.
michael@0 176 *
michael@0 177 * This class owns the buffer list.
michael@0 178 */
michael@0 179 class nsScannerSubstring
michael@0 180 {
michael@0 181 public:
michael@0 182 typedef nsScannerBufferList::Buffer Buffer;
michael@0 183 typedef nsScannerBufferList::Position Position;
michael@0 184 typedef uint32_t size_type;
michael@0 185
michael@0 186 nsScannerSubstring();
michael@0 187 nsScannerSubstring( const nsAString& s );
michael@0 188
michael@0 189 ~nsScannerSubstring();
michael@0 190
michael@0 191 nsScannerIterator& BeginReading( nsScannerIterator& iter ) const;
michael@0 192 nsScannerIterator& EndReading( nsScannerIterator& iter ) const;
michael@0 193
michael@0 194 size_type Length() const { return mLength; }
michael@0 195
michael@0 196 int32_t CountChar( char16_t ) const;
michael@0 197
michael@0 198 void Rebind( const nsScannerSubstring&, const nsScannerIterator&, const nsScannerIterator& );
michael@0 199 void Rebind( const nsAString& );
michael@0 200
michael@0 201 const nsSubstring& AsString() const;
michael@0 202
michael@0 203 bool GetNextFragment( nsScannerFragment& ) const;
michael@0 204 bool GetPrevFragment( nsScannerFragment& ) const;
michael@0 205
michael@0 206 static inline Buffer* AllocBufferFromString( const nsAString& aStr ) { return nsScannerBufferList::AllocBufferFromString(aStr); }
michael@0 207 static inline Buffer* AllocBuffer( size_type aCapacity ) { return nsScannerBufferList::AllocBuffer(aCapacity); }
michael@0 208
michael@0 209 protected:
michael@0 210
michael@0 211 void acquire_ownership_of_buffer_list() const
michael@0 212 {
michael@0 213 mBufferList->AddRef();
michael@0 214 mStart.mBuffer->IncrementUsageCount();
michael@0 215 }
michael@0 216
michael@0 217 void release_ownership_of_buffer_list()
michael@0 218 {
michael@0 219 if (mBufferList)
michael@0 220 {
michael@0 221 mStart.mBuffer->DecrementUsageCount();
michael@0 222 mBufferList->DiscardUnreferencedPrefix(mStart.mBuffer);
michael@0 223 mBufferList->Release();
michael@0 224 }
michael@0 225 }
michael@0 226
michael@0 227 void init_range_from_buffer_list()
michael@0 228 {
michael@0 229 mStart.mBuffer = mBufferList->Head();
michael@0 230 mStart.mPosition = mStart.mBuffer->DataStart();
michael@0 231
michael@0 232 mEnd.mBuffer = mBufferList->Tail();
michael@0 233 mEnd.mPosition = mEnd.mBuffer->DataEnd();
michael@0 234
michael@0 235 mLength = Position::Distance(mStart, mEnd);
michael@0 236 }
michael@0 237
michael@0 238 Position mStart;
michael@0 239 Position mEnd;
michael@0 240 nsScannerBufferList *mBufferList;
michael@0 241 size_type mLength;
michael@0 242
michael@0 243 // these fields are used to implement AsString
michael@0 244 nsDependentSubstring mFlattenedRep;
michael@0 245 bool mIsDirty;
michael@0 246
michael@0 247 friend class nsScannerSharedSubstring;
michael@0 248 };
michael@0 249
michael@0 250
michael@0 251 /**
michael@0 252 * nsScannerString provides methods to grow and modify a buffer list.
michael@0 253 */
michael@0 254 class nsScannerString : public nsScannerSubstring
michael@0 255 {
michael@0 256 public:
michael@0 257
michael@0 258 nsScannerString( Buffer* );
michael@0 259
michael@0 260 // you are giving ownership to the string, it takes and keeps your
michael@0 261 // buffer, deleting it when done.
michael@0 262 // Use AllocBuffer or AllocBufferFromString to create a Buffer object
michael@0 263 // for use with this function.
michael@0 264 void AppendBuffer( Buffer* );
michael@0 265
michael@0 266 void DiscardPrefix( const nsScannerIterator& );
michael@0 267 // any other way you want to do this?
michael@0 268
michael@0 269 void UngetReadable(const nsAString& aReadable, const nsScannerIterator& aCurrentPosition);
michael@0 270 void ReplaceCharacter(nsScannerIterator& aPosition, char16_t aChar);
michael@0 271 };
michael@0 272
michael@0 273
michael@0 274 /**
michael@0 275 * nsScannerSharedSubstring implements copy-on-write semantics for
michael@0 276 * nsScannerSubstring. When you call .writable(), it will copy the data
michael@0 277 * and return a mutable string object. This class also manages releasing
michael@0 278 * the reference to the scanner buffer when it is no longer needed.
michael@0 279 */
michael@0 280
michael@0 281 class nsScannerSharedSubstring
michael@0 282 {
michael@0 283 public:
michael@0 284 nsScannerSharedSubstring()
michael@0 285 : mBuffer(nullptr), mBufferList(nullptr) { }
michael@0 286
michael@0 287 ~nsScannerSharedSubstring()
michael@0 288 {
michael@0 289 if (mBufferList)
michael@0 290 ReleaseBuffer();
michael@0 291 }
michael@0 292
michael@0 293 // Acquire a copy-on-write reference to the given substring.
michael@0 294 NS_HIDDEN_(void) Rebind(const nsScannerIterator& aStart,
michael@0 295 const nsScannerIterator& aEnd);
michael@0 296
michael@0 297 // Get a mutable reference to this string
michael@0 298 nsSubstring& writable()
michael@0 299 {
michael@0 300 if (mBufferList)
michael@0 301 MakeMutable();
michael@0 302
michael@0 303 return mString;
michael@0 304 }
michael@0 305
michael@0 306 // Get a const reference to this string
michael@0 307 const nsSubstring& str() const { return mString; }
michael@0 308
michael@0 309 private:
michael@0 310 typedef nsScannerBufferList::Buffer Buffer;
michael@0 311
michael@0 312 NS_HIDDEN_(void) ReleaseBuffer();
michael@0 313 NS_HIDDEN_(void) MakeMutable();
michael@0 314
michael@0 315 nsDependentSubstring mString;
michael@0 316 Buffer *mBuffer;
michael@0 317 nsScannerBufferList *mBufferList;
michael@0 318 };
michael@0 319
michael@0 320 /**
michael@0 321 * nsScannerIterator works just like nsReadingIterator<CharT> except that
michael@0 322 * it knows how to iterate over a list of scanner buffers.
michael@0 323 */
michael@0 324 class nsScannerIterator
michael@0 325 {
michael@0 326 public:
michael@0 327 typedef nsScannerIterator self_type;
michael@0 328 typedef ptrdiff_t difference_type;
michael@0 329 typedef char16_t value_type;
michael@0 330 typedef const char16_t* pointer;
michael@0 331 typedef const char16_t& reference;
michael@0 332 typedef nsScannerSubstring::Buffer Buffer;
michael@0 333
michael@0 334 protected:
michael@0 335
michael@0 336 nsScannerFragment mFragment;
michael@0 337 const char16_t* mPosition;
michael@0 338 const nsScannerSubstring* mOwner;
michael@0 339
michael@0 340 friend class nsScannerSubstring;
michael@0 341 friend class nsScannerSharedSubstring;
michael@0 342
michael@0 343 public:
michael@0 344 nsScannerIterator() {}
michael@0 345 // nsScannerIterator( const nsScannerIterator& ); // auto-generated copy-constructor OK
michael@0 346 // nsScannerIterator& operator=( const nsScannerIterator& ); // auto-generated copy-assignment operator OK
michael@0 347
michael@0 348 inline void normalize_forward();
michael@0 349 inline void normalize_backward();
michael@0 350
michael@0 351 pointer get() const
michael@0 352 {
michael@0 353 return mPosition;
michael@0 354 }
michael@0 355
michael@0 356 char16_t operator*() const
michael@0 357 {
michael@0 358 return *get();
michael@0 359 }
michael@0 360
michael@0 361 const nsScannerFragment& fragment() const
michael@0 362 {
michael@0 363 return mFragment;
michael@0 364 }
michael@0 365
michael@0 366 const Buffer* buffer() const
michael@0 367 {
michael@0 368 return mFragment.mBuffer;
michael@0 369 }
michael@0 370
michael@0 371 self_type& operator++()
michael@0 372 {
michael@0 373 ++mPosition;
michael@0 374 normalize_forward();
michael@0 375 return *this;
michael@0 376 }
michael@0 377
michael@0 378 self_type operator++( int )
michael@0 379 {
michael@0 380 self_type result(*this);
michael@0 381 ++mPosition;
michael@0 382 normalize_forward();
michael@0 383 return result;
michael@0 384 }
michael@0 385
michael@0 386 self_type& operator--()
michael@0 387 {
michael@0 388 normalize_backward();
michael@0 389 --mPosition;
michael@0 390 return *this;
michael@0 391 }
michael@0 392
michael@0 393 self_type operator--( int )
michael@0 394 {
michael@0 395 self_type result(*this);
michael@0 396 normalize_backward();
michael@0 397 --mPosition;
michael@0 398 return result;
michael@0 399 }
michael@0 400
michael@0 401 difference_type size_forward() const
michael@0 402 {
michael@0 403 return mFragment.mFragmentEnd - mPosition;
michael@0 404 }
michael@0 405
michael@0 406 difference_type size_backward() const
michael@0 407 {
michael@0 408 return mPosition - mFragment.mFragmentStart;
michael@0 409 }
michael@0 410
michael@0 411 self_type& advance( difference_type n )
michael@0 412 {
michael@0 413 while ( n > 0 )
michael@0 414 {
michael@0 415 difference_type one_hop = std::min(n, size_forward());
michael@0 416
michael@0 417 NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string");
michael@0 418 // perhaps I should |break| if |!one_hop|?
michael@0 419
michael@0 420 mPosition += one_hop;
michael@0 421 normalize_forward();
michael@0 422 n -= one_hop;
michael@0 423 }
michael@0 424
michael@0 425 while ( n < 0 )
michael@0 426 {
michael@0 427 normalize_backward();
michael@0 428 difference_type one_hop = std::max(n, -size_backward());
michael@0 429
michael@0 430 NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string");
michael@0 431 // perhaps I should |break| if |!one_hop|?
michael@0 432
michael@0 433 mPosition += one_hop;
michael@0 434 n -= one_hop;
michael@0 435 }
michael@0 436
michael@0 437 return *this;
michael@0 438 }
michael@0 439 };
michael@0 440
michael@0 441
michael@0 442 inline
michael@0 443 bool
michael@0 444 SameFragment( const nsScannerIterator& a, const nsScannerIterator& b )
michael@0 445 {
michael@0 446 return a.fragment().mFragmentStart == b.fragment().mFragmentStart;
michael@0 447 }
michael@0 448
michael@0 449
michael@0 450 /**
michael@0 451 * this class is needed in order to make use of the methods in nsAlgorithm.h
michael@0 452 */
michael@0 453 template <>
michael@0 454 struct nsCharSourceTraits<nsScannerIterator>
michael@0 455 {
michael@0 456 typedef nsScannerIterator::difference_type difference_type;
michael@0 457
michael@0 458 static
michael@0 459 uint32_t
michael@0 460 readable_distance( const nsScannerIterator& first, const nsScannerIterator& last )
michael@0 461 {
michael@0 462 return uint32_t(SameFragment(first, last) ? last.get() - first.get() : first.size_forward());
michael@0 463 }
michael@0 464
michael@0 465 static
michael@0 466 const nsScannerIterator::value_type*
michael@0 467 read( const nsScannerIterator& iter )
michael@0 468 {
michael@0 469 return iter.get();
michael@0 470 }
michael@0 471
michael@0 472 static
michael@0 473 void
michael@0 474 advance( nsScannerIterator& s, difference_type n )
michael@0 475 {
michael@0 476 s.advance(n);
michael@0 477 }
michael@0 478 };
michael@0 479
michael@0 480
michael@0 481 /**
michael@0 482 * inline methods follow
michael@0 483 */
michael@0 484
michael@0 485 inline
michael@0 486 void
michael@0 487 nsScannerIterator::normalize_forward()
michael@0 488 {
michael@0 489 while (mPosition == mFragment.mFragmentEnd && mOwner->GetNextFragment(mFragment))
michael@0 490 mPosition = mFragment.mFragmentStart;
michael@0 491 }
michael@0 492
michael@0 493 inline
michael@0 494 void
michael@0 495 nsScannerIterator::normalize_backward()
michael@0 496 {
michael@0 497 while (mPosition == mFragment.mFragmentStart && mOwner->GetPrevFragment(mFragment))
michael@0 498 mPosition = mFragment.mFragmentEnd;
michael@0 499 }
michael@0 500
michael@0 501 inline
michael@0 502 bool
michael@0 503 operator==( const nsScannerIterator& lhs, const nsScannerIterator& rhs )
michael@0 504 {
michael@0 505 return lhs.get() == rhs.get();
michael@0 506 }
michael@0 507
michael@0 508 inline
michael@0 509 bool
michael@0 510 operator!=( const nsScannerIterator& lhs, const nsScannerIterator& rhs )
michael@0 511 {
michael@0 512 return lhs.get() != rhs.get();
michael@0 513 }
michael@0 514
michael@0 515
michael@0 516 inline
michael@0 517 nsScannerBufferList::Position::Position(const nsScannerIterator& aIter)
michael@0 518 : mBuffer(const_cast<Buffer*>(aIter.buffer()))
michael@0 519 , mPosition(const_cast<char16_t*>(aIter.get()))
michael@0 520 {}
michael@0 521
michael@0 522 inline
michael@0 523 nsScannerBufferList::Position&
michael@0 524 nsScannerBufferList::Position::operator=(const nsScannerIterator& aIter)
michael@0 525 {
michael@0 526 mBuffer = const_cast<Buffer*>(aIter.buffer());
michael@0 527 mPosition = const_cast<char16_t*>(aIter.get());
michael@0 528 return *this;
michael@0 529 }
michael@0 530
michael@0 531
michael@0 532 /**
michael@0 533 * scanner string utils
michael@0 534 *
michael@0 535 * These methods mimic the API provided by nsReadableUtils in xpcom/string.
michael@0 536 * Here we provide only the methods that the htmlparser module needs.
michael@0 537 */
michael@0 538
michael@0 539 inline
michael@0 540 size_t
michael@0 541 Distance( const nsScannerIterator& aStart, const nsScannerIterator& aEnd )
michael@0 542 {
michael@0 543 typedef nsScannerBufferList::Position Position;
michael@0 544 return Position::Distance(Position(aStart), Position(aEnd));
michael@0 545 }
michael@0 546
michael@0 547 void
michael@0 548 CopyUnicodeTo( const nsScannerIterator& aSrcStart,
michael@0 549 const nsScannerIterator& aSrcEnd,
michael@0 550 nsAString& aDest );
michael@0 551
michael@0 552 inline
michael@0 553 void
michael@0 554 CopyUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
michael@0 555 {
michael@0 556 nsScannerIterator begin, end;
michael@0 557 CopyUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
michael@0 558 }
michael@0 559
michael@0 560 void
michael@0 561 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
michael@0 562 const nsScannerIterator& aSrcEnd,
michael@0 563 nsAString& aDest );
michael@0 564
michael@0 565 inline
michael@0 566 void
michael@0 567 AppendUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
michael@0 568 {
michael@0 569 nsScannerIterator begin, end;
michael@0 570 AppendUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
michael@0 571 }
michael@0 572
michael@0 573 void
michael@0 574 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
michael@0 575 const nsScannerIterator& aSrcEnd,
michael@0 576 nsScannerSharedSubstring& aDest );
michael@0 577
michael@0 578 bool
michael@0 579 FindCharInReadable( char16_t aChar,
michael@0 580 nsScannerIterator& aStart,
michael@0 581 const nsScannerIterator& aEnd );
michael@0 582
michael@0 583 bool
michael@0 584 FindInReadable( const nsAString& aPattern,
michael@0 585 nsScannerIterator& aStart,
michael@0 586 nsScannerIterator& aEnd,
michael@0 587 const nsStringComparator& = nsDefaultStringComparator() );
michael@0 588
michael@0 589 bool
michael@0 590 RFindInReadable( const nsAString& aPattern,
michael@0 591 nsScannerIterator& aStart,
michael@0 592 nsScannerIterator& aEnd,
michael@0 593 const nsStringComparator& = nsDefaultStringComparator() );
michael@0 594
michael@0 595 inline
michael@0 596 bool
michael@0 597 CaseInsensitiveFindInReadable( const nsAString& aPattern,
michael@0 598 nsScannerIterator& aStart,
michael@0 599 nsScannerIterator& aEnd )
michael@0 600 {
michael@0 601 return FindInReadable(aPattern, aStart, aEnd,
michael@0 602 nsCaseInsensitiveStringComparator());
michael@0 603 }
michael@0 604
michael@0 605 #endif // !defined(nsScannerString_h___)

mercurial