Remove dead string files from the tree, r=dbaron, rs=scc

This commit is contained in:
jaggernaut%netscape.com 2001-09-24 23:55:19 +00:00
Родитель f801e503cc
Коммит dec9bd6a52
8 изменённых файлов: 0 добавлений и 1542 удалений

Просмотреть файл

@ -1,269 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsPromiseConcatenation.h --- string concatenation machinery lives here, but don't include this file
directly, always get it by including either "nsAString.h" or one of the compatibility headers */
#ifndef nsPromiseConcatenation_h___
#define nsPromiseConcatenation_h___
/**
NOT FOR USE BY HUMANS
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
- left to right evaluation is required ... do not use parentheses to override this
In practice, neither of these is onerous. Parentheses do not change the semantics of the
concatenation, only the order in which the result is assembled ... so there's no reason
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetReadableFragment()|.
*/
class NS_COM nsPromiseConcatenation
: public nsAPromiseString
{
public:
typedef nsPromiseConcatenation self_type;
typedef PRUnichar char_type;
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
class NS_COM nsPromiseCConcatenation
: public nsAPromiseCString
{
public:
typedef nsPromiseCConcatenation self_type;
typedef char char_type;
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseCConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseCConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseCConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
/*
How shall we provide |operator+()|?
What would it return? It has to return a stack based object, because the client will
not be given an opportunity to handle memory management in an expression like
myWritableString = stringA + stringB + stringC;
...so the `obvious' answer of returning a new |nsSharedString| is no good. We could
return an |nsString|, if that name were in scope here, though there's no telling what the client
will really want to do with the result. What might be better, though,
is to return a `promise' to concatenate some strings...
By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle
assignment and other interesting uses within writable strings, plus we drastically reduce
the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings
in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work
to implement the virtual functions of readables.
*/
inline
const nsPromiseConcatenation
operator+( const nsPromiseConcatenation& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseCConcatenation
operator+( const nsPromiseCConcatenation& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseConcatenation
operator+( const nsAString& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs);
}
inline
const nsPromiseCConcatenation
operator+( const nsACString& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs);
}
#if 0
inline
const nsPromiseConcatenation
nsPromiseConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
inline
const nsPromiseCConcatenation
nsPromiseCConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseCConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
#endif
#endif /* !defined(nsPromiseConcatenation_h___) */

Просмотреть файл

@ -1,182 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsPromiseSubstring_h___
#define nsPromiseSubstring_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
//
// nsPromiseSubstring
//
class NS_COM nsPromiseSubstring
: public nsAPromiseString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
class NS_COM nsPromiseCSubstring
: public nsAPromiseCString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseCSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseCSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseCSubstring( const nsPromiseCSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseCSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
inline
const nsPromiseCSubstring
Substring( const nsACString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseCSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseSubstring
Substring( const nsAString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseCSubstring
Substring( const nsReadingIterator<char>& aStart, const nsReadingIterator<char>& aEnd )
{
return nsPromiseCSubstring(aStart, aEnd);
}
inline
const nsPromiseSubstring
Substring( const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd )
{
return nsPromiseSubstring(aStart, aEnd);
}
#endif /* !defined(nsPromiseSubstring_h___) */

Просмотреть файл

@ -1,197 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsAString.h"
// remember, no one should include "nsPromiseConcatenation.h" themselves
// one always gets it through "nsAString.h"
PRUint32
nsPromiseConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const PRUnichar*
nsPromiseConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}
PRUint32
nsPromiseCConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseCConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseCConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const char*
nsPromiseCConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}

Просмотреть файл

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsPromiseSubstring.h"
PRUint32
nsPromiseSubstring::Length() const
{
return mLength;
}
const PRUnichar*
nsPromiseSubstring::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const PRUnichar* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}
PRUint32
nsPromiseCSubstring::Length() const
{
return mLength;
}
const char*
nsPromiseCSubstring::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const char* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}

Просмотреть файл

@ -1,269 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsPromiseConcatenation.h --- string concatenation machinery lives here, but don't include this file
directly, always get it by including either "nsAString.h" or one of the compatibility headers */
#ifndef nsPromiseConcatenation_h___
#define nsPromiseConcatenation_h___
/**
NOT FOR USE BY HUMANS
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
- left to right evaluation is required ... do not use parentheses to override this
In practice, neither of these is onerous. Parentheses do not change the semantics of the
concatenation, only the order in which the result is assembled ... so there's no reason
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetReadableFragment()|.
*/
class NS_COM nsPromiseConcatenation
: public nsAPromiseString
{
public:
typedef nsPromiseConcatenation self_type;
typedef PRUnichar char_type;
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
class NS_COM nsPromiseCConcatenation
: public nsAPromiseCString
{
public:
typedef nsPromiseCConcatenation self_type;
typedef char char_type;
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseCConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseCConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseCConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
/*
How shall we provide |operator+()|?
What would it return? It has to return a stack based object, because the client will
not be given an opportunity to handle memory management in an expression like
myWritableString = stringA + stringB + stringC;
...so the `obvious' answer of returning a new |nsSharedString| is no good. We could
return an |nsString|, if that name were in scope here, though there's no telling what the client
will really want to do with the result. What might be better, though,
is to return a `promise' to concatenate some strings...
By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle
assignment and other interesting uses within writable strings, plus we drastically reduce
the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings
in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work
to implement the virtual functions of readables.
*/
inline
const nsPromiseConcatenation
operator+( const nsPromiseConcatenation& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseCConcatenation
operator+( const nsPromiseCConcatenation& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseConcatenation
operator+( const nsAString& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs);
}
inline
const nsPromiseCConcatenation
operator+( const nsACString& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs);
}
#if 0
inline
const nsPromiseConcatenation
nsPromiseConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
inline
const nsPromiseCConcatenation
nsPromiseCConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseCConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
#endif
#endif /* !defined(nsPromiseConcatenation_h___) */

Просмотреть файл

@ -1,182 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsPromiseSubstring_h___
#define nsPromiseSubstring_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
//
// nsPromiseSubstring
//
class NS_COM nsPromiseSubstring
: public nsAPromiseString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
class NS_COM nsPromiseCSubstring
: public nsAPromiseCString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseCSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseCSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseCSubstring( const nsPromiseCSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseCSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
inline
const nsPromiseCSubstring
Substring( const nsACString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseCSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseSubstring
Substring( const nsAString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseCSubstring
Substring( const nsReadingIterator<char>& aStart, const nsReadingIterator<char>& aEnd )
{
return nsPromiseCSubstring(aStart, aEnd);
}
inline
const nsPromiseSubstring
Substring( const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd )
{
return nsPromiseSubstring(aStart, aEnd);
}
#endif /* !defined(nsPromiseSubstring_h___) */

Просмотреть файл

@ -1,197 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsAString.h"
// remember, no one should include "nsPromiseConcatenation.h" themselves
// one always gets it through "nsAString.h"
PRUint32
nsPromiseConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const PRUnichar*
nsPromiseConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}
PRUint32
nsPromiseCConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseCConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseCConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const char*
nsPromiseCConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}

Просмотреть файл

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsPromiseSubstring.h"
PRUint32
nsPromiseSubstring::Length() const
{
return mLength;
}
const PRUnichar*
nsPromiseSubstring::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const PRUnichar* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}
PRUint32
nsPromiseCSubstring::Length() const
{
return mLength;
}
const char*
nsPromiseCSubstring::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const char* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}