Adjust mbstate_t to embed the state of the ICU converter.

* make room in mbstate_t for containing an ICU-converter's state
  (well, in fact the whole converter object)
* adjust libroot's locale add-on to clone converters into a given
  mbstate_t directly
* adjust ICUThreadLocalStorageValue to contain the converter pointer
  instead of a converter-ID (if the converter is related to an
  mbstate_t, it points into the mbstate_t).
* adjust users of converters to directly use converter pointers
  instead of ICUConverterRef
* drop now unused ICUConverterManager and ICUConverterRef
* update gcc4 optional package

This brings our multibyte implementation into a fully working state,
both non-ascii and non-8-bit characters can now be handled normally
in the Terminal, i.e. this finally fixes #6276.

N.B.: Since the size of mbstate_t has changed, everything (including
the compiler!) needs to be rebuilt.
This commit is contained in:
Oliver Tappe
2011-12-15 13:18:11 +01:00
parent 8726c67f5e
commit ec99f3b2a6
11 changed files with 141 additions and 223 deletions
+3 -1
View File
@@ -27,8 +27,10 @@ typedef __WINT_TYPE__ wint_t;
typedef int wctype_t;
typedef struct {
void* converter;
char charset[64];
unsigned int count;
unsigned int converterID;
char data[1024 + 8]; // 1024 bytes for data, 8 for alignment space
} mbstate_t;
@@ -8,12 +8,11 @@
#include <pthread.h>
#include <unicode/locid.h>
#include <unicode/ucnv.h>
#include <unicode/unistr.h>
#include <SupportDefs.h>
#include "ICUConverterManager.h"
#include "ICUThreadLocalStorageValue.h"
namespace BPrivate {
@@ -38,7 +37,7 @@ protected:
char* destination, int destinationSize,
const char* defaultValue = "");
status_t _GetConverter(ICUConverterRef& converterRefOut);
status_t _GetConverter(UConverter*& converterOut);
static const uint16 skMaxPosixLocaleNameLen = 128;
static const size_t skLCBufSize = 16;
@@ -1,106 +0,0 @@
/*
* Copyright 2011, Oliver Tappe, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _ICU_CONVERTER_MANAGER_H
#define _ICU_CONVERTER_MANAGER_H
#include <pthread.h>
#include <map>
#include <unicode/ucnv.h>
#include <SupportDefs.h>
#include <locks.h>
#include <Referenceable.h>
#include <util/DoublyLinkedList.h>
//#include <util/OpenHashTable.h>
#include "ICUThreadLocalStorageValue.h"
namespace BPrivate {
namespace Libroot {
class ICUConverterInfo : public BReferenceable {
public:
ICUConverterInfo(UConverter* converter,
const char* charset, ICUConverterID id);
virtual ~ICUConverterInfo();
UConverter* Converter() const
{ return fConverter; }
const char* Charset() const
{ return fCharset; }
ICUConverterID ID() const
{ return fID; }
private:
UConverter* fConverter;
char fCharset[UCNV_MAX_CONVERTER_NAME_LENGTH];
ICUConverterID fID;
};
typedef BReference<ICUConverterInfo> ICUConverterRef;
class ICUConverterManager {
public:
ICUConverterManager();
~ICUConverterManager();
status_t CreateConverter(const char* charset,
ICUConverterRef& converterRefOut,
ICUConverterID& idOut);
status_t GetConverter(ICUConverterID id,
ICUConverterRef& converterRefOut);
status_t DropConverter(ICUConverterID id);
static ICUConverterManager* Instance();
private:
static void _CreateInstance();
static ICUConverterManager* sInstance;
static const size_t skMaxConvertersPerProcess = 1024;
private:
class LinkedConverterInfo
:
public ICUConverterInfo,
public DoublyLinkedListLinkImpl<LinkedConverterInfo>
{
public:
LinkedConverterInfo(UConverter* converter, const char* charset,
ICUConverterID id)
:
ICUConverterInfo(converter, charset, id)
{
}
};
typedef std::map<ICUConverterID, LinkedConverterInfo*> ConverterMap;
typedef DoublyLinkedList<LinkedConverterInfo> ConverterList;
private:
ConverterMap fConverterMap;
ConverterList fLRUConverters;
mutex fMutex;
ICUConverterID fNextConverterID;
};
} // namespace Libroot
} // namespace BPrivate
#endif // _ICU_CONVERTER_MANAGER_H
@@ -49,7 +49,7 @@ public:
private:
status_t _GetConverterForMbState(mbstate_t* mbState,
ICUConverterRef& converterRefOut);
UConverter*& converterOut);
status_t _DropConverterFromMbState(mbstate_t* mbState);
@@ -8,6 +8,8 @@
#include <pthread.h>
#include <unicode/ucnv.h>
#include <SupportDefs.h>
@@ -15,11 +17,9 @@ namespace BPrivate {
namespace Libroot {
typedef unsigned int ICUConverterID;
struct ICUThreadLocalStorageValue {
ICUConverterID converterID;
UConverter* converter;
char charset[64];
ICUThreadLocalStorageValue();
~ICUThreadLocalStorageValue();