2000-08-05 04:51:37 +04:00
|
|
|
/* -*- 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.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 2000 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Original Author:
|
|
|
|
* Scott Collins <scc@mozilla.org>
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nsReadableUtils.h"
|
2000-08-05 07:32:36 +04:00
|
|
|
#include "nsMemory.h"
|
2000-08-05 04:51:37 +04:00
|
|
|
|
2000-08-05 05:15:45 +04:00
|
|
|
|
|
|
|
|
2000-08-05 08:25:49 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A character sink that performs a |reinterpret_cast| style conversion between character types.
|
|
|
|
*/
|
2000-08-05 07:32:36 +04:00
|
|
|
template <class FromCharT, class ToCharT>
|
|
|
|
class LossyConvertEncoding
|
2000-08-05 06:13:59 +04:00
|
|
|
{
|
|
|
|
public:
|
2000-08-05 07:32:36 +04:00
|
|
|
typedef FromCharT value_type;
|
|
|
|
|
|
|
|
typedef FromCharT input_type;
|
|
|
|
typedef ToCharT output_type;
|
2000-08-05 06:13:59 +04:00
|
|
|
|
|
|
|
public:
|
2000-08-05 07:32:36 +04:00
|
|
|
LossyConvertEncoding( output_type* aDestination ) : mDestination(aDestination) { }
|
2000-08-05 06:13:59 +04:00
|
|
|
|
|
|
|
PRUint32
|
|
|
|
write( const input_type* aSource, PRUint32 aSourceLength )
|
|
|
|
{
|
|
|
|
const input_type* done_writing = aSource + aSourceLength;
|
|
|
|
while ( aSource < done_writing )
|
2000-08-05 07:32:36 +04:00
|
|
|
*mDestination++ = (output_type)(*aSource++); // use old-style cast to mimic old |ns[C]String| behavior
|
|
|
|
return aSourceLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
write_terminator()
|
|
|
|
{
|
|
|
|
*mDestination = output_type(0);
|
2000-08-05 06:13:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2000-08-05 07:32:36 +04:00
|
|
|
output_type* mDestination;
|
2000-08-05 06:13:59 +04:00
|
|
|
};
|
|
|
|
|
2000-08-05 08:25:49 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A helper function that allocates a buffer of the desired character type big enough to hold a copy of the supplied string (plus a zero terminator).
|
|
|
|
*
|
|
|
|
* @param aSource an string you will eventually be making a copy of
|
|
|
|
* @return a new buffer (of the type specified by the second parameter) which you must free with |nsMemory::Free|.
|
|
|
|
*
|
|
|
|
*/
|
2000-08-05 07:32:36 +04:00
|
|
|
template <class FromCharT, class ToCharT>
|
|
|
|
inline
|
|
|
|
ToCharT*
|
|
|
|
AllocateStringCopy( const basic_nsAReadableString<FromCharT>& aSource, ToCharT* )
|
|
|
|
{
|
|
|
|
return NS_STATIC_CAST(ToCharT*, nsMemory::Alloc((aSource.Length()+1) * sizeof(ToCharT)));
|
|
|
|
}
|
2000-08-05 06:13:59 +04:00
|
|
|
|
2000-08-05 05:15:45 +04:00
|
|
|
|
|
|
|
char*
|
2000-08-05 07:32:36 +04:00
|
|
|
ToNewCString( const nsAReadableString& aSource )
|
2000-08-05 04:51:37 +04:00
|
|
|
{
|
2000-08-05 07:32:36 +04:00
|
|
|
char* result = AllocateStringCopy(aSource, (char*)0);
|
|
|
|
copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding<PRUnichar, char>(result)).write_terminator();
|
2000-08-05 06:13:59 +04:00
|
|
|
return result;
|
2000-08-05 04:51:37 +04:00
|
|
|
}
|
|
|
|
|
2000-08-05 07:32:36 +04:00
|
|
|
char*
|
|
|
|
ToNewCString( const nsAReadableCString& aSource )
|
2000-08-05 04:51:37 +04:00
|
|
|
{
|
2000-08-05 07:32:36 +04:00
|
|
|
// no conversion needed, just allocate a buffer of the correct length and copy into it
|
|
|
|
|
|
|
|
char* result = AllocateStringCopy(aSource, (char*)0);
|
|
|
|
*copy_string(aSource.BeginReading(), aSource.EndReading(), result) = char(0);
|
2000-08-05 06:13:59 +04:00
|
|
|
return result;
|
2000-08-05 04:51:37 +04:00
|
|
|
}
|
|
|
|
|
2000-08-05 07:32:36 +04:00
|
|
|
PRUnichar*
|
|
|
|
ToNewUnicode( const nsAReadableString& aSource )
|
|
|
|
{
|
|
|
|
// no conversion needed, just allocate a buffer of the correct length and copy into it
|
2000-08-05 05:15:45 +04:00
|
|
|
|
2000-08-05 07:32:36 +04:00
|
|
|
PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0);
|
|
|
|
*copy_string(aSource.BeginReading(), aSource.EndReading(), result) = PRUnichar(0);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRUnichar*
|
|
|
|
ToNewUnicode( const nsAReadableCString& aSource )
|
|
|
|
{
|
|
|
|
PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0);
|
|
|
|
copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding<char, PRUnichar>(result)).write_terminator();
|
|
|
|
return result;
|
|
|
|
}
|
2000-08-05 05:15:45 +04:00
|
|
|
|
2000-08-05 04:51:37 +04:00
|
|
|
PRBool
|
2000-08-05 07:32:36 +04:00
|
|
|
IsASCII( const nsAReadableString& aString )
|
2000-08-05 04:51:37 +04:00
|
|
|
{
|
2000-08-05 08:25:49 +04:00
|
|
|
static const PRUnichar NOT_ASCII = PRUnichar(~0x007F);
|
2000-08-05 04:51:37 +04:00
|
|
|
|
|
|
|
|
|
|
|
// Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character
|
|
|
|
|
2000-08-05 07:32:36 +04:00
|
|
|
typedef nsAReadableString::const_iterator iterator;
|
|
|
|
iterator iter = aString.BeginReading();
|
|
|
|
iterator done_reading = aString.EndReading();
|
2000-08-05 04:51:37 +04:00
|
|
|
|
2000-08-05 07:32:36 +04:00
|
|
|
// for each chunk of |aString|...
|
2000-08-05 04:51:37 +04:00
|
|
|
while ( iter != done_reading )
|
|
|
|
{
|
2000-08-05 07:32:36 +04:00
|
|
|
iterator::difference_type chunk_size = iter.size_forward();
|
2000-08-05 04:51:37 +04:00
|
|
|
const PRUnichar* c = iter.get();
|
|
|
|
const PRUnichar* chunk_end = c + chunk_size;
|
|
|
|
|
|
|
|
// for each character in this chunk...
|
|
|
|
while ( c < chunk_end )
|
|
|
|
if ( *c++ & NOT_ASCII )
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
iter += chunk_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
2000-08-05 06:13:59 +04:00
|
|
|
}
|
|
|
|
|