mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
Evolution of the CharsetConverterManager in order to pair the new Charset Menu. r=erik
This commit is contained in:
parent
835790a98b
commit
5760e40e40
@ -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___ */
|
||||
|
@ -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<nsICharsetConverterManager>::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;i<mEncSize;) {
|
||||
info = GetICharsetConverterInfo(mEncArray, i, &mEncSize);
|
||||
if (info == NULL) continue;
|
||||
// get the registry
|
||||
res = nsServiceManager::GetService(NS_REGISTRY_PROGID,
|
||||
nsIRegistry::GetIID(), (nsISupports**)®istry);
|
||||
if (NS_FAILED(res)) goto done;
|
||||
|
||||
char *charset;
|
||||
info->GetCharsetDest(&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;i<mDecSize;) {
|
||||
info = GetICharsetConverterInfo(mDecArray, i, &mDecSize);
|
||||
if (info == NULL) continue;
|
||||
|
||||
char *charset;
|
||||
info->GetCharsetSrc(&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;i<size;i++) (*aResult)[i] = array[i]->mName;
|
||||
|
||||
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;i<mEncSize;i++) (*aResult)[i]=mEncArray[i].mCharset;
|
||||
}
|
||||
NS_IMETHODIMP nsCharsetConverterManager::GetEncoderList(nsString *** aResult,
|
||||
PRInt32 * aCount)
|
||||
{
|
||||
return GetConverterList(&mEncoderArray, aResult, aCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCharsetConverterManager::GetDecoderFlags(nsString * aName,
|
||||
PRInt32 * aFlags)
|
||||
{
|
||||
*aFlags = 0;
|
||||
|
||||
nsConverterInfo * info = GetConverterInfo(&mDecoderArray, aName);
|
||||
if (info == NULL) return NS_ERROR_UCONV_NOCONV;
|
||||
|
||||
*aFlags = info->mFlags;
|
||||
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;i<mDecSize;i++) (*aResult)[i]=mDecArray[i].mCharset;
|
||||
}
|
||||
nsConverterInfo * info = GetConverterInfo(&mEncoderArray, aName);
|
||||
if (info == NULL) return NS_ERROR_UCONV_NOCONV;
|
||||
|
||||
*aFlags = info->mFlags;
|
||||
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);
|
||||
}
|
||||
|
@ -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;i<ct;i++) {
|
||||
@ -130,9 +130,9 @@ nsresult testCharsetConverterManager()
|
||||
}
|
||||
delete [] cs;
|
||||
|
||||
res = ccMan->GetEncodableCharsets(&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<ct;i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user