diff --git a/mozilla/intl/uconv/public/nsICharsetConverterManager.h b/mozilla/intl/uconv/public/nsICharsetConverterManager.h index 1845f84a4bb..f661b1c19bc 100644 --- a/mozilla/intl/uconv/public/nsICharsetConverterManager.h +++ b/mozilla/intl/uconv/public/nsICharsetConverterManager.h @@ -29,123 +29,70 @@ #include "nsIUnicodeEncoder.h" #include "nsIUnicodeDecoder.h" -// Interface ID for our ConverterManager interface -// {1E3F79F0-6B6B-11d2-8A86-00600811A836} -// NS_DECLARE_ID(kICharsetConverterManagerIID, -// 0x1e3f79f0, 0x6b6b, 0x11d2, 0x8a, 0x86, 0x0, 0x60, 0x8, 0x11, 0xa8, 0x36); +#define NS_ICHARSETCONVERTERMANAGER_IID \ + {0x3c1c0161, 0x9bd0, 0x11d3, { 0x9d, 0x9, 0x0, 0x50, 0x4, 0x0, 0x7, 0xb2}} -#define NS_ICHARSETCONVERTERMANAGER_IID \ -{ /* 1E3F79F0-6B6B-11d2-8A86-00600811A836 */ \ - 0x1e3f79f0, \ - 0x6b6b, \ - 0x11d2, \ - {0x8a, 0x86, 0x00, 0x60, 0x08, 0x11, 0xa8, 0x36} \ -} +// XXX change to NS_CHARSETCONVERTERMANAGER_CID +#define NS_ICHARSETCONVERTERMANAGER_CID \ + {0x3c1c0163, 0x9bd0, 0x11d3, { 0x9d, 0x9, 0x0, 0x50, 0x4, 0x0, 0x7, 0xb2}} -// Class ID for our ConverterManager implementation -// {1E3F79F1-6B6B-11d2-8A86-00600811A836} -// NS_DECLARE_ID(kCharsetConverterManagerCID, -// 0x1e3f79f1, 0x6b6b, 0x11d2, 0x8a, 0x86, 0x0, 0x60, 0x8, 0x11, 0xa8, 0x36); +// XXX change to NS_CHARSETCONVERTERMANAGER_PID +#define NS_CHARSETCONVERTERMANAGER_PROGID "charset-converter-manager" -#define NS_ICHARSETCONVERTERMANAGER_CID \ -{ /* 1E3F79F1-6B6B-11d2-8A86-00600811A836 */ \ - 0x1e3f79f1, \ - 0x6b6b, \ - 0x11d2, \ - {0x8a, 0x86, 0x00, 0x60, 0x08, 0x11, 0xa8, 0x36} \ -} -#define NS_CHARSETCONVERTERMANAGER_PROGID "component://netscape/intl/charsetconvertermanager" +#define NS_REGISTRY_UCONV_BASE "software/netscape/intl/uconv/" #define NS_ERROR_UCONV_NOCONV \ - NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_UCONV,1) + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_UCONV, 0x01) + +#define SET_FOR_BROWSER(_val) (_val |= 0x00000001) +#define SET_NOT_FOR_BROWSER(_val) (_val |= (!0x00000001)) +#define GET_FOR_BROWSER(_val) ((_val &= 0x00000001) != 0) + +#define SET_FOR_EDITOR(_val) (_val |= 0x00000001) +#define SET_NOT_FOR_EDITOR(_val) (_val |= (!0x00000001)) +#define GET_FOR_EDITOR(_val) ((_val &= 0x00000001) != 0) + +#define SET_FOR_MAILNEWS(_val) (_val |= 0x00000002) +#define SET_NOT_FOR_MAILNEWS(_val) (_val |= (!0x00000002)) +#define GET_FOR_MAILNEWS(_val) ((_val &= 0x00000002) != 0) + +#define SET_FOR_MAILNEWSEDITOR(_val) (_val |= 0x00000002) +#define SET_NOT_FOR_MAILNEWSEDITOR(_val) (_val |= (!0x00000002)) +#define GET_FOR_MAILNEWSEDITOR(_val) ((_val &= 0x00000002) != 0) /** * Interface for a Manager of Charset Converters. - * + * + * This Manager's data is a caching of Registry available stuff. But the access + * methods are also doing all the work to get it and provide it. + * * Note: The term "Charset" used in the classes, interfaces and file names * should be read as "Coded Character Set". I am saying "charset" only for * length considerations: it is a much shorter word. This convention is for * source-code only, in the attached documents I will be either using the - * full expression or I'll specify a different convetion. + * full expression or I'll specify a different convention. * - * XXX Move the ICharsetManager methods (the last 2 methods in the interface) - * into a separate interface. They are conceptually independent. I left them - * here only for easier implementation. + * A DECODER converts from a random encoding into Unicode. + * An ENCODER converts from Unicode into a random encoding. + * All our data structures and APIs are divided like that. * - * XXX Add HasUnicodeEncoder() and HasUnicodeDecoder() methods. - * - * @created 17/Nov/1998 + * @created 15/Nov/1999 * @author Catalin Rotaru [CATA] */ class nsICharsetConverterManager : public nsISupports { public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICHARSETCONVERTERMANAGER_IID) - static const nsIID& GetIID() { static nsIID iid = NS_ICHARSETCONVERTERMANAGER_IID; return iid; } - /** - * Find and instantiate a Converter able to encode from Unicode into the - * destination charset. - * - * @param aDest [IN] the known name/alias of the destination charset - * @param aResult [OUT] the charset converter - * @return NS_ERROR_UCONV_NOCONV if no converter was found for - * this charset - */ NS_IMETHOD GetUnicodeEncoder(const nsString * aDest, nsIUnicodeEncoder ** aResult) = 0; - - /** - * Find and instantiate a Converter able to decode from the source charset - * into Unicode. - * - * @param aSrc [IN] the known name/alias of the source charset - * @param aResult [OUT] the charset converter - * @return NS_ERROR_UCONV_NOCONV if no converter was found for - * this charset - */ NS_IMETHOD GetUnicodeDecoder(const nsString * aSrc, nsIUnicodeDecoder ** aResult) = 0; - - /** - * Returns a list of charsets for which we have converters from Unicode. - * - * @param aResult [OUT] an array of pointers to Strings (charset names) - * @param aCount [OUT] the size (number of elements) of that array - */ - NS_IMETHOD GetEncodableCharsets(nsString *** aResult, PRInt32 * aCount) = 0; - - /** - * Returns a list of charsets for which we have converters into Unicode. - * - * @param aResult [OUT] an array of pointers to Strings (charset names) - * @param aCount [OUT] the size (number of elements) of that array - */ - NS_IMETHOD GetDecodableCharsets(nsString *** aResult, PRInt32 * aCount) = 0; - - /** - * Resolves the canonical name of a charset. If the given name is unknown - * to the resolver, a new identical string will be returned! This way, - * new & unknown charsets are not rejected and they are treated as any other - * charset except they can't have aliases. - * - * @param aCharset [IN] the known name/alias of the character set - * @param aResult [OUT] the canonical name of the character set - */ - NS_IMETHOD GetCharsetName(const nsString * aCharset, - nsString ** aResult) = 0; - - /** - * Returns a list containing all the legal names for a given charset. The - * list will allways have at least 1 element: the cannonical name for that - * charset. - * - * @param aCharset [IN] a known name/alias of the character set - * @param aResult [OUT] the list; in the first position is the - * cannonical name, then the other aliases - */ - NS_IMETHOD GetCharsetNames(const nsString * aCharset, - nsString *** aResult, PRInt32 * aCount) = 0; + NS_IMETHOD GetDecoderList(nsString *** aResult, PRInt32 * aCount) = 0; + NS_IMETHOD GetEncoderList(nsString *** aResult, PRInt32 * aCount) = 0; + NS_IMETHOD GetDecoderFlags(nsString * aName, PRInt32 * aFlags) = 0; + NS_IMETHOD GetEncoderFlags(nsString * aName, PRInt32 * aFlags) = 0; }; #endif /* nsICharsetConverterManager_h___ */ diff --git a/mozilla/intl/uconv/src/nsCharsetConverterManager.cpp b/mozilla/intl/uconv/src/nsCharsetConverterManager.cpp index b68a5ac332f..580c8eb04ba 100644 --- a/mozilla/intl/uconv/src/nsCharsetConverterManager.cpp +++ b/mozilla/intl/uconv/src/nsCharsetConverterManager.cpp @@ -22,16 +22,10 @@ #define NS_IMPL_IDS -#include "pratom.h" #include "nsString.h" -#include "nsIComponentManager.h" #include "nsIRegistry.h" -#include "nsIEnumerator.h" #include "nsIServiceManager.h" #include "nsICharsetConverterManager.h" -#include "nsICharsetConverterInfo.h" -#include "nsIUnicodeEncoder.h" -#include "nsIUnicodeDecoder.h" #include "nsUConvDll.h" // just for CIDs @@ -42,52 +36,62 @@ #include "nsIUnicodeDecodeUtil.h" #include "nsUnicodeDecodeUtil.h" -//---------------------------------------------------------------------- -// Global functions and data [declaration] +static NS_DEFINE_IID(kRegistryNodeIID, NS_IREGISTRYNODE_IID); -struct ConverterInfo +//---------------------------------------------------------------------------- +// Class nsObject [declaration] + +class nsObject { - nsString * mCharset; - const nsCID * mCID; - PRBool mFreeCID; - - ConverterInfo() - : mCharset(nsnull), mCID(nsnull), mFreeCID(PR_FALSE) {} - - ~ConverterInfo() - { - if (mCharset != NULL) delete mCharset; - if (mFreeCID) delete (nsCID*)mCID; - } +public: + virtual ~nsObject(); }; -//---------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// Class nsObjectArray [declaration] + +class nsObjectArray +{ +private: + + nsObject ** mArray; + PRInt32 mCapacity; + PRInt32 mUsage; + + void Init(PRInt32 aCapacity); + +public: + nsObjectArray(); + nsObjectArray(PRInt32 aCapacity); + ~nsObjectArray(); + + nsObject ** GetArray(); + PRInt32 GetUsage(); + nsresult InsureCapacity(PRInt32 aCapacity); + nsresult AddObject(nsObject * aObject); +}; + +//---------------------------------------------------------------------------- +// Class nsConverterInfo [declaration] + +class nsConverterInfo : public nsObject +{ +public: + nsString * mName; + nsCID mCID; + PRInt32 mFlags; + + nsConverterInfo(); + ~nsConverterInfo(); +}; + +//---------------------------------------------------------------------------- // Class nsCharsetConverterManager [declaration] /** * The actual implementation of the nsICharsetConverterManager interface. * - * Requirements for a Manager: - * - singleton - * - special lifetime (survive even if it's not used, die only under memory - * pressure conditions or app termination) - * - * Ways of implementing it & fulfill those requirements: - * + simple xpcom object (current implementation model) - * - xpcom service (best, but no support available yet) - * - global class with static methods (ie part of the platform) - * - * Interesting observation: the NS_IMPL_IDS macros suck! In a given file, one - * can only declare OR define IDs, not both. Considering the unique-per-dll - * implementation, the headers inclusion and IDs declaration vs. definition - * becomes quite tricky. - * - * XXX make this component thread safe - * - * XXX Use the more general xpcom extensibility model when it will be ready. - * That means: Component Categories + Monikers. Better performance! - * - * @created 17/Nov/1998 + * @created 15/Nov/1999 * @author Catalin Rotaru [CATA] */ class nsCharsetConverterManager : public nsICharsetConverterManager @@ -96,196 +100,219 @@ class nsCharsetConverterManager : public nsICharsetConverterManager private: - /** - * Pointer to the unique instance of this class. - */ - static nsICharsetConverterManager * mInstance; + nsObjectArray mDecoderArray; + nsObjectArray mEncoderArray; /** - * The Mapping data structures. + * Takes charset information from Registry and puts it into those arrays. */ - ConverterInfo mEncArray[100]; - PRInt32 mEncSize; - ConverterInfo mDecArray[100]; - PRInt32 mDecSize; - - PRBool mMappingDone; + void FillInfoArrays(); + void FillConverterProperties(nsObjectArray * aArray); /** - * Class constructor. + * Returns NULL if charset could not be found. */ - nsCharsetConverterManager(); + nsConverterInfo * GetConverterInfo(nsObjectArray * aArray, + nsString * aName); - /** - * Creates some sort of mapping (Charset, Charset) -> Converter. - */ - nsresult CreateMapping(); - - /** - * Gathers the necessary informations about each Converter. - */ - nsresult GatherConvertersInfo(); - - /** - * Attempts to return a ICharsetConverterInfo reference for the given charset - * in the array. If errors, the converter will be eliminated from the array. - */ - nsICharsetConverterInfo * GetICharsetConverterInfo(ConverterInfo * ci, - PRInt32 aIndex, PRInt32 * aSize); + nsresult GetConverterList(nsObjectArray * aArray, nsString *** aResult, + PRInt32 * aCount); + static nsresult RegisterConverterPresenceData(char * aRegistryPath, + PRBool aPresence); public: - /** - * Class destructor. - */ + nsCharsetConverterManager(); virtual ~nsCharsetConverterManager(); + static nsresult RegisterConverterManagerData(); - /** - * Unique factory method for this class (the constructor is private). - * - * @return a singleton object, instance of this class - */ - static nsICharsetConverterManager * GetInstance(); - - //-------------------------------------------------------------------- + //-------------------------------------------------------------------------- // Interface nsICharsetConverterManager [declaration] NS_IMETHOD GetUnicodeEncoder(const nsString * aDest, nsIUnicodeEncoder ** aResult); NS_IMETHOD GetUnicodeDecoder(const nsString * aSrc, nsIUnicodeDecoder ** aResult); - NS_IMETHOD GetEncodableCharsets(nsString *** aResult, PRInt32 * aCount); - NS_IMETHOD GetDecodableCharsets(nsString *** aResult, PRInt32 * aCount); - NS_IMETHOD GetCharsetName(const nsString * aCharset, nsString ** aResult); - NS_IMETHOD GetCharsetNames(const nsString * aCharset, nsString *** aResult, - PRInt32 * aCount); + NS_IMETHOD GetDecoderList(nsString *** aResult, PRInt32 * aCount); + NS_IMETHOD GetEncoderList(nsString *** aResult, PRInt32 * aCount); + NS_IMETHOD GetDecoderFlags(nsString * aName, PRInt32 * aFlags); + NS_IMETHOD GetEncoderFlags(nsString * aName, PRInt32 * aFlags); }; -//---------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// Global functions and data [implementation] + +NS_IMETHODIMP NS_NewCharsetConverterManager(nsISupports* aOuter, + const nsIID& aIID, + void** aResult) +{ + if (!aResult) { + return NS_ERROR_NULL_POINTER; + } + if (aOuter) { + *aResult = nsnull; + return NS_ERROR_NO_AGGREGATION; + } + nsCharsetConverterManager * inst = new nsCharsetConverterManager(); + if (!inst) { + *aResult = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + nsresult res = inst->QueryInterface(aIID, aResult); + if (NS_FAILED(res)) { + *aResult = nsnull; + delete inst; + } + return res; +} + +//---------------------------------------------------------------------------- +// Class nsObject [implementation] + +// XXX clarify why I can't have this method as a pure virtual one?! +nsObject::~nsObject() +{ +} + +//---------------------------------------------------------------------------- +// Class nsObjectsArray [implementation] + +nsObjectArray::nsObjectArray(PRInt32 aCapacity) +{ + Init(aCapacity); +} + +nsObjectArray::nsObjectArray() +{ + Init(64); +} + +nsObjectArray::~nsObjectArray() +{ + for (PRInt32 i = 0; i < mUsage; i++) delete mArray[i]; + if (mArray != NULL) delete [] mArray; +} + +nsObject ** nsObjectArray::GetArray() +{ + return mArray; +} + +PRInt32 nsObjectArray::GetUsage() +{ + return mUsage; +} + +void nsObjectArray::Init(PRInt32 aCapacity) +{ + mCapacity = aCapacity; + mUsage = 0; + mArray = NULL; +} + +nsresult nsObjectArray::InsureCapacity(PRInt32 aCapacity) +{ + PRInt32 i; + + if (mArray == NULL) { + mArray = new nsObject * [mCapacity]; + if (mArray == NULL) return NS_ERROR_OUT_OF_MEMORY; + } + + if (aCapacity > mCapacity) { + while (aCapacity > mCapacity) mCapacity *= 2; + nsObject ** newArray = new nsObject * [mCapacity]; + if (newArray == NULL) return NS_ERROR_OUT_OF_MEMORY; + for (i = 0; i < mUsage; i++) newArray[i] = mArray[i]; + delete [] mArray; + mArray = newArray; + } + + return NS_OK; +} + +nsresult nsObjectArray::AddObject(nsObject * aObject) +{ + nsresult res; + + res = InsureCapacity(mUsage + 1); + if (NS_FAILED(res)) return res; + + (mArray)[mUsage++] = aObject; + return NS_OK; +} + +//---------------------------------------------------------------------------- +// Class nsConverterInfo [implementation] + +nsConverterInfo::nsConverterInfo() +{ + mName = NULL; +} + +nsConverterInfo::~nsConverterInfo() +{ + if (mName != NULL) delete mName; +} + +//---------------------------------------------------------------------------- // Class nsCharsetConverterManager [implementation] -NS_IMPL_ISUPPORTS(nsCharsetConverterManager, nsCOMTypeInfo::GetIID()); - -nsICharsetConverterManager * nsCharsetConverterManager::mInstance = NULL; +NS_IMPL_ISUPPORTS(nsCharsetConverterManager, nsICharsetConverterManager::GetIID()); nsCharsetConverterManager::nsCharsetConverterManager() { - mEncSize = 0; - mDecSize = 0; - - mMappingDone = PR_FALSE; - NS_INIT_REFCNT(); PR_AtomicIncrement(&g_InstanceCount); - CreateMapping(); + FillInfoArrays(); + FillConverterProperties(&mDecoderArray); + FillConverterProperties(&mEncoderArray); } nsCharsetConverterManager::~nsCharsetConverterManager() { - mInstance = NULL; PR_AtomicDecrement(&g_InstanceCount); } -nsICharsetConverterManager * nsCharsetConverterManager::GetInstance() +nsresult nsCharsetConverterManager::RegisterConverterManagerData() { - if (mInstance == NULL) mInstance = new nsCharsetConverterManager(); - return mInstance; + // XXX take these konstants out of here + // XXX change "xuconv" to "uconv" when the new enc&dec trees are in place + RegisterConverterPresenceData("software/netscape/intl/xuconv/not-for-browser", PR_FALSE); + + return NS_OK; } -nsresult nsCharsetConverterManager::CreateMapping() +nsresult nsCharsetConverterManager::RegisterConverterPresenceData( + char * aRegistryPath, + PRBool aPresence) { - mMappingDone = PR_TRUE; - - nsresult res = NS_OK; + nsresult res; nsIRegistry * registry = NULL; - nsIEnumerator * components = NULL; - nsRegistryKey uconvKey, key; - - // XXX hack; make these dynamic - mEncSize = mDecSize = 0; + nsRegistryKey key; // get the registry res = nsServiceManager::GetService(NS_REGISTRY_PROGID, - nsIRegistry::GetIID(), - (nsISupports**)®istry); + nsIRegistry::GetIID(), (nsISupports**)®istry); if (NS_FAILED(res)) goto done; // open the registry res = registry->OpenWellKnownRegistry( - nsIRegistry::ApplicationComponentRegistry); + nsIRegistry::ApplicationComponentRegistry); if (NS_FAILED(res)) goto done; - // get subtree - res = registry -> GetSubtree(nsIRegistry::Common, - "software/netscape/intl/uconv", - &uconvKey); + res = registry -> AddSubtree(nsIRegistry::Common, aRegistryPath, &key); if (NS_FAILED(res)) goto done; - // enumerate subtrees - res = registry -> EnumerateSubtrees(uconvKey, &components); + // XXX instead of these hardcoded values, I should read from a property file + res = registry -> SetInt(key, "x-fake-1999", 1); if (NS_FAILED(res)) goto done; - res = components -> First(); + res = registry -> SetInt(key, "x-fake-2000", 1); + if (NS_FAILED(res)) goto done; + res = registry -> SetInt(key, "X-EUC-TW", 1); if (NS_FAILED(res)) goto done; - - // XXX take these KONSTANTS out of here - // XXX check return values, free stuff - // XXX bit hacky, clean me up - while (NS_OK != components -> IsDone()) { - nsISupports * base; - res = components -> CurrentItem(&base); - if (NS_SUCCEEDED(res)) { - nsIRegistryNode * node; - nsIID nodeIID = NS_IREGISTRYNODE_IID; - res = base->QueryInterface (nodeIID, (void**)&node); - if (NS_FAILED(res)) continue; - - char *name; - res = node->GetName(&name); - if (NS_FAILED(res)) continue; - - nsCID * cid = new nsCID(); - char * src; - char * dest; - if (!cid->Parse(name)) continue; - - res = node->GetKey(&key); - if (NS_FAILED(res)) continue; - - res = registry->GetString(key, "source", &src); - if (NS_FAILED(res)) continue; - res = registry->GetString(key, "destination", &dest); - if (NS_FAILED(res)) { - nsCRT::free(src); - continue; - } - - nsAutoString str; - - if (!strcmp(src, "Unicode")) { - str.Assign(dest); - GetCharsetName(&str,&mEncArray[mEncSize].mCharset); - mEncArray[mEncSize].mCID = cid; - mEncArray[mEncSize].mFreeCID = PR_TRUE; - mEncSize++; - } else if (!strcmp(dest, "Unicode")) { - str.Assign(src); - GetCharsetName(&str,&mDecArray[mDecSize].mCharset); - mDecArray[mDecSize].mCID = cid; - mDecArray[mDecSize].mFreeCID = PR_TRUE; - mDecSize++; - } - - nsCRT::free(src); - nsCRT::free(dest); - nsCRT::free(name); - NS_RELEASE(node); - NS_RELEASE(base); - } - - res = components->Next(); - } done: if (registry != NULL) { @@ -293,91 +320,163 @@ done: nsServiceManager::ReleaseService(NS_REGISTRY_PROGID, registry); } - NS_IF_RELEASE(components); - return res; } - -nsresult nsCharsetConverterManager::GatherConvertersInfo() +// XXX rethink the registry structure(tree) for these converters +// The idea is to have two trees: +// .../uconv/decoder/(CID/name) +// .../uconv/encoder/(CID/name) +// XXX take the registry strings out and make them macros +void nsCharsetConverterManager::FillInfoArrays() { - nsICharsetConverterInfo * info; - nsString * str; - PRInt32 i; + nsresult res = NS_OK; + nsIEnumerator * components = NULL; + nsIRegistry * registry = NULL; + nsRegistryKey uconvKey, key; - for (i=0;iGetCharsetDest(&charset); - str = new nsString(charset); - GetCharsetName(str,&mEncArray[i].mCharset); - delete str; - i++; - NS_RELEASE(info); + // open the registry + res = registry->OpenWellKnownRegistry( + nsIRegistry::ApplicationComponentRegistry); + if (NS_FAILED(res)) goto done; + + // get subtree + res = registry->GetSubtree(nsIRegistry::Common, + "software/netscape/intl/uconv", &uconvKey); + if (NS_FAILED(res)) goto done; + + // enumerate subtrees + res = registry->EnumerateSubtrees(uconvKey, &components); + if (NS_FAILED(res)) goto done; + res = components->First(); + if (NS_FAILED(res)) goto done; + + while (NS_OK != components->IsDone()) { + nsISupports * base = NULL; + nsIRegistryNode * node = NULL; + char * name = NULL; + char * src = NULL; + char * dest = NULL; + nsConverterInfo * ci = NULL; + + res = components->CurrentItem(&base); + if (NS_FAILED(res)) goto done1; + + res = base->QueryInterface(kRegistryNodeIID, (void**)&node); + if (NS_FAILED(res)) goto done1; + + res = node->GetName(&name); + if (NS_FAILED(res)) goto done1; + + ci = new nsConverterInfo(); + if (ci == NULL) goto done1; + if (!(ci->mCID.Parse(name))) goto done1; + + res = node->GetKey(&key); + if (NS_FAILED(res)) goto done1; + + res = registry->GetString(key, "source", &src); + if (NS_FAILED(res)) goto done1; + + res = registry->GetString(key, "destination", &dest); + if (NS_FAILED(res)) goto done1; + + if (!strcmp(src, "Unicode")) { + ci->mName = new nsString(dest); + mEncoderArray.AddObject(ci); + } else if (!strcmp(dest, "Unicode")) { + ci->mName = new nsString(src); + mDecoderArray.AddObject(ci); + } else goto done1; + + ci = NULL; + +done1: + NS_IF_RELEASE(base); + NS_IF_RELEASE(node); + + if (name != NULL) nsCRT::free(name); + if (src != NULL) nsCRT::free(src); + if (dest != NULL) nsCRT::free(dest); + if (ci != NULL) delete ci; + + res = components->Next(); + if (NS_FAILED(res)) break; // this is NOT supposed to fail! } - for (i=0;iGetCharsetSrc(&charset); - str = new nsString(charset); - GetCharsetName(str,&mDecArray[i].mCharset); - delete str; - i++; - NS_RELEASE(info); + // finish and clean up +done: + if (registry != NULL) { + registry->Close(); + nsServiceManager::ReleaseService(NS_REGISTRY_PROGID, registry); } - return NS_OK; + NS_IF_RELEASE(components); } -nsICharsetConverterInfo * -nsCharsetConverterManager::GetICharsetConverterInfo(ConverterInfo * aArray, - PRInt32 aIndex, - PRInt32 * aSize) +void nsCharsetConverterManager::FillConverterProperties( + nsObjectArray * aArray) { - nsresult res; - nsIFactory * factory; - nsICharsetConverterInfo * info; + PRInt32 size = aArray->GetUsage(); + nsConverterInfo ** array = (nsConverterInfo **)aArray->GetArray(); + if ((size == 0) || (array == NULL)) return; - res=nsComponentManager::FindFactory(*(aArray[aIndex].mCID), &factory); - if (NS_FAILED(res)) { - #if 1 - printf(" get charset info FindFactory failed %d %x", aIndex, res); - #endif - goto reduceArray; + for (PRInt32 i = 0; i < size; i++) { + int val = 0; + SET_FOR_BROWSER(val); + SET_FOR_MAILNEWSEDITOR(val); + array[i]->mFlags = val; } - res=factory->QueryInterface(kICharsetConverterInfoIID, (void ** )&info); - NS_RELEASE(factory); - if (NS_FAILED(res)) { - #if 1 - printf(" get charset info QI failed %d %x", aIndex, res); - #endif - goto reduceArray; - } + // XXX get these properties from registry, not from your stomach +} - return info; +// XXX optimise this method - use some hash tables for God's sake! +// That could also mean taking the name out of the data structure. Maybe. +nsConverterInfo * nsCharsetConverterManager::GetConverterInfo( + nsObjectArray * aArray, + nsString * aName) +{ + PRInt32 size = aArray->GetUsage(); + nsConverterInfo ** array = (nsConverterInfo **)aArray->GetArray(); + if ((size == 0) || (array == NULL)) return NULL; -reduceArray: - - PRInt32 i; - - (*aSize)--; - for (i=aIndex; i<*aSize;) aArray[i] = aArray[++i]; - if (i>=0) { - aArray[i].mCharset = NULL; - aArray[i].mCID = NULL; - } + for (PRInt32 i = 0; i < size; i++) if (aName->Equals(*(array[i]->mName))) + return array[i]; return NULL; } +nsresult nsCharsetConverterManager::GetConverterList( + nsObjectArray * aArray, + nsString *** aResult, + PRInt32 * aCount) +{ + *aResult = NULL; + *aCount = 0; -//---------------------------------------------------------------------- + PRInt32 size = aArray->GetUsage(); + nsConverterInfo ** array = (nsConverterInfo **)aArray->GetArray(); + if ((size == 0) || (array == NULL)) return NS_OK; + + *aResult = new nsString * [size]; + if (*aResult == NULL) return NS_ERROR_OUT_OF_MEMORY; + + *aCount = size; + for (PRInt32 i=0;imName; + + return NS_OK; + + // XXX also create new Strings here, as opposed to just providing pointers + // to the existing ones +} + +//---------------------------------------------------------------------------- // Interface nsICharsetConverterManager [implementation] NS_IMETHODIMP nsCharsetConverterManager::GetUnicodeEncoder( @@ -422,84 +521,38 @@ NS_IMETHODIMP nsCharsetConverterManager::GetUnicodeDecoder( return res; } -NS_IMETHODIMP nsCharsetConverterManager::GetEncodableCharsets( - nsString *** aResult, - PRInt32 * aCount) +NS_IMETHODIMP nsCharsetConverterManager::GetDecoderList(nsString *** aResult, + PRInt32 * aCount) { - nsresult res; - if (!mMappingDone) { - res = CreateMapping(); - if NS_FAILED(res) return res; - } + return GetConverterList(&mDecoderArray, aResult, aCount); +} - *aResult = NULL; - *aCount = 0; - if (mEncSize != 0) { - *aResult = new nsString * [mEncSize]; - *aCount = mEncSize; - for (PRInt32 i=0;imFlags; return NS_OK; } -NS_IMETHODIMP nsCharsetConverterManager::GetDecodableCharsets( - nsString *** aResult, - PRInt32 * aCount) +NS_IMETHODIMP nsCharsetConverterManager::GetEncoderFlags(nsString * aName, + PRInt32 * aFlags) { - nsresult res; - if (!mMappingDone) { - res = CreateMapping(); - if NS_FAILED(res) return res; - } + *aFlags = 0; - *aResult = NULL; - *aCount = 0; - if (mDecSize != 0) { - *aResult = new nsString * [mDecSize]; - *aCount = mDecSize; - for (PRInt32 i=0;imFlags; return NS_OK; } - -NS_IMETHODIMP nsCharsetConverterManager::GetCharsetName( - const nsString * aCharset, - nsString ** aResult) -{ - // XXX add aliases capability here - - *aResult = new nsString(*aCharset); - return NS_OK; -} - -NS_IMETHODIMP nsCharsetConverterManager::GetCharsetNames( - const nsString * aCharset, - nsString *** aResult, - PRInt32 * aCount) -{ - // XXX write me - return NS_OK; -} - -//---------------------------------------------------------------------- - -NS_IMETHODIMP -NS_NewCharsetConverterManager(nsISupports* aOuter, const nsIID& aIID, - void** aResult) -{ - if (!aResult) { - return NS_ERROR_INVALID_POINTER; - } - if (aOuter) { - *aResult = nsnull; - return NS_ERROR_NO_AGGREGATION; - } - nsICharsetConverterManager* inst = nsCharsetConverterManager::GetInstance(); - if (!inst) { - *aResult = nsnull; - return NS_ERROR_OUT_OF_MEMORY; - } - return inst->QueryInterface(aIID, aResult); -} diff --git a/mozilla/intl/uconv/tests/nsTestUConv.cpp b/mozilla/intl/uconv/tests/nsTestUConv.cpp index c898fd66a32..24e21906fa1 100644 --- a/mozilla/intl/uconv/tests/nsTestUConv.cpp +++ b/mozilla/intl/uconv/tests/nsTestUConv.cpp @@ -116,9 +116,9 @@ nsresult testCharsetConverterManager() nsString ** cs; PRInt32 ct; - res = ccMan->GetDecodableCharsets(&cs, &ct); + res = ccMan->GetDecoderList(&cs, &ct); if (NS_FAILED(res)) { - printf("ERROR at GetDecodableCharsets() code=0x%x.\n", res); + printf("ERROR at GetDecoderList() code=0x%x.\n", res); } else { printf("UDecoders (%d): ", ct); for (int i=0;iGetEncodableCharsets(&cs, &ct); + res = ccMan->GetEncoderList(&cs, &ct); if (NS_FAILED(res)) { - printf("ERROR at GetEncodableCharsets() code=0x%x.\n", res); + printf("ERROR at GetEncoderList() code=0x%x.\n", res); } else { printf("UEncoders (%d): ", ct); for (int i=0;i