Continuing OS/2 wizard work
It's pretty much working now
This commit is contained in:
mkaply%us.ibm.com 2002-08-27 03:06:10 +00:00
Родитель 7e57b09c22
Коммит a29dba5688
3 изменённых файлов: 58 добавлений и 118 удалений

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

@ -163,59 +163,7 @@ void PMERROR( const char *api)
int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize )
{
UconvObject* pConverter = 0;
uconv_attribute_t attr;
/* Short circuit most common case */
if ((gUconvInfoList) && (gUconvInfoList->mCodePage == CodePage)) {
pConverter = &(gUconvInfoList->mConverter);
} else {
nsUconvInfo* UconvInfoList;
nsUconvInfo* prevUconvInfoList;
if (gUconvInfoList) {
UconvInfoList = gUconvInfoList;
while (UconvInfoList) {
if (UconvInfoList->mCodePage == CodePage) {
pConverter = &(UconvInfoList->mConverter);
break;
}
prevUconvInfoList = UconvInfoList;
UconvInfoList = UconvInfoList->pNext;
} /* endwhile */
} /* endif */
if (!pConverter) {
nsUconvInfo* pnsUconvInfo;
pnsUconvInfo = (nsUconvInfo*)malloc(sizeof(nsUconvInfo));
pnsUconvInfo->mCodePage = CodePage;
UniChar codepage[20];
int unirc = ::UniMapCpToUcsCp( CodePage, codepage, 20);
if (unirc == ULS_SUCCESS) {
unirc = ::UniCreateUconvObject( codepage, &pnsUconvInfo->mConverter);
if (unirc == ULS_SUCCESS) {
::UniQueryUconvObject(pnsUconvInfo->mConverter, &attr, sizeof(uconv_attribute_t),
NULL, NULL, NULL);
attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
attr.subchar_len=1;
attr.subchar[0]='?';
::UniSetUconvObject(pnsUconvInfo->mConverter, &attr);
pConverter = &(pnsUconvInfo->mConverter);
pnsUconvInfo->pNext = NULL;
if (gUconvInfoList) {
prevUconvInfoList->pNext = pnsUconvInfo;
} else {
gUconvInfoList = pnsUconvInfo;
}
}
}
}
}
/* We didn't get a converter, just use default */
if (!pConverter) {
if (gUconvInfoList)
pConverter = &(gUconvInfoList->mConverter);
} /* endif */
UconvObject Converter = OS2Uni::GetUconvObject(CodePage);
UniChar *ucsString = (UniChar*) pText;
size_t ucsLen = ulLength;
@ -224,7 +172,7 @@ int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, c
char *tmp = szBuffer; // function alters the out pointer
int unirc = ::UniUconvFromUcs( *pConverter, &ucsString, &ucsLen,
int unirc = ::UniUconvFromUcs( Converter, &ucsString, &ucsLen,
(void**) &tmp, &cplen, &cSubs);
if( unirc != ULS_SUCCESS )
@ -241,59 +189,7 @@ int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, c
int MultiByteToWideChar( int CodePage, const char*pText, ULONG ulLength, PRUnichar *szBuffer, ULONG ulSize )
{
UconvObject* pConverter = 0;
uconv_attribute_t attr;
/* Short circuit most common case */
if ((gUconvInfoList) && (gUconvInfoList->mCodePage == CodePage)) {
pConverter = &(gUconvInfoList->mConverter);
} else {
nsUconvInfo* UconvInfoList;
nsUconvInfo* prevUconvInfoList;
if (gUconvInfoList) {
UconvInfoList = gUconvInfoList;
while (UconvInfoList) {
if (UconvInfoList->mCodePage == CodePage) {
pConverter = &(UconvInfoList->mConverter);
break;
}
prevUconvInfoList = UconvInfoList;
UconvInfoList = UconvInfoList->pNext;
} /* endwhile */
} /* endif */
if (!pConverter) {
nsUconvInfo* pnsUconvInfo;
pnsUconvInfo = (nsUconvInfo*)malloc(sizeof(nsUconvInfo));
pnsUconvInfo->mCodePage = CodePage;
UniChar codepage[20];
int unirc = ::UniMapCpToUcsCp( CodePage, codepage, 20);
if (unirc == ULS_SUCCESS) {
unirc = ::UniCreateUconvObject( codepage, &pnsUconvInfo->mConverter);
if (unirc == ULS_SUCCESS) {
::UniQueryUconvObject(pnsUconvInfo->mConverter, &attr, sizeof(uconv_attribute_t),
NULL, NULL, NULL);
attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
attr.subchar_len=1;
attr.subchar[0]='?';
::UniSetUconvObject(pnsUconvInfo->mConverter, &attr);
pConverter = &(pnsUconvInfo->mConverter);
pnsUconvInfo->pNext = NULL;
if (gUconvInfoList) {
prevUconvInfoList->pNext = pnsUconvInfo;
} else {
gUconvInfoList = pnsUconvInfo;
}
}
}
}
}
/* We didn't get a converter, just use default */
if (!pConverter) {
if (gUconvInfoList)
pConverter = &(gUconvInfoList->mConverter);
} /* endif */
UconvObject Converter = OS2Uni::GetUconvObject(CodePage);
char *ucsString = (char*) pText;
size_t ucsLen = ulLength;
@ -302,7 +198,7 @@ int MultiByteToWideChar( int CodePage, const char*pText, ULONG ulLength, PRUnich
PRUnichar *tmp = szBuffer; // function alters the out pointer
int unirc = ::UniUconvToUcs( *pConverter, (void**)&ucsString, &ucsLen,
int unirc = ::UniUconvToUcs( Converter, (void**)&ucsString, &ucsLen,
NS_REINTERPRET_CAST(UniChar**, &tmp),
&cplen, &cSubs);
@ -318,3 +214,44 @@ int MultiByteToWideChar( int CodePage, const char*pText, ULONG ulLength, PRUnich
return ulSize - cplen;
}
nsHashtable OS2Uni::gUconvObjects;
UconvObject
OS2Uni::GetUconvObject(int CodePage)
{
nsPRUint32Key key(CodePage);
UconvObject uco = OS2Uni::gUconvObjects.Get(&key);
if (!uco) {
UniChar codepage[20];
int unirc = ::UniMapCpToUcsCp(CodePage, codepage, 20);
if (unirc == ULS_SUCCESS) {
unirc = ::UniCreateUconvObject(codepage, &uco);
if (unirc == ULS_SUCCESS) {
uconv_attribute_t attr;
::UniQueryUconvObject(uco, &attr, sizeof(uconv_attribute_t),
NULL, NULL, NULL);
attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
attr.subchar_len=1;
attr.subchar[0]='?';
::UniSetUconvObject(uco, &attr);
OS2Uni::gUconvObjects.Put(&key, uco);
}
}
}
return uco;
}
PR_STATIC_CALLBACK(PRIntn)
UconvObjectEnum(nsHashKey* hashKey, void *aData, void* closure)
{
UniFreeUconvObject((UconvObject)aData);
return kHashEnumerateRemove;
}
OS2Uni::FreeUconvObjects()
{
if (gUconvObjects.Count()) {
gUconvObjects.Enumerate(UconvObjectEnum, nsnull);
}
}

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

@ -32,6 +32,7 @@
#define INCL_DEV
#include <os2.h>
#include "prlog.h"
#include "nsHashtable.h"
#include <uconv.h> // XXX hack XXX
@ -72,17 +73,7 @@ void PMERROR(const char *str);
class nsString;
class nsIDeviceContext;
struct nsUconvInfo
{
PRUint16 mCodePage;
UconvObject mConverter;
nsUconvInfo* pNext;
};
static nsUconvInfo* gUconvInfoList = NULL;
int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize );
int MultiByteToWideChar( int CodePage, const char*pText, ULONG ulLength, PRUnichar *szBuffer, ULONG ulSize );
BOOL GetTextExtentPoint32(HPS aPS, const char* aString, int aLength, PSIZEL aSizeL);
BOOL ExtTextOut(HPS aPS, int X, int Y, UINT fuOptions, const RECTL* lprc,
const char* aString, unsigned int aLength, const int* pDx);
@ -99,4 +90,15 @@ BOOL IsDBCS();
extern PRLogModuleInfo *gGFXOS2LogModule;
#endif
class OS2Uni {
public:
static UconvObject GetUconvObject(int CodePage);
static FreeUconvObjects();
private:
static nsHashtable gUconvObjects;
};
int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize );
int MultiByteToWideChar( int CodePage, const char*pText, ULONG ulLength, PRUnichar *szBuffer, ULONG ulSize );
#endif

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

@ -196,6 +196,7 @@ static const nsModuleComponentInfo components[] =
PR_STATIC_CALLBACK(void)
nsGfxOS2ModuleDtor(nsIModule *self)
{
OS2Uni::FreeUconvObjects();
// nsRenderingContextOS2::Shutdown();
}