Fix for bug 63081. We remove carriage returns passed to us by the parser in the copy from the sink buffer to the content model. r=jst

git-svn-id: svn://10.0.0.236/trunk@85317 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
vidur%netscape.com
2001-01-22 23:11:02 +00:00
parent bdb40b4833
commit 5624d576e9
12 changed files with 384 additions and 16 deletions

View File

@@ -118,4 +118,156 @@ nsLayoutUtils::GetDynamicScriptContext(JSContext *aContext,
(void**)aScriptContext);
}
template <class OutputIterator>
struct NormalizeNewlinesCharTraits {
public:
typedef typename OutputIterator::value_type value_type;
public:
NormalizeNewlinesCharTraits(OutputIterator& aIterator) : mIterator(aIterator) { }
void writechar(typename OutputIterator::value_type aChar) {
*mIterator++ = aChar;
}
private:
OutputIterator mIterator;
};
#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
template <class CharT>
struct NormalizeNewlinesCharTraits<CharT*> {
public:
typedef CharT value_type;
public:
NormalizeNewlinesCharTraits(CharT* aCharPtr) : mCharPtr(aCharPtr) { }
void writechar(CharT aChar) {
*mCharPtr++ = aChar;
}
private:
CharT* mCharPtr;
};
#else
NS_SPECIALIZE_TEMPLATE
struct NormalizeNewlinesCharTraits<char*> {
public:
typedef char value_type;
public:
NormalizeNewlinesCharTraits(char* aCharPtr) : mCharPtr(aCharPtr) { }
void writechar(char aChar) {
*mCharPtr++ = aChar;
}
private:
char* mCharPtr;
};
NS_SPECIALIZE_TEMPLATE
struct NormalizeNewlinesCharTraits<PRUnichar*> {
public:
typedef PRUnichar value_type;
public:
NormalizeNewlinesCharTraits(PRUnichar* aCharPtr) : mCharPtr(aCharPtr) { }
void writechar(PRUnichar aChar) {
*mCharPtr++ = aChar;
}
private:
PRUnichar* mCharPtr;
};
#endif
template <class OutputIterator>
class CopyNormalizeNewlines
{
public:
typedef typename OutputIterator::value_type value_type;
public:
CopyNormalizeNewlines(OutputIterator* aDestination) :
mLastCharCR(PR_FALSE),
mDestination(aDestination),
mWritten(0)
{ }
PRUint32 GetCharsWritten() {
return mWritten;
}
PRUint32 write(const typename OutputIterator::value_type* aSource, PRUint32 aSourceLength) {
// If the last source buffer ended with a CR...
if (mLastCharCR) {
// ..and if the next one is a LF, then skip it since
// we've already written out a newline
if (aSourceLength && (*aSource == value_type('\n'))) {
aSource++;
}
mLastCharCR = PR_FALSE;
}
const typename OutputIterator::value_type* done_writing = aSource + aSourceLength;
PRUint32 num_written = 0;
while ( aSource < done_writing ) {
if (*aSource == value_type('\r')) {
mDestination->writechar('\n');
aSource++;
// If we've reached the end of the buffer, record
// that we wrote out a CR
if (aSource == done_writing) {
mLastCharCR = PR_TRUE;
}
// If the next character is a LF, skip it
else if (*aSource == value_type('\n')) {
aSource++;
}
}
else {
mDestination->writechar(*aSource++);
}
num_written++;
}
mWritten += num_written;
return aSourceLength;
}
private:
PRBool mLastCharCR;
OutputIterator* mDestination;
PRUint32 mWritten;
};
// static
PRUint32
nsLayoutUtils::CopyNewlineNormalizedUnicodeTo(const nsAReadableString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength)
{
typedef NormalizeNewlinesCharTraits<PRUnichar*> sink_traits;
sink_traits dest_traits(aDest);
CopyNormalizeNewlines<sink_traits> normalizer(&dest_traits);
nsReadingIterator<PRUnichar> fromBegin, fromEnd;
copy_string(aSource.BeginReading(fromBegin).advance( PRInt32(aSrcOffset) ), aSource.BeginReading(fromEnd).advance( PRInt32(aSrcOffset+aLength) ), normalizer);
return normalizer.GetCharsWritten();
}
// static
PRUint32
nsLayoutUtils::CopyNewlineNormalizedUnicodeTo(nsReadingIterator<PRUnichar>& aSrcStart, const nsReadingIterator<PRUnichar>& aSrcEnd, nsAWritableString& aDest)
{
typedef nsWritingIterator<PRUnichar> WritingIterator;
typedef NormalizeNewlinesCharTraits<WritingIterator> sink_traits;
WritingIterator iter;
aDest.BeginWriting(iter);
sink_traits dest_traits(iter);
CopyNormalizeNewlines<sink_traits> normalizer(&dest_traits);
copy_string(aSrcStart, aSrcEnd, normalizer);
return normalizer.GetCharsWritten();
}