fixes bug 166612 "implement NS_CopyNativeToUnicode / NS_CopyUnicodeToNative

on all platforms" r=dougt sr=alecf
This commit is contained in:
darin%netscape.com 2002-10-06 00:29:46 +00:00
Родитель 6a89f8aa64
Коммит 2d08c9acd7
6 изменённых файлов: 536 добавлений и 395 удалений

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

@ -29,6 +29,7 @@
#include "nsXPIDLString.h"
#include "nsLocalFileMac.h"
#include "nsNativeCharsetUtils.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
#include "nsIInternetConfigService.h"
@ -62,7 +63,6 @@
#include <AEDataModel.h>
#include <AERegistry.h>
#include <Gestalt.h>
#include <UnicodeConverter.h>
#include <Math64.h>
#include <Aliases.h>
@ -149,168 +149,6 @@ nsPathParser::nsPathParser(const nsACString &inPath) :
mBuffer[offset] = '\0';
}
#pragma mark -
#pragma mark [nsFSStringConversionMac]
class nsFSStringConversionMac {
public:
static nsresult UCSToFS(const nsAString& aIn, nsACString& aOut);
static nsresult FSToUCS(const nsACString& ain, nsAString& aOut);
static void CleanUp();
private:
static TextEncoding GetSystemEncoding();
static nsresult PrepareEncoder();
static nsresult PrepareDecoder();
static UnicodeToTextInfo sEncoderInfo;
static TextToUnicodeInfo sDecoderInfo;
};
UnicodeToTextInfo nsFSStringConversionMac::sEncoderInfo = nsnull;
TextToUnicodeInfo nsFSStringConversionMac::sDecoderInfo = nsnull;
nsresult nsFSStringConversionMac::UCSToFS(const nsAString& aIn, nsACString& aOut)
{
nsresult rv = PrepareEncoder();
if (NS_FAILED(rv)) return rv;
OSStatus err = noErr;
char stackBuffer[512];
aOut.Truncate(0);
nsReadingIterator<PRUnichar> done_reading;
aIn.EndReading(done_reading);
// for each chunk of |aIn|...
PRUint32 fragmentLength = 0;
nsReadingIterator<PRUnichar> iter;
for (aIn.BeginReading(iter); iter != done_reading && err == noErr; iter.advance(PRInt32(fragmentLength)))
{
fragmentLength = PRUint32(iter.size_forward());
UInt32 bytesLeft = fragmentLength * sizeof(UniChar);
nsReadingIterator<PRUnichar> sub_iter(iter);
do {
UInt32 bytesRead = 0, bytesWritten = 0;
err = ::ConvertFromUnicodeToText(sEncoderInfo,
bytesLeft,
(const UniChar*)sub_iter.get(),
kUnicodeUseFallbacksMask | kUnicodeLooseMappingsMask,
0, nsnull, nsnull, nsnull,
sizeof(stackBuffer),
&bytesRead,
&bytesWritten,
stackBuffer);
if (err == kTECUsedFallbacksStatus)
err = noErr;
else if (err == kTECOutputBufferFullStatus) {
bytesLeft -= bytesRead;
sub_iter.advance(bytesRead / sizeof(UniChar));
}
aOut.Append(stackBuffer, bytesWritten);
}
while (err == kTECOutputBufferFullStatus);
}
return (err == noErr) ? NS_OK : NS_ERROR_FAILURE;
}
nsresult nsFSStringConversionMac::FSToUCS(const nsACString& aIn, nsAString& aOut)
{
nsresult rv = PrepareDecoder();
if (NS_FAILED(rv)) return rv;
OSStatus err = noErr;
UniChar stackBuffer[512];
aOut.Truncate(0);
nsReadingIterator<char> done_reading;
aIn.EndReading(done_reading);
// for each chunk of |aIn|...
PRUint32 fragmentLength = 0;
nsReadingIterator<char> iter;
for (aIn.BeginReading(iter); iter != done_reading && err == noErr; iter.advance(PRInt32(fragmentLength)))
{
fragmentLength = PRUint32(iter.size_forward());
UInt32 bytesLeft = fragmentLength;
nsReadingIterator<char> sub_iter(iter);
do {
UInt32 bytesRead = 0, bytesWritten = 0;
err = ::ConvertFromTextToUnicode(sDecoderInfo,
bytesLeft,
sub_iter.get(),
kUnicodeUseFallbacksMask | kUnicodeLooseMappingsMask,
0, nsnull, nsnull, nsnull,
sizeof(stackBuffer),
&bytesRead,
&bytesWritten,
stackBuffer);
if (err == kTECUsedFallbacksStatus)
err = noErr;
else if (err == kTECOutputBufferFullStatus) {
bytesLeft -= bytesRead;
sub_iter.advance(bytesRead);
}
aOut.Append((PRUnichar *)stackBuffer, bytesWritten / sizeof(PRUnichar));
}
while (err == kTECOutputBufferFullStatus);
}
return (err == noErr) ? NS_OK : NS_ERROR_FAILURE;
}
void nsFSStringConversionMac::CleanUp()
{
if (sDecoderInfo) {
::DisposeTextToUnicodeInfo(&sDecoderInfo);
sDecoderInfo = nsnull;
}
if (sEncoderInfo) {
::DisposeUnicodeToTextInfo(&sEncoderInfo);
sEncoderInfo = nsnull;
}
}
TextEncoding nsFSStringConversionMac::GetSystemEncoding()
{
OSStatus err;
TextEncoding theEncoding;
err = ::UpgradeScriptInfoToTextEncoding(smSystemScript, kTextLanguageDontCare,
kTextRegionDontCare, NULL, &theEncoding);
if (err != noErr)
theEncoding = kTextEncodingMacRoman;
return theEncoding;
}
nsresult nsFSStringConversionMac::PrepareEncoder()
{
nsresult rv = NS_OK;
if (!sEncoderInfo) {
OSStatus err;
err = ::CreateUnicodeToTextInfoByEncoding(GetSystemEncoding(), &sEncoderInfo);
if (err)
rv = NS_ERROR_FAILURE;
}
return rv;
}
nsresult nsFSStringConversionMac::PrepareDecoder()
{
nsresult rv = NS_OK;
if (!sDecoderInfo) {
OSStatus err;
err = ::CreateTextToUnicodeInfoByEncoding(GetSystemEncoding(), &sDecoderInfo);
if (err)
rv = NS_ERROR_FAILURE;
}
return rv;
}
#pragma mark -
#pragma mark [static util funcs]
@ -768,7 +606,7 @@ static OSErr HFSPlusGetRawPath(const FSSpec& inSpec, nsAString& outStr)
err = GetParentFolderSpec(inSpec, parentDirSpec);
if (err == noErr) {
const char *startPtr = (const char*)&inSpec.name[1];
nsFSStringConversionMac::FSToUCS(Substring(startPtr, startPtr + PRUint32(inSpec.name[0])), outStr);
NS_CopyNativeToUnicode(Substring(startPtr, startPtr + PRUint32(inSpec.name[0])), outStr);
err = ::FSpMakeFSRef(&parentDirSpec, &nodeRef);
}
}
@ -1322,7 +1160,7 @@ nsLocalFile::InitWithPath(const nsAString &filePath)
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(filePath, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(filePath, fsStr)))
rv = InitWithNativePath(fsStr);
return rv;
@ -1550,7 +1388,7 @@ nsLocalFile::Append(const nsAString &node)
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(node, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(node, fsStr)))
rv = AppendNative(fsStr);
return rv;
@ -1582,7 +1420,7 @@ nsLocalFile::AppendRelativePath(const nsAString &relPath)
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(relPath, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(relPath, fsStr)))
rv = AppendRelativeNativePath(fsStr);
return rv;
@ -1633,7 +1471,7 @@ nsLocalFile::GetLeafName(nsAString &aLeafName)
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = GetNativeLeafName(fsStr)))
rv = nsFSStringConversionMac::FSToUCS(fsStr, aLeafName);
rv = NS_CopyNativeToUnicode(fsStr, aLeafName);
return rv;
}
@ -1672,7 +1510,7 @@ nsLocalFile::SetLeafName(const nsAString &aLeafName)
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(aLeafName, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(aLeafName, fsStr)))
rv = SetNativeLeafName(fsStr);
return rv;
@ -1694,7 +1532,7 @@ nsLocalFile::GetNativePath(nsACString &_retval)
if ((err = HFSPlusGetRawPath(mSpec, ucPathString)) != noErr)
return MacErrorMapper(err);
rv = nsFSStringConversionMac::UCSToFS(ucPathString, fsCharSetPathStr);
rv = NS_CopyUnicodeToNative(ucPathString, fsCharSetPathStr);
if (NS_FAILED(rv))
return rv;
}
@ -1757,7 +1595,7 @@ nsLocalFile::GetPath(nsAString &_retval)
nsAutoString ucAppendage;
if (mAppendedPath.First() != ':')
ucPathString.Append(PRUnichar(':'));
rv = nsFSStringConversionMac::FSToUCS(mAppendedPath, ucAppendage);
rv = NS_CopyNativeToUnicode(mAppendedPath, ucAppendage);
if (NS_FAILED(rv))
return rv;
ucPathString.Append(ucAppendage);
@ -1771,7 +1609,7 @@ nsLocalFile::GetPath(nsAString &_retval)
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = GetNativePath(fsStr))) {
rv = nsFSStringConversionMac::FSToUCS(fsStr, _retval);
rv = NS_CopyNativeToUnicode(fsStr, _retval);
}
}
return rv;
@ -1871,7 +1709,7 @@ nsLocalFile::CopyTo(nsIFile *newParentDir, const nsAString &newName)
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(newName, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(newName, fsStr)))
rv = CopyToNative(newParentDir, fsStr);
return rv;
}
@ -1890,7 +1728,7 @@ nsLocalFile::CopyToFollowingLinks(nsIFile *newParentDir, const nsAString &newNam
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(newName, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(newName, fsStr)))
rv = CopyToFollowingLinksNative(newParentDir, fsStr);
return rv;
}
@ -1909,7 +1747,7 @@ nsLocalFile::MoveTo(nsIFile *newParentDir, const nsAString &newName)
nsresult rv;
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = nsFSStringConversionMac::UCSToFS(newName, fsStr)))
if (NS_SUCCEEDED(rv = NS_CopyUnicodeToNative(newName, fsStr)))
rv = MoveToNative(newParentDir, fsStr);
return rv;
}
@ -2543,7 +2381,7 @@ nsLocalFile::GetTarget(nsAString &_retval)
nsCAutoString fsStr;
if (NS_SUCCEEDED(rv = GetNativeTarget(fsStr))) {
rv = nsFSStringConversionMac::FSToUCS(fsStr, _retval);
rv = NS_CopyNativeToUnicode(fsStr, _retval);
}
return rv;
}
@ -3641,7 +3479,7 @@ nsresult
NS_NewLocalFile(const nsAString &path, PRBool followLinks, nsILocalFile* *result)
{
nsCAutoString fsCharSetStr;
nsresult rv = nsFSStringConversionMac::UCSToFS(path, fsCharSetStr);
nsresult rv = NS_CopyUnicodeToNative(path, fsCharSetStr);
if (NS_FAILED(rv))
return rv;
return NS_NewNativeLocalFile(fsCharSetStr, followLinks, result);
@ -3674,5 +3512,4 @@ nsLocalFile::GlobalInit()
void
nsLocalFile::GlobalShutdown()
{
nsFSStringConversionMac::CleanUp();
}

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

@ -28,8 +28,7 @@
#include "nsMemory.h"
#include "nsLocalFileOS2.h"
#include <uconv.h>
#include "nsNativeCharsetUtils.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
@ -2155,92 +2154,14 @@ static int isleadbyte(int c)
return retval;
}
static UconvObject UnicodeConverter = NULL;
static nsresult NS_CreateUnicodeConverters()
{
ULONG ulLength;
ULONG ulCodePage;
DosQueryCp(sizeof(ULONG), &ulCodePage, &ulLength);
UniChar codepage[20];
int unirc = ::UniMapCpToUcsCp(ulCodePage, codepage, 20);
if (unirc == ULS_SUCCESS) {
unirc = ::UniCreateUconvObject(codepage, &UnicodeConverter);
if (unirc == ULS_SUCCESS) {
uconv_attribute_t attr;
::UniQueryUconvObject(UnicodeConverter, &attr, sizeof(uconv_attribute_t),
NULL, NULL, NULL);
attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
attr.subchar_len=1;
attr.subchar[0]='_';
::UniSetUconvObject(UnicodeConverter, &attr);
}
}
}
static void NS_DestroyUnicodeConverters()
{
::UniFreeUconvObject(UnicodeConverter);
}
static nsresult
UCS2toFS(const PRUnichar *aBuffer, char **aResult)
{
size_t inLength = UniStrlen(aBuffer)+1;
size_t outLength = CCHMAXPATH;
UniChar *inString = (UniChar*)aBuffer;
char *outString = (char*)nsMemory::Alloc(outLength);
size_t cSubs = 0;
char *tempString = outString;
int unirc = ::UniUconvFromUcs(UnicodeConverter, &inString, &inLength,
(void**)&tempString, &outLength, &cSubs);
NS_ASSERTION(unirc != UCONV_E2BIG, "Path too big");
if( unirc != ULS_SUCCESS )
return NS_ERROR_FAILURE;
*aResult = outString;
return NS_OK;
}
static nsresult
FStoUCS2(const char* aBuffer, PRUnichar **aResult)
{
size_t inLength = strlen(aBuffer)+1;
size_t outLength = CCHMAXPATH;
char *inString = (char*)aBuffer;
UniChar *outString = (UniChar*)nsMemory::Alloc(outLength);
size_t cSubs = 0;
UniChar *tempString = outString;
int unirc = ::UniUconvToUcs(UnicodeConverter, (void**)&inString, &inLength,
&tempString, &outLength, &cSubs);
NS_ASSERTION(unirc != UCONV_E2BIG, "Path too big");
if( unirc != ULS_SUCCESS )
return NS_ERROR_FAILURE;
*aResult = (PRUnichar*)outString;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::InitWithPath(const nsAString &filePath)
{
if (filePath.IsEmpty())
return InitWithNativePath(nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(filePath).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(filePath, tmp);
if (NS_SUCCEEDED(rv))
return InitWithNativePath(tmp);
@ -2254,8 +2175,8 @@ nsLocalFile::Append(const nsAString &node)
if (node.IsEmpty())
return NS_OK;
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(node).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(node, tmp);
if (NS_SUCCEEDED(rv))
return AppendNative(tmp);
@ -2269,8 +2190,8 @@ nsLocalFile::AppendRelativePath(const nsAString &node)
if (node.IsEmpty())
return NS_OK;
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(node).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(node, tmp);
if (NS_SUCCEEDED(rv))
return AppendRelativeNativePath(tmp);
@ -2284,12 +2205,8 @@ nsLocalFile::GetLeafName(nsAString &aLeafName)
nsCAutoString tmp;
nsresult rv = GetNativeLeafName(tmp);
if (NS_SUCCEEDED(rv)) {
nsXPIDLString ucsBuf;
rv = FStoUCS2(tmp.get(), getter_Copies(ucsBuf));
if (NS_SUCCEEDED(rv))
aLeafName = ucsBuf;
}
if (NS_SUCCEEDED(rv))
rv = NS_CopyNativeToUnicode(tmp, aLeafName);
return rv;
}
@ -2300,8 +2217,8 @@ nsLocalFile::SetLeafName(const nsAString &aLeafName)
if (aLeafName.IsEmpty())
return SetNativeLeafName(nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(aLeafName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(aLeafName, tmp);
if (NS_SUCCEEDED(rv))
return SetNativeLeafName(tmp);
@ -2312,11 +2229,7 @@ nsLocalFile::SetLeafName(const nsAString &aLeafName)
NS_IMETHODIMP
nsLocalFile::GetPath(nsAString &_retval)
{
nsXPIDLString ucsBuf;
nsresult rv = FStoUCS2(mWorkingPath.get(), getter_Copies(ucsBuf));
if (NS_SUCCEEDED(rv))
_retval = ucsBuf;
return rv;
return NS_CopyNativeToUnicode(mWorkingPath, _retval);
}
NS_IMETHODIMP
@ -2325,8 +2238,8 @@ nsLocalFile::CopyTo(nsIFile *newParentDir, const nsAString &newName)
if (newName.IsEmpty())
return CopyToNative(newParentDir, nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(newName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
if (NS_SUCCEEDED(rv))
return CopyToNative(newParentDir, tmp);
@ -2340,8 +2253,8 @@ nsLocalFile::CopyToFollowingLinks(nsIFile *newParentDir, const nsAString &newNam
if (newName.IsEmpty())
return CopyToFollowingLinksNative(newParentDir, nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(newName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
if (NS_SUCCEEDED(rv))
return CopyToFollowingLinksNative(newParentDir, tmp);
@ -2355,8 +2268,8 @@ nsLocalFile::MoveTo(nsIFile *newParentDir, const nsAString &newName)
if (newName.IsEmpty())
return MoveToNative(newParentDir, nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(newName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
if (NS_SUCCEEDED(rv))
return MoveToNative(newParentDir, tmp);
@ -2370,12 +2283,8 @@ nsLocalFile::GetTarget(nsAString &_retval)
nsCAutoString tmp;
nsresult rv = GetNativeTarget(tmp);
if (NS_SUCCEEDED(rv)) {
nsXPIDLString ucsBuf;
rv = FStoUCS2(tmp.get(), getter_Copies(ucsBuf));
if (NS_SUCCEEDED(rv))
_retval = ucsBuf;
}
if (NS_SUCCEEDED(rv))
rv = NS_CopyNativeToUnicode(tmp, _retval);
return rv;
}
@ -2386,8 +2295,8 @@ NS_NewLocalFile(const nsAString &path, PRBool followLinks, nsILocalFile* *result
if (path.IsEmpty())
return NS_NewNativeLocalFile(nsCString(), followLinks, result);
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(path).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(path, tmp);
if (NS_SUCCEEDED(rv))
return NS_NewNativeLocalFile(tmp, followLinks, result);
@ -2402,11 +2311,9 @@ NS_NewLocalFile(const nsAString &path, PRBool followLinks, nsILocalFile* *result
void
nsLocalFile::GlobalInit()
{
NS_CreateUnicodeConverters();
}
void
nsLocalFile::GlobalShutdown()
{
NS_DestroyUnicodeConverters();
}

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

@ -27,6 +27,7 @@
#include "nsMemory.h"
#include "nsLocalFileWin.h"
#include "nsNativeCharsetUtils.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
@ -2167,67 +2168,11 @@ NS_NewNativeLocalFile(const nsACString &path, PRBool followLinks, nsILocalFile*
// UCS2 interface
//-----------------------------------------------------------------------------
static nsresult UCS2toFS(const PRUnichar *aBuffer, char **aResult)
{
NS_ENSURE_ARG_POINTER(aBuffer);
// includes null termination
size_t chars = ::WideCharToMultiByte(CP_ACP, 0,
aBuffer, -1,
NULL, 0, NULL, NULL);
if (chars == 0)
return NS_ERROR_FAILURE;
*aResult = (char*)nsMemory::Alloc(chars * sizeof(char));
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
// default "defaultChar" is '?', which is an illegal character on windows file system.
// That will cause file uncreatable. Change it to '_'
const char defaultChar = '_';
chars = ::WideCharToMultiByte(CP_ACP, 0,
aBuffer, -1,
*aResult, chars, &defaultChar, NULL);
if (chars == 0)
{
nsMemory::Free(*aResult);
*aResult = nsnull;
return NS_ERROR_FAILURE;
}
return NS_OK;
}
static nsresult FStoUCS2(const char* aBuffer, PRUnichar **aResult)
{
NS_ENSURE_ARG_POINTER(aBuffer);
// includes null termination
size_t chars = ::MultiByteToWideChar(CP_ACP, 0, aBuffer, -1, NULL, 0);
if (chars == 0)
return NS_ERROR_FAILURE;
*aResult = (PRUnichar*)nsMemory::Alloc(chars * sizeof(PRUnichar));
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
chars = ::MultiByteToWideChar(CP_ACP, 0,
aBuffer, -1,
*aResult, chars);
if (chars == 0) {
nsMemory::Free(*aResult);
*aResult = nsnull;
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
nsLocalFile::InitWithPath(const nsAString &filePath)
{
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(filePath).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(filePath, tmp);
if (NS_SUCCEEDED(rv))
return InitWithNativePath(tmp);
@ -2237,8 +2182,8 @@ nsLocalFile::InitWithPath(const nsAString &filePath)
nsresult
nsLocalFile::Append(const nsAString &node)
{
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(node).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(node, tmp);
if (NS_SUCCEEDED(rv))
return AppendNative(tmp);
@ -2248,8 +2193,8 @@ nsLocalFile::Append(const nsAString &node)
nsresult
nsLocalFile::AppendRelativePath(const nsAString &node)
{
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(node).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(node, tmp);
if (NS_SUCCEEDED(rv))
return AppendRelativeNativePath(tmp);
return rv;
@ -2260,12 +2205,8 @@ nsLocalFile::GetLeafName(nsAString &aLeafName)
{
nsCAutoString tmp;
nsresult rv = GetNativeLeafName(tmp);
if (NS_SUCCEEDED(rv)) {
nsXPIDLString ucsBuf;
rv = FStoUCS2(tmp.get(), getter_Copies(ucsBuf));
if (NS_SUCCEEDED(rv))
aLeafName = ucsBuf;
}
if (NS_SUCCEEDED(rv))
rv = NS_CopyNativeToUnicode(tmp, aLeafName);
return rv;
}
@ -2273,8 +2214,8 @@ nsLocalFile::GetLeafName(nsAString &aLeafName)
nsresult
nsLocalFile::SetLeafName(const nsAString &aLeafName)
{
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(aLeafName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(aLeafName, tmp);
if (NS_SUCCEEDED(rv))
return SetNativeLeafName(tmp);
@ -2284,11 +2225,7 @@ nsLocalFile::SetLeafName(const nsAString &aLeafName)
nsresult
nsLocalFile::GetPath(nsAString &_retval)
{
nsXPIDLString ucsBuf;
nsresult rv = FStoUCS2(mWorkingPath.get(), getter_Copies(ucsBuf));
if (NS_SUCCEEDED(rv))
_retval = ucsBuf;
return rv;
return NS_CopyNativeToUnicode(mWorkingPath, _retval);
}
nsresult
@ -2297,8 +2234,8 @@ nsLocalFile::CopyTo(nsIFile *newParentDir, const nsAString &newName)
if (newName.IsEmpty())
return CopyToNative(newParentDir, nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(newName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
if (NS_SUCCEEDED(rv))
return CopyToNative(newParentDir, tmp);
@ -2311,8 +2248,8 @@ nsLocalFile::CopyToFollowingLinks(nsIFile *newParentDir, const nsAString &newNam
if (newName.IsEmpty())
return CopyToFollowingLinksNative(newParentDir, nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(newName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
if (NS_SUCCEEDED(rv))
return CopyToFollowingLinksNative(newParentDir, tmp);
@ -2325,8 +2262,8 @@ nsLocalFile::MoveTo(nsIFile *newParentDir, const nsAString &newName)
if (newName.IsEmpty())
return MoveToNative(newParentDir, nsCString());
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(newName).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
if (NS_SUCCEEDED(rv))
return MoveToNative(newParentDir, tmp);
@ -2338,12 +2275,8 @@ nsLocalFile::GetTarget(nsAString &_retval)
{
nsCAutoString tmp;
nsresult rv = GetNativeTarget(tmp);
if (NS_SUCCEEDED(rv)) {
nsXPIDLString ucsBuf;
rv = FStoUCS2(tmp.get(), getter_Copies(ucsBuf));
if (NS_SUCCEEDED(rv))
_retval = ucsBuf;
}
if (NS_SUCCEEDED(rv))
rv = NS_CopyNativeToUnicode(tmp, _retval);
return rv;
}
@ -2351,8 +2284,8 @@ nsLocalFile::GetTarget(nsAString &_retval)
nsresult
NS_NewLocalFile(const nsAString &path, PRBool followLinks, nsILocalFile* *result)
{
nsXPIDLCString tmp;
nsresult rv = UCS2toFS(PromiseFlatString(path).get(), getter_Copies(tmp));
nsCAutoString tmp;
nsresult rv = NS_CopyUnicodeToNative(path, tmp);
if (NS_SUCCEEDED(rv))
return NS_NewNativeLocalFile(tmp, followLinks, result);

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

@ -39,6 +39,9 @@
*
* ***** END LICENSE BLOCK ***** */
//-----------------------------------------------------------------------------
// XP_UNIX
//-----------------------------------------------------------------------------
#if defined(XP_UNIX)
#include <stdlib.h> // mbtowc, wctomb
@ -789,6 +792,9 @@ NS_ShutdownNativeCharsetUtils()
nsNativeCharsetConverter::GlobalShutdown();
}
//-----------------------------------------------------------------------------
// XP_BEOS
//-----------------------------------------------------------------------------
#elif defined(XP_BEOS)
#include "nsAString.h"
@ -818,23 +824,455 @@ NS_ShutdownNativeCharsetUtils()
{
}
#else // non XP_UNIX implementations go here...
//-----------------------------------------------------------------------------
// XP_WIN
//-----------------------------------------------------------------------------
#elif defined(XP_WIN)
#include "nsDebug.h"
#include <windows.h>
#include "nsAString.h"
NS_COM nsresult
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
{
NS_NOTREACHED("NS_CopyNativeToUnicode");
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv;
PRUint32 inputLen = input.Length();
output.Truncate();
nsACString::const_iterator iter, end;
input.BeginReading(iter);
input.EndReading(end);
// determine length of result
PRUint32 size, resultLen = 0;
for (; iter != end; iter.advance(size)) {
const char *buf = iter.get();
size = iter.size_forward();
int n = ::MultiByteToWideChar(CP_ACP, 0, buf, size, NULL, 0);
if (n > 0)
resultLen += n;
else
break;
}
output.SetLength(resultLen); // allocate sufficient space
nsAString::iterator out_iter;
output.BeginWriting(out_iter);
PRUnichar *result = out_iter.get();
input.BeginReading(iter);
for (; iter != end; iter.advance(size)) {
const char *buf = iter.get();
size = iter.size_forward();
int n = ::MultiByteToWideChar(CP_ACP, 0, buf, size, result, resultLen);
if (n > 0) {
result += n;
resultLen -= n;
}
else
break;
}
return NS_OK;
}
NS_COM nsresult
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
{
NS_NOTREACHED("NS_CopyUnicodeToNative");
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv;
PRUint32 inputLen = input.Length();
output.Truncate();
nsAString::const_iterator iter, end;
input.BeginReading(iter);
input.EndReading(end);
// determine length of result
PRUint32 size, resultLen = 0;
for (; iter != end; iter.advance(size)) {
const PRUnichar *buf = iter.get();
size = iter.size_forward();
int n = ::WideCharToMultiByte(CP_ACP, 0, buf, size, NULL, 0,
NULL, NULL);
if (n > 0)
resultLen += n;
else
break;
}
output.SetLength(resultLen); // allocate sufficient space
nsACString::iterator out_iter;
output.BeginWriting(out_iter);
// default "defaultChar" is '?', which is an illegal character on windows
// file system. That will cause file uncreatable. Change it to '_'
const char defaultChar = '_';
char *result = out_iter.get();
input.BeginReading(iter);
for (; iter != end; iter.advance(size)) {
const PRUnichar *buf = iter.get();
size = iter.size_forward();
int n = ::WideCharToMultiByte(CP_ACP, 0, buf, size, result, resultLen,
&defaultChar, NULL);
if (n > 0) {
result += n;
resultLen -= n;
}
else
break;
}
return NS_OK;
}
void
NS_StartupNativeCharsetUtils()
{
}
void
NS_ShutdownNativeCharsetUtils()
{
}
//-----------------------------------------------------------------------------
// XP_OS2
//-----------------------------------------------------------------------------
#elif defined(XP_OS2)
#include <uconv.h>
#include "nsPromiseFlatString.h"
static UconvObject UnicodeConverter = NULL;
NS_COM nsresult
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
{
nsresult rv;
// XXX not the most efficient algorithm here
const nsPromiseFlatCString &flat = PromiseFlatCString(input);
char *inputStr = (char*)flat.get();
size_t inputLen = flat.Length() + 1; // include null char
// assume worst case allocation
size_t resultLen = CCHMAXPATH;
output.Truncate();
output.SetLength(resultLen);
nsAString::iterator out_iter;
output.BeginWriting(out_iter);
UniChar *result = (UniChar*)out_iter.get();
size_t cSubs = 0;
size_t resultLeft = resultLen;
int unirc = ::UniUconvToUcs(UnicodeConverter, &inputStr, &inputLen,
(void**)&result, &resultLeft, &cSubs);
NS_ASSERTION(unirc != UCONV_E2BIG, "Path too big");
if (unirc != ULS_SUCCESS) {
output.Truncate();
return NS_ERROR_FAILURE;
}
// need to update string length to reflect how many bytes were actually
// written. note: conversion wrote null byte.
output.SetLength(resultLen - (resultLeft + 1));
return NS_OK;
}
NS_COM nsresult
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
{
nsresult rv;
// XXX not the most efficient algorithm here
const nsPromiseFlatString &flat = PromiseFlatString(input);
UniChar *inputStr = (UniChar*)flat.get();
size_t inputLen = flat.Length() + 1; // include null char
// assume worst case allocation
size_t resultLen = CCHMAXPATH;
output.Truncate();
output.SetLength(resultLen);
nsACString::iterator out_iter;
output.BeginWriting(out_iter);
char *result = out_iter.get();
size_t cSubs = 0;
size_t resultLeft = resultLen;
int unirc = ::UniUconvFromUcs(UnicodeConverter, &inputStr, &inputLen,
(void**)&result, &resultLeft, &cSubs);
NS_ASSERTION(unirc != UCONV_E2BIG, "Path too big");
if (unirc != ULS_SUCCESS) {
output.Truncate();
return NS_ERROR_FAILURE;
}
// need to update string length to reflect how many bytes were actually
// written. note: conversion wrote null byte.
output.SetLength(resultLen - (resultLeft + 1));
return NS_OK;
}
void
NS_StartupNativeCharsetUtils()
{
ULONG ulLength;
ULONG ulCodePage;
DosQueryCp(sizeof(ULONG), &ulCodePage, &ulLength);
UniChar codepage[20];
int unirc = ::UniMapCpToUcsCp(ulCodePage, codepage, 20);
if (unirc == ULS_SUCCESS) {
unirc = ::UniCreateUconvObject(codepage, &UnicodeConverter);
if (unirc == ULS_SUCCESS) {
uconv_attribute_t attr;
::UniQueryUconvObject(UnicodeConverter, &attr, sizeof(uconv_attribute_t),
NULL, NULL, NULL);
attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
attr.subchar_len=1;
attr.subchar[0]='_';
::UniSetUconvObject(UnicodeConverter, &attr);
}
}
}
void
NS_ShutdownNativeCharsetUtils()
{
::UniFreeUconvObject(UnicodeConverter);
}
//-----------------------------------------------------------------------------
// XP_MAC
//-----------------------------------------------------------------------------
#elif defined(XP_MAC)
#include <UnicodeConverter.h>
#include <TextCommon.h>
#include <Script.h>
#include <MacErrors.h>
#include "nsAString.h"
class nsFSStringConversionMac {
public:
static nsresult UCSToFS(const nsAString& aIn, nsACString& aOut);
static nsresult FSToUCS(const nsACString& ain, nsAString& aOut);
static void CleanUp();
private:
static TextEncoding GetSystemEncoding();
static nsresult PrepareEncoder();
static nsresult PrepareDecoder();
static UnicodeToTextInfo sEncoderInfo;
static TextToUnicodeInfo sDecoderInfo;
};
UnicodeToTextInfo nsFSStringConversionMac::sEncoderInfo = nsnull;
TextToUnicodeInfo nsFSStringConversionMac::sDecoderInfo = nsnull;
nsresult nsFSStringConversionMac::UCSToFS(const nsAString& aIn, nsACString& aOut)
{
nsresult rv = PrepareEncoder();
if (NS_FAILED(rv)) return rv;
OSStatus err = noErr;
char stackBuffer[512];
aOut.Truncate(0);
nsReadingIterator<PRUnichar> done_reading;
aIn.EndReading(done_reading);
// for each chunk of |aIn|...
PRUint32 fragmentLength = 0;
nsReadingIterator<PRUnichar> iter;
for (aIn.BeginReading(iter); iter != done_reading && err == noErr; iter.advance(PRInt32(fragmentLength)))
{
fragmentLength = PRUint32(iter.size_forward());
UInt32 bytesLeft = fragmentLength * sizeof(UniChar);
nsReadingIterator<PRUnichar> sub_iter(iter);
do {
UInt32 bytesRead = 0, bytesWritten = 0;
err = ::ConvertFromUnicodeToText(sEncoderInfo,
bytesLeft,
(const UniChar*)sub_iter.get(),
kUnicodeUseFallbacksMask | kUnicodeLooseMappingsMask,
0, nsnull, nsnull, nsnull,
sizeof(stackBuffer),
&bytesRead,
&bytesWritten,
stackBuffer);
if (err == kTECUsedFallbacksStatus)
err = noErr;
else if (err == kTECOutputBufferFullStatus) {
bytesLeft -= bytesRead;
sub_iter.advance(bytesRead / sizeof(UniChar));
}
aOut.Append(stackBuffer, bytesWritten);
}
while (err == kTECOutputBufferFullStatus);
}
return (err == noErr) ? NS_OK : NS_ERROR_FAILURE;
}
nsresult nsFSStringConversionMac::FSToUCS(const nsACString& aIn, nsAString& aOut)
{
nsresult rv = PrepareDecoder();
if (NS_FAILED(rv)) return rv;
OSStatus err = noErr;
UniChar stackBuffer[512];
aOut.Truncate(0);
nsReadingIterator<char> done_reading;
aIn.EndReading(done_reading);
// for each chunk of |aIn|...
PRUint32 fragmentLength = 0;
nsReadingIterator<char> iter;
for (aIn.BeginReading(iter); iter != done_reading && err == noErr; iter.advance(PRInt32(fragmentLength)))
{
fragmentLength = PRUint32(iter.size_forward());
UInt32 bytesLeft = fragmentLength;
nsReadingIterator<char> sub_iter(iter);
do {
UInt32 bytesRead = 0, bytesWritten = 0;
err = ::ConvertFromTextToUnicode(sDecoderInfo,
bytesLeft,
sub_iter.get(),
kUnicodeUseFallbacksMask | kUnicodeLooseMappingsMask,
0, nsnull, nsnull, nsnull,
sizeof(stackBuffer),
&bytesRead,
&bytesWritten,
stackBuffer);
if (err == kTECUsedFallbacksStatus)
err = noErr;
else if (err == kTECOutputBufferFullStatus) {
bytesLeft -= bytesRead;
sub_iter.advance(bytesRead);
}
aOut.Append((PRUnichar *)stackBuffer, bytesWritten / sizeof(PRUnichar));
}
while (err == kTECOutputBufferFullStatus);
}
return (err == noErr) ? NS_OK : NS_ERROR_FAILURE;
}
void nsFSStringConversionMac::CleanUp()
{
if (sDecoderInfo) {
::DisposeTextToUnicodeInfo(&sDecoderInfo);
sDecoderInfo = nsnull;
}
if (sEncoderInfo) {
::DisposeUnicodeToTextInfo(&sEncoderInfo);
sEncoderInfo = nsnull;
}
}
TextEncoding nsFSStringConversionMac::GetSystemEncoding()
{
OSStatus err;
TextEncoding theEncoding;
err = ::UpgradeScriptInfoToTextEncoding(smSystemScript, kTextLanguageDontCare,
kTextRegionDontCare, NULL, &theEncoding);
if (err != noErr)
theEncoding = kTextEncodingMacRoman;
return theEncoding;
}
nsresult nsFSStringConversionMac::PrepareEncoder()
{
nsresult rv = NS_OK;
if (!sEncoderInfo) {
OSStatus err;
err = ::CreateUnicodeToTextInfoByEncoding(GetSystemEncoding(), &sEncoderInfo);
if (err)
rv = NS_ERROR_FAILURE;
}
return rv;
}
nsresult nsFSStringConversionMac::PrepareDecoder()
{
nsresult rv = NS_OK;
if (!sDecoderInfo) {
OSStatus err;
err = ::CreateTextToUnicodeInfoByEncoding(GetSystemEncoding(), &sDecoderInfo);
if (err)
rv = NS_ERROR_FAILURE;
}
return rv;
}
NS_COM nsresult
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
{
return nsFSStringConversionMac::FSToUCS(input, output);
}
NS_COM nsresult
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
{
return nsFSStringConversionMac::UCSToFS(input, output);
}
void
NS_StartupNativeCharsetUtils()
{
}
void
NS_ShutdownNativeCharsetUtils()
{
nsFSStringConversionMac::CleanUp();
}
//-----------------------------------------------------------------------------
// default : truncate/zeropad
//-----------------------------------------------------------------------------
#else
#include "nsReadableUtils.h"
NS_COM nsresult
NS_CopyNativeToUnicode(const nsACString &input, nsAString &output)
{
CopyASCIItoUCS2(input, output);
return NS_OK;
}
NS_COM nsresult
NS_CopyUnicodeToNative(const nsAString &input, nsACString &output)
{
CopyUCS2toASCII(input, output);
return NS_OK;
}
void

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

@ -45,16 +45,12 @@
* *
* *** THESE ARE NOT GENERAL PURPOSE CONVERTERS *** *
* *
* NS_CopyNativeToUnicode / NS_CopyUnicodeToNative should only be used *
* by XPCOM for converting *FILENAMES* between native and unicode. They *
* are not designed or tested for general encoding converter use. *
* NS_CopyNativeToUnicode / NS_CopyUnicodeToNative should only be used *
* for converting *FILENAMES* between native and unicode. They are not *
* designed or tested for general encoding converter use. *
* *
\*****************************************************************************/
// XXX XXX XXX XXX only implemented for XP_UNIX XXX XXX XXX XXX
/**
* thread-safe conversion routines that do not depend on uconv libraries.
*/

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

@ -1583,6 +1583,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsNativeCharsetUtils.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDirectoryService.cpp</PATH>
@ -2295,6 +2302,11 @@
<PATH>nsLocalFileMac.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsNativeCharsetUtils.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDirectoryService.cpp</PATH>
@ -4059,6 +4071,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsNativeCharsetUtils.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDirectoryService.cpp</PATH>
@ -4776,6 +4795,11 @@
<PATH>nsLocalFileMac.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsNativeCharsetUtils.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDirectoryService.cpp</PATH>
@ -5502,6 +5526,12 @@
<PATH>nsLocalFileMac.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>xpcom.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsNativeCharsetUtils.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>xpcom.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>