fix for bug 110531, r=dougt, jag, sr=darin - moving ConverterInputStream into uconv, and changing the one in XPCOM into an UTF8-only converter

This commit is contained in:
alecf@netscape.com
2001-12-04 01:10:43 +00:00
parent bdeed4f9b9
commit f49275bd79
12 changed files with 146 additions and 548 deletions

View File

@@ -1244,7 +1244,7 @@ CSSLoaderImpl::LoadSheet(URLKey& aKey, SheetLoadData* aData)
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result)) {
// Translate the input using the argument character set id into unicode // Translate the input using the argument character set id into unicode
nsIUnicharInputStream* uin; nsIUnicharInputStream* uin;
result = NS_NewConverterStream(&uin, nsnull, in); result = NS_NewUTF8ConverterStream(&uin, in, 0);
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result)) {
mLoadingSheets.Put(&aKey, aData); mLoadingSheets.Put(&aKey, aData);
PRBool completed; PRBool completed;

View File

@@ -51,7 +51,7 @@
#include "prlog.h" #include "prlog.h"
#include "prmem.h" #include "prmem.h"
#include "nsIUnicharInputStream.h" #include "nsIConverterInputStream.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@@ -822,9 +822,9 @@ IsLoadableDTD(nsCOMPtr<nsIURI>* aDTD)
res = dtdURL->GetFileName(getter_Copies(fileName)); res = dtdURL->GetFileName(getter_Copies(fileName));
if (NS_SUCCEEDED(res) && fileName) { if (NS_SUCCEEDED(res) && fileName) {
nsSpecialSystemDirectory dtdPath(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); nsSpecialSystemDirectory dtdPath(nsSpecialSystemDirectory::OS_CurrentProcessDirectory);
nsString path; path.AssignWithConversion(kDTDDirectory); nsCAutoString path(kDTDDirectory);
path.AppendWithConversion(fileName.get()); path.Append(fileName);
dtdPath += path; dtdPath += path.get();
if (dtdPath.Exists()) { if (dtdPath.Exists()) {
// The DTD was found in the local DTD directory. // The DTD was found in the local DTD directory.
// Set aDTD to a file: url pointing to the local DTD // Set aDTD to a file: url pointing to the local DTD
@@ -878,14 +878,10 @@ nsresult nsExpatTokenizer::LoadStream(nsIInputStream* in,
// read it // read it
PRUint32 aCount = 1024, PRUint32 aCount = 1024,
bufsize = aCount*sizeof(PRUnichar); bufsize = aCount*sizeof(PRUnichar);
nsIUnicharInputStream *uniIn = nsnull; nsCOMPtr<nsIUnicharInputStream> uniIn;
nsAutoString utf8; utf8.AssignWithConversion("UTF-8");
nsresult res = NS_NewConverterStream(&uniIn, nsresult res = NS_NewUTF8ConverterStream(getter_AddRefs(uniIn),
nsnull, in, aCount);
in,
aCount,
&utf8);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
PRUint32 aReadCount = 0; PRUint32 aReadCount = 0;
@@ -909,7 +905,6 @@ nsresult nsExpatTokenizer::LoadStream(nsIInputStream* in,
uniBuf = (PRUnichar *) PR_Malloc(retLen*sizeof(PRUnichar)); uniBuf = (PRUnichar *) PR_Malloc(retLen*sizeof(PRUnichar));
nsCRT::memcpy(uniBuf, aBuf, sizeof(PRUnichar) * retLen); nsCRT::memcpy(uniBuf, aBuf, sizeof(PRUnichar) * retLen);
PR_FREEIF(aBuf); PR_FREEIF(aBuf);
NS_RELEASE(uniIn);
return res; return res;
} }

View File

@@ -1,217 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include "nsICSSParser.h"
#include "nsICSSStyleSheet.h"
#include "nsIStyleRule.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIIOService.h"
#include "nsIURL.h"
#include "nsIInputStream.h"
#include "nsIUnicharInputStream.h"
#include "nsString.h"
// XXX begin bad code
#include "plevent.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsLayoutCID.h"
#include "nsCOMPtr.h"
#ifdef XP_PC
#define NETLIB_DLL "netlib.dll"
#define XPCOM_DLL "xpcom32.dll"
#define LAYOUT_DLL "gkhtml.dll"
#else
#ifdef XP_MAC
#include "nsMacRepository.h"
#else
#define NETLIB_DLL "libnecko"MOZ_DLL_SUFFIX
#define XPCOM_DLL "libxpcom"MOZ_DLL_SUFFIX
#define LAYOUT_DLL "libgklayout"MOZ_DLL_SUFFIX
#endif
#endif
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
// XXX end bad code
static void Usage(void)
{
printf("usage: TestCSSParser [-v] [-s string | url1 ...]\n");
}
int main(int argc, char** argv)
{
nsComponentManager::RegisterComponent(kEventQueueServiceCID, NULL, NULL, XPCOM_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kIOServiceCID, NULL, NULL, NETLIB_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kCSSParserCID, NULL, NULL, LAYOUT_DLL, PR_FALSE, PR_FALSE);
nsresult rv;
PRBool verbose = PR_FALSE;
nsString* string = nsnull;
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (strcmp(argv[i], "-v") == 0) {
verbose = PR_TRUE;
}
else if (strcmp(argv[i], "-s") == 0) {
if ((nsnull != string) || (i == argc - 1)) {
Usage();
return -1;
}
string = new nsString;
string->AssignWithConversion(argv[++i]);
}
else {
Usage();
return -1;
}
}
else
break;
}
// Create the Event Queue for this thread...
nsIEventQueueService* pEventQService = nsnull;
rv = nsServiceManager::GetService(kEventQueueServiceCID,
NS_GET_IID(nsIEventQueueService),
(nsISupports **)&pEventQService);
if (NS_SUCCEEDED(rv)) {
// XXX: What if this fails?
rv = pEventQService->CreateThreadEventQueue();
}
// Create parser
nsCOMPtr<nsICSSParser> css;
rv = nsComponentManager::CreateInstance(kCSSParserCID,
nsnull,
NS_GET_IID(nsICSSParser),
getter_AddRefs(css));
if (NS_FAILED(rv)) {
printf("can't create css parser: %d\n", rv);
return -1;
}
PRUint32 infoMask;
css->GetInfoMask(infoMask);
printf("CSS parser supports %x\n", infoMask);
if (nsnull != string) {
nsIStyleRule* rule;
rv = css->ParseStyleAttribute(*string, nsnull, &rule);
if (NS_OK == rv) {
if (verbose && (nsnull != rule)) {
rule->List();
}
}
else {
printf("ParseStyleAttribute failed: rv=%d\n", rv);
}
}
else {
for (; i < argc; i++) {
char* urlName = argv[i];
// Create url object
nsIURI* url;
nsCOMPtr<nsIIOService> service(do_GetService(kIOServiceCID, &rv));
if (NS_FAILED(rv)) return -1;
nsIURI *uri = nsnull;
rv = service->NewURI(urlName, nsnull, &uri);
if (NS_FAILED(rv)) return -1;
rv = uri->QueryInterface(NS_GET_IID(nsIURI), (void**)&url);
NS_RELEASE(uri);
if (NS_OK != rv) {
printf("invalid URL: '%s'\n", urlName);
return -1;
}
// Get an input stream from the url
nsIInputStream* in;
rv = NS_OpenURI(&in, url);
if (rv != NS_OK) {
printf("open of url('%s') failed: error=%x\n", urlName, rv);
continue;
}
// Translate the input using the argument character set id into unicode
nsIUnicharInputStream* uin;
rv = NS_NewConverterStream(&uin, nsnull, in);
if (NS_OK != rv) {
printf("can't create converter input stream: %d\n", rv);
return -1;
}
// Parse the input and produce a style set
nsICSSStyleSheet* sheet;
rv = css->Parse(uin, url, sheet);
if (NS_OK == rv) {
if (verbose) {
sheet->List();
}
}
else {
printf("parse failed: %d\n", rv);
}
url->Release();
in->Release();
uin->Release();
sheet->Release();
}
}
/* Release the event queue for the thread */
if (nsnull != pEventQService) {
pEventQService->DestroyThreadEventQueue();
nsServiceManager::ReleaseService(kEventQueueServiceCID, pEventQService);
}
return 0;
}

View File

@@ -1,146 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include "nsCSSScanner.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIIOService.h"
#include "nsIURL.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
#include "nsIInputStream.h"
#include "nsIUnicharInputStream.h"
#include "nsString.h"
int main(int argc, char** argv)
{
if (2 != argc) {
printf("usage: TestCSSScanner url\n");
return -1;
}
// Create url object
char* urlName = argv[1];
nsIURI* url;
nsresult rv;
nsCOMPtr<nsIIOService> service(do_GetService(kIOServiceCID, &rv));
if (NS_FAILED(rv)) return -1;
nsIURI *uri = nsnull;
rv = service->NewURI(urlName, nsnull, &uri);
if (NS_FAILED(rv)) return -1;
rv = uri->QueryInterface(NS_GET_IID(nsIURI), (void**)&url);
NS_RELEASE(uri);
if (NS_OK != rv) {
printf("invalid URL: '%s'\n", urlName);
return -1;
}
// Get an input stream from the url
nsIInputStream* in;
rv = NS_OpenURI(&in, url);
if (rv != NS_OK) {
printf("open of url('%s') failed: error=%x\n", urlName, rv);
return -1;
}
// Translate the input using the argument character set id into unicode
nsIUnicharInputStream* uin;
rv = NS_NewConverterStream(&uin, nsnull, in);
if (NS_OK != rv) {
printf("can't create converter input stream: %d\n", rv);
return -1;
}
// Create scanner and set it up to process the input file
nsCSSScanner* css = new nsCSSScanner();
if (nsnull == css) {
printf("Out of memory allocating nsCSSScanner\n");
return -1;
}
css->Init(uin, url);
// Scan the file and dump out the tokens
nsCSSToken tok;
PRInt32 ec;
for (;;) {
char buf[20];
if (!css->Next(ec, tok)) {
break;
}
printf("%02d: ", tok.mType);
switch (tok.mType) {
case eCSSToken_Ident:
case eCSSToken_AtKeyword:
case eCSSToken_String:
case eCSSToken_Function:
case eCSSToken_WhiteSpace:
case eCSSToken_URL:
case eCSSToken_InvalidURL:
case eCSSToken_ID:
case eCSSToken_HTMLComment:
fputs(NS_LossyConvertUCS2toASCII(tok.mIdent).get(), stdout);
fputs("\n", stdout);
break;
case eCSSToken_Number:
printf("%g\n", tok.mNumber);
break;
case eCSSToken_Percentage:
printf("%g%%\n", tok.mNumber * 100.0f);
break;
case eCSSToken_Dimension:
tok.mIdent.ToCString(buf, sizeof(buf));
printf("%g%s\n", tok.mNumber, buf);
break;
case eCSSToken_Symbol:
printf("%c (%x)\n", tok.mSymbol, tok.mSymbol);
break;
}
}
delete css;
uin->Release();
in->Release();
url->Release();
return 0;
}

View File

@@ -1244,7 +1244,7 @@ CSSLoaderImpl::LoadSheet(URLKey& aKey, SheetLoadData* aData)
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result)) {
// Translate the input using the argument character set id into unicode // Translate the input using the argument character set id into unicode
nsIUnicharInputStream* uin; nsIUnicharInputStream* uin;
result = NS_NewConverterStream(&uin, nsnull, in); result = NS_NewUTF8ConverterStream(&uin, in, 0);
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result)) {
mLoadingSheets.Put(&aKey, aData); mLoadingSheets.Put(&aKey, aData);
PRBool completed; PRBool completed;

View File

@@ -51,7 +51,7 @@
#include "prlog.h" #include "prlog.h"
#include "prmem.h" #include "prmem.h"
#include "nsIUnicharInputStream.h" #include "nsIConverterInputStream.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@@ -822,9 +822,9 @@ IsLoadableDTD(nsCOMPtr<nsIURI>* aDTD)
res = dtdURL->GetFileName(getter_Copies(fileName)); res = dtdURL->GetFileName(getter_Copies(fileName));
if (NS_SUCCEEDED(res) && fileName) { if (NS_SUCCEEDED(res) && fileName) {
nsSpecialSystemDirectory dtdPath(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); nsSpecialSystemDirectory dtdPath(nsSpecialSystemDirectory::OS_CurrentProcessDirectory);
nsString path; path.AssignWithConversion(kDTDDirectory); nsCAutoString path(kDTDDirectory);
path.AppendWithConversion(fileName.get()); path.Append(fileName);
dtdPath += path; dtdPath += path.get();
if (dtdPath.Exists()) { if (dtdPath.Exists()) {
// The DTD was found in the local DTD directory. // The DTD was found in the local DTD directory.
// Set aDTD to a file: url pointing to the local DTD // Set aDTD to a file: url pointing to the local DTD
@@ -878,14 +878,10 @@ nsresult nsExpatTokenizer::LoadStream(nsIInputStream* in,
// read it // read it
PRUint32 aCount = 1024, PRUint32 aCount = 1024,
bufsize = aCount*sizeof(PRUnichar); bufsize = aCount*sizeof(PRUnichar);
nsIUnicharInputStream *uniIn = nsnull; nsCOMPtr<nsIUnicharInputStream> uniIn;
nsAutoString utf8; utf8.AssignWithConversion("UTF-8");
nsresult res = NS_NewConverterStream(&uniIn, nsresult res = NS_NewUTF8ConverterStream(getter_AddRefs(uniIn),
nsnull, in, aCount);
in,
aCount,
&utf8);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
PRUint32 aReadCount = 0; PRUint32 aReadCount = 0;
@@ -909,7 +905,6 @@ nsresult nsExpatTokenizer::LoadStream(nsIInputStream* in,
uniBuf = (PRUnichar *) PR_Malloc(retLen*sizeof(PRUnichar)); uniBuf = (PRUnichar *) PR_Malloc(retLen*sizeof(PRUnichar));
nsCRT::memcpy(uniBuf, aBuf, sizeof(PRUnichar) * retLen); nsCRT::memcpy(uniBuf, aBuf, sizeof(PRUnichar) * retLen);
PR_FREEIF(aBuf); PR_FREEIF(aBuf);
NS_RELEASE(uniIn);
return res; return res;
} }

View File

@@ -53,12 +53,8 @@
[scriptable, uuid(283EE646-1AEF-11D4-98B3-00C04fA0CE9A)] [scriptable, uuid(283EE646-1AEF-11D4-98B3-00C04fA0CE9A)]
interface nsIPropertyElement : nsISupports { interface nsIPropertyElement : nsISupports {
attribute wstring key;
[noscript] void SetKey(in nsStringPtr aKey); attribute wstring value;
[noscript] void SetValue(in nsStringPtr aValue);
wstring getKey();
wstring getValue();
}; };

View File

@@ -111,14 +111,8 @@ NS_IMETHODIMP
nsPersistentProperties::Load(nsIInputStream *aIn) nsPersistentProperties::Load(nsIInputStream *aIn)
{ {
PRInt32 c; PRInt32 c;
nsresult ret = NS_ERROR_FAILURE; nsresult ret = NS_NewUTF8ConverterStream(&mIn, aIn, 0);
nsAutoString uesc;
uesc.AssignWithConversion("UTF-8");
#ifndef XPCOM_STANDALONE
ret = NS_NewConverterStream(&mIn, nsnull, aIn, 0, &uesc);
#endif /* XPCOM_STANDALONE */
if (ret != NS_OK) { if (ret != NS_OK) {
#ifdef NS_DEBUG #ifdef NS_DEBUG
printf("NS_NewConverterStream failed\n"); printf("NS_NewConverterStream failed\n");
@@ -299,16 +293,13 @@ AddElemToArray(PLHashEntry* he, PRIntn i, void* arg)
{ {
nsISupportsArray *propArray = (nsISupportsArray *) arg; nsISupportsArray *propArray = (nsISupportsArray *) arg;
nsString* keyStr = new nsString((PRUnichar*) he->key); nsPropertyElement *element =
nsString* valueStr = new nsString((PRUnichar*) he->value); new nsPropertyElement((PRUnichar*)he->key,
(PRUnichar*)he->value);
nsPropertyElement *element = new nsPropertyElement();
if (!element) if (!element)
return HT_ENUMERATE_STOP; return HT_ENUMERATE_STOP;
NS_ADDREF(element); NS_ADDREF(element);
element->SetKey(keyStr);
element->SetValue(valueStr);
propArray->InsertElementAt(element, i); propArray->InsertElementAt(element, i);
return HT_ENUMERATE_NEXT; return HT_ENUMERATE_NEXT;
@@ -450,20 +441,7 @@ nsPersistentProperties::Has(const char* prop, PRBool *result)
// PropertyElement // PropertyElement
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
nsPropertyElement::nsPropertyElement()
{
NS_INIT_REFCNT();
mKey = nsnull;
mValue = nsnull;
}
nsPropertyElement::~nsPropertyElement()
{
if (mKey)
delete mKey;
if (mValue)
delete mValue;
}
NS_METHOD NS_METHOD
nsPropertyElement::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) nsPropertyElement::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{ {
@@ -485,7 +463,7 @@ nsPropertyElement::GetKey(PRUnichar **aReturnKey)
{ {
if (aReturnKey) if (aReturnKey)
{ {
*aReturnKey = ToNewUnicode(*mKey); *aReturnKey = ToNewUnicode(mKey);
return NS_OK; return NS_OK;
} }
@@ -497,7 +475,7 @@ nsPropertyElement::GetValue(PRUnichar **aReturnValue)
{ {
if (aReturnValue) if (aReturnValue)
{ {
*aReturnValue = ToNewUnicode(*mValue); *aReturnValue = ToNewUnicode(mValue);
return NS_OK; return NS_OK;
} }
@@ -505,18 +483,16 @@ nsPropertyElement::GetValue(PRUnichar **aReturnValue)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsPropertyElement::SetKey(nsString* aKey) nsPropertyElement::SetKey(const PRUnichar* aKey)
{ {
mKey = aKey; mKey = aKey;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsPropertyElement::SetValue(nsString* aValue) nsPropertyElement::SetValue(const PRUnichar* aValue)
{ {
mValue = aValue; mValue = aValue;
return NS_OK; return NS_OK;
} }

View File

@@ -74,6 +74,8 @@ public:
protected: protected:
nsIUnicharInputStream* mIn; nsIUnicharInputStream* mIn;
PRUint32 mBufferPos;
PRUint32 mBufferLength;
nsIPersistentProperties* mSubclass; nsIPersistentProperties* mSubclass;
struct PLHashTable* mTable; struct PLHashTable* mTable;
}; };
@@ -81,8 +83,10 @@ protected:
class nsPropertyElement : public nsIPropertyElement class nsPropertyElement : public nsIPropertyElement
{ {
public: public:
nsPropertyElement(); nsPropertyElement() {};
virtual ~nsPropertyElement(); nsPropertyElement(const PRUnichar *aKey,
const PRUnichar *aValue): mKey(aKey), mValue(aValue) {}
virtual ~nsPropertyElement() {};
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -92,12 +96,12 @@ public:
// nsIPropertyElement methods: // nsIPropertyElement methods:
NS_IMETHOD GetKey(PRUnichar **aReturnKey); NS_IMETHOD GetKey(PRUnichar **aReturnKey);
NS_IMETHOD GetValue(PRUnichar **aReturnValue); NS_IMETHOD GetValue(PRUnichar **aReturnValue);
NS_IMETHOD SetKey(nsString* aKey); NS_IMETHOD SetKey(const PRUnichar* aKey);
NS_IMETHOD SetValue(nsString* aValue); NS_IMETHOD SetValue(const PRUnichar* aValue);
protected: protected:
nsString* mKey; nsString mKey;
nsString* mValue; nsString mValue;
}; };
#endif /* nsPersistentProperties_h___ */ #endif /* nsPersistentProperties_h___ */

View File

@@ -76,10 +76,8 @@ extern NS_COM nsresult
* NS_INPUTSTREAM_NO_CONVERTER. * NS_INPUTSTREAM_NO_CONVERTER.
*/ */
extern NS_COM nsresult extern NS_COM nsresult
NS_NewConverterStream(nsIUnicharInputStream** aInstancePtrResult, NS_NewUTF8ConverterStream(nsIUnicharInputStream** aInstancePtrResult,
nsISupports* aOuter,
nsIInputStream* aStreamToWrap, nsIInputStream* aStreamToWrap,
PRInt32 aBufferSize = 0, PRInt32 aBufferSize = 0);
nsString* aCharSet = nsnull);
#endif /* nsUnicharInputStream_h___ */ #endif /* nsUnicharInputStream_h___ */

View File

@@ -35,15 +35,11 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef XPCOM_STANDALONE
#define NS_IMPL_IDS
#include "nsIUnicharInputStream.h" #include "nsIUnicharInputStream.h"
#include "nsIByteBuffer.h" #include "nsIByteBuffer.h"
#include "nsIUnicharBuffer.h" #include "nsIUnicharBuffer.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsIUnicodeDecoder.h"
#include "nsString.h" #include "nsString.h"
#include "nsCRT.h" #include "nsCRT.h"
#include <fcntl.h> #include <fcntl.h>
@@ -53,8 +49,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
class StringUnicharInputStream : public nsIUnicharInputStream { class StringUnicharInputStream : public nsIUnicharInputStream {
public: public:
StringUnicharInputStream(nsString* aString); StringUnicharInputStream(nsString* aString);
@@ -142,44 +136,11 @@ NS_NewStringUnicharInputStream(nsIUnicharInputStream** aInstancePtrResult,
//---------------------------------------------------------------------- //----------------------------------------------------------------------
/** class UTF8InputStream : public nsIUnicharInputStream {
* This function used to be public, with the NS_COM declaration. I am
* changing it right now into a module private visibility because there are
* better and more xpcom-like ways to get a Converter.
*/
nsresult NS_NewB2UConverter(nsIUnicodeDecoder** aInstancePtrResult, nsISupports* aOuter, nsString* aCharSet);
nsresult
NS_NewB2UConverter(nsIUnicodeDecoder** aInstancePtrResult,
nsISupports* aOuter,
nsString* aCharSet)
{
if (nsnull != aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
// Create converter
nsresult res;
nsAutoString defaultCharset;
defaultCharset.AssignWithConversion("ISO-8859-1");
if (aCharSet == nsnull) aCharSet = &defaultCharset;
nsCOMPtr<nsICharsetConverterManager> ccm =
do_GetService(kCharsetConverterManagerCID, &res);
if (NS_FAILED(res)) return res;
return ccm->GetUnicodeDecoder(aCharSet, aInstancePtrResult);
}
//----------------------------------------------------------------------
class ConverterInputStream : public nsIUnicharInputStream {
public: public:
ConverterInputStream(nsIInputStream* aStream, UTF8InputStream(nsIInputStream* aStream,
nsIUnicodeDecoder* aConverter,
PRUint32 aBufSize); PRUint32 aBufSize);
virtual ~ConverterInputStream(); virtual ~UTF8InputStream();
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_IMETHOD Read(PRUnichar* aBuf, NS_IMETHOD Read(PRUnichar* aBuf,
@@ -191,67 +152,52 @@ public:
protected: protected:
PRInt32 Fill(nsresult * aErrorCode); PRInt32 Fill(nsresult * aErrorCode);
nsIInputStream* mInput; static PRInt32 CountValidUTF8Bytes(const char *aBuf, PRInt32 aMaxBytes);
nsIUnicodeDecoder* mConverter;
nsIByteBuffer* mByteData; nsCOMPtr<nsIInputStream> mInput;
nsCOMPtr<nsIByteBuffer> mByteData;
nsCOMPtr<nsIUnicharBuffer> mUnicharData;
PRUint32 mByteDataOffset; PRUint32 mByteDataOffset;
nsIUnicharBuffer* mUnicharData;
PRUint32 mUnicharDataOffset; PRUint32 mUnicharDataOffset;
PRUint32 mUnicharDataLength; PRUint32 mUnicharDataLength;
}; };
ConverterInputStream::ConverterInputStream(nsIInputStream* aStream, UTF8InputStream::UTF8InputStream(nsIInputStream* aStream,
nsIUnicodeDecoder* aConverter, PRUint32 aBufferSize) :
PRUint32 aBufferSize) mInput(aStream)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mInput = aStream;
NS_ADDREF(aStream);
mConverter = aConverter;
NS_ADDREF(aConverter);
if (aBufferSize == 0) { if (aBufferSize == 0) {
aBufferSize = 8192; aBufferSize = 8192;
} }
// XXX what if these fail? // XXX what if these fail?
NS_NewByteBuffer(&mByteData, nsnull, aBufferSize); NS_NewByteBuffer(getter_AddRefs(mByteData), nsnull, aBufferSize);
NS_NewUnicharBuffer(&mUnicharData, nsnull, aBufferSize); NS_NewUnicharBuffer(getter_AddRefs(mUnicharData), nsnull, aBufferSize);
mByteDataOffset = 0; mByteDataOffset = 0;
mUnicharDataOffset = 0; mUnicharDataOffset = 0;
mUnicharDataLength = 0; mUnicharDataLength = 0;
} }
NS_IMPL_ISUPPORTS1(ConverterInputStream,nsIUnicharInputStream) NS_IMPL_ISUPPORTS1(UTF8InputStream,nsIUnicharInputStream)
ConverterInputStream::~ConverterInputStream() UTF8InputStream::~UTF8InputStream()
{ {
Close(); Close();
} }
nsresult ConverterInputStream::Close() nsresult UTF8InputStream::Close()
{ {
if (nsnull != mInput) {
NS_RELEASE(mInput);
mInput = nsnull; mInput = nsnull;
}
if (nsnull != mConverter) {
NS_RELEASE(mConverter);
mConverter = nsnull;
}
if (nsnull != mByteData) {
NS_RELEASE(mByteData);
mByteData = nsnull; mByteData = nsnull;
}
if (nsnull != mUnicharData) {
NS_RELEASE(mUnicharData);
mUnicharData = nsnull; mUnicharData = nsnull;
}
return NS_OK; return NS_OK;
} }
nsresult ConverterInputStream::Read(PRUnichar* aBuf, nsresult UTF8InputStream::Read(PRUnichar* aBuf,
PRUint32 aOffset, PRUint32 aOffset,
PRUint32 aCount, PRUint32 aCount,
PRUint32 *aReadCount) PRUint32 *aReadCount)
@@ -277,7 +223,7 @@ nsresult ConverterInputStream::Read(PRUnichar* aBuf,
return NS_OK; return NS_OK;
} }
PRInt32 ConverterInputStream::Fill(nsresult * aErrorCode) PRInt32 UTF8InputStream::Fill(nsresult * aErrorCode)
{ {
if (nsnull == mInput) { if (nsnull == mInput) {
// We already closed the stream! // We already closed the stream!
@@ -300,43 +246,92 @@ PRInt32 ConverterInputStream::Fill(nsresult * aErrorCode)
NS_ASSERTION(remainder + nb == mByteData->GetLength(), "bad nb"); NS_ASSERTION(remainder + nb == mByteData->GetLength(), "bad nb");
// Now convert as much of the byte buffer to unicode as possible // Now convert as much of the byte buffer to unicode as possible
PRInt32 dstLen = mUnicharData->GetBufferSize(); PRInt32 srcLen = CountValidUTF8Bytes(mByteData->GetBuffer(),remainder + nb);
PRInt32 srcLen = remainder + nb;
*aErrorCode = mConverter->Convert(mByteData->GetBuffer(), &srcLen, NS_ConvertUTF8toUCS2
mUnicharData->GetBuffer(), &dstLen); unicodeValue(Substring(mByteData->GetBuffer(),
mByteData->GetBuffer() + srcLen));
PRInt32 dstLen = unicodeValue.Length();
// the number of UCS2 characters should always be <= the number of
// UTF8 chars
NS_ASSERTION(dstLen <= mUnicharData->GetBufferSize(),
"Ouch. I would overflow my buffer if I wasn't so careful.");
if (dstLen > mUnicharData->GetBufferSize()) return 0;
nsCRT::memcpy((void *)mUnicharData->GetBuffer(),
(void *)unicodeValue.get(), dstLen*sizeof(PRUnichar));
mUnicharDataOffset = 0; mUnicharDataOffset = 0;
mUnicharDataLength = dstLen; mUnicharDataLength = dstLen;
mByteDataOffset += srcLen; mByteDataOffset += srcLen;
return dstLen; return dstLen;
} }
// XXX hook up auto-detect here (do we need more info, like the url?) PRInt32
NS_COM nsresult UTF8InputStream::CountValidUTF8Bytes(const char* aBuffer, PRInt32 aMaxBytes)
NS_NewConverterStream(nsIUnicharInputStream** aInstancePtrResult,
nsISupports* aOuter,
nsIInputStream* aStreamToWrap,
PRInt32 aBufferSize,
nsString* aCharSet)
{ {
if (nsnull != aOuter) { const char *c = aBuffer;
return NS_ERROR_NO_AGGREGATION; const char *lastchar = aBuffer;
PRInt32 bytes = 0;
while (*c && bytes <= aMaxBytes) {
lastchar = c;
if (UTF8traits::isASCII(*c)) {
c++;
bytes++;
} }
// Create converter else if (UTF8traits::is2byte(*c)) {
nsIUnicodeDecoder* converter; c += 2;
nsresult rv = NS_NewB2UConverter(&converter, nsnull, aCharSet); bytes += 2;
if (NS_OK != rv) {
return rv;
} }
else if (UTF8traits::is3byte(*c)) {
c += 3;
bytes += 3;
}
else if (UTF8traits::is4byte(*c)) {
c += 4;
bytes += 4;
}
else if (UTF8traits::is5byte(*c)) {
c += 5;
bytes += 5;
}
else if (UTF8traits::is6byte(*c)) {
c+=6;
bytes +=6;
}
else
NS_WARNING("Unrecognized UTF8 string in UTF8InputStream::CountValidUTF8Bytes()");
}
// if we skipped pas the end of the buffer, back up to the last character
if (bytes > aMaxBytes) {
c = lastchar;
bytes = (c-aBuffer);
}
return bytes;
}
NS_COM nsresult
NS_NewUTF8ConverterStream(nsIUnicharInputStream** aInstancePtrResult,
nsIInputStream* aStreamToWrap,
PRInt32 aBufferSize)
{
// Create converter input stream // Create converter input stream
ConverterInputStream* it = UTF8InputStream* it =
new ConverterInputStream(aStreamToWrap, converter, aBufferSize); new UTF8InputStream(aStreamToWrap, aBufferSize);
NS_RELEASE(converter);
if (nsnull == it) { if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
return it->QueryInterface(NS_GET_IID(nsIUnicharInputStream), return it->QueryInterface(NS_GET_IID(nsIUnicharInputStream),
(void **) aInstancePtrResult); (void **) aInstancePtrResult);
} }
#endif /* XPCOM_STANDALONE */

View File

@@ -36,7 +36,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include <stdio.h> #include <stdio.h>
#include "nscore.h" #include "nscore.h"
#include "nsIUnicharInputStream.h" #include "nsIConverterInputStream.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsCRT.h" #include "nsCRT.h"
@@ -52,7 +52,7 @@ static nsString* ConvertCharacterSetName(const char* aName)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if (3 != argc) { if (3 != argc) {
printf("usage: CvtURL url character-set-name\n"); printf("usage: CvtURL url utf8\n");
return -1; return -1;
} }
@@ -82,9 +82,12 @@ int main(int argc, char** argv)
return -1; return -1;
} }
// Translate the input using the argument character set id into unicode // Translate the input using the argument character set id into
nsIUnicharInputStream* uin; // unicode
rv = NS_NewConverterStream(&uin, nsnull, in, 0, cset); nsCOMPtr<nsIConverterInputStream> uin =
do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv);
if (NS_SUCCEEDED(rv))
uin->Init(in, cset->get(), nsnull);
if (NS_OK != rv) { if (NS_OK != rv) {
printf("can't create converter input stream: %d\n", rv); printf("can't create converter input stream: %d\n", rv);
return -1; return -1;
@@ -117,7 +120,6 @@ int main(int argc, char** argv)
// Release the objects // Release the objects
in->Release(); in->Release();
uin->Release();
url->Release(); url->Release();
return 0; return 0;