1 /* 2 * Copyright 2010-2011, Oliver Tappe, zooey@hirschkaefer.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _LOCALE_BACKEND_H 6 #define _LOCALE_BACKEND_H 7 8 9 #include <SupportDefs.h> 10 11 #include <locale.h> 12 #include <time.h> 13 #include <wctype.h> 14 15 16 struct lc_time_t; 17 struct locale_data; // glibc 18 19 20 namespace BPrivate { 21 namespace Libroot { 22 23 24 struct LocaleCtypeDataBridge { 25 private: 26 const unsigned short* localClassInfoTable; 27 const int* localToLowerTable; 28 const int* localToUpperTable; 29 30 public: 31 const unsigned short** addrOfClassInfoTable; 32 const int** addrOfToLowerTable; 33 const int** addrOfToUpperTable; 34 35 const unsigned short* const posixClassInfo; 36 const int* const posixToLowerMap; 37 const int* const posixToUpperMap; 38 39 bool isGlobal; 40 41 LocaleCtypeDataBridge(bool isGlobal); 42 43 void setMbCurMax(unsigned short mbCurMax); 44 void ApplyToCurrentThread(); 45 }; 46 47 48 struct LocaleMessagesDataBridge { 49 const char** const posixLanginfo; 50 51 LocaleMessagesDataBridge(); 52 }; 53 54 55 struct LocaleMonetaryDataBridge { 56 const struct lconv* const posixLocaleConv; 57 58 LocaleMonetaryDataBridge(); 59 }; 60 61 62 struct LocaleNumericDataBridge { 63 private: 64 // struct used by glibc to store numeric locale data 65 struct GlibcNumericLocale { 66 const char* name; 67 const char* filedata; 68 off_t filesize; 69 int mmaped; 70 unsigned int usage_count; 71 int use_translit; 72 const char *options; 73 unsigned int nstrings; 74 union locale_data_value 75 { 76 const uint32_t* wstr; 77 const char* string; 78 unsigned int word; 79 } 80 values[6]; 81 }; 82 locale_data* originalGlibcLocale; 83 GlibcNumericLocale glibcNumericLocaleData; 84 85 public: 86 const struct lconv* const posixLocaleConv; 87 GlibcNumericLocale* glibcNumericLocale; 88 bool isGlobal; 89 90 LocaleNumericDataBridge(bool isGlobal); 91 ~LocaleNumericDataBridge(); 92 93 void ApplyToCurrentThread(); 94 }; 95 96 97 struct LocaleTimeDataBridge { 98 const struct lc_time_t* const posixLCTimeInfo; 99 100 LocaleTimeDataBridge(); 101 }; 102 103 104 struct TimeConversionDataBridge { 105 static const int32 kTZNameLength = 64; 106 107 private: 108 int localDaylight; 109 long localTimezone; 110 char* localTZName[2]; 111 char localTZName0[kTZNameLength]; 112 char localTZName1[kTZNameLength]; 113 114 public: 115 int* addrOfDaylight; 116 long* addrOfTimezone; 117 char** addrOfTZName; 118 bool isGlobal; 119 120 TimeConversionDataBridge(bool isGlobal); 121 }; 122 123 124 struct LocaleDataBridge { 125 LocaleCtypeDataBridge ctypeDataBridge; 126 LocaleMessagesDataBridge messagesDataBridge; 127 LocaleMonetaryDataBridge monetaryDataBridge; 128 LocaleNumericDataBridge numericDataBridge; 129 LocaleTimeDataBridge timeDataBridge; 130 TimeConversionDataBridge timeConversionDataBridge; 131 const char** const posixLanginfo; 132 bool isGlobal; 133 134 LocaleDataBridge(bool isGlobal); 135 136 void ApplyToCurrentThread(); 137 }; 138 139 140 class LocaleBackend { 141 public: 142 LocaleBackend(); 143 virtual ~LocaleBackend(); 144 145 virtual const char* SetLocale(int category, const char* locale) = 0; 146 virtual const struct lconv* LocaleConv() = 0; 147 virtual const struct lc_time_t* LCTimeInfo() = 0; 148 149 virtual int IsWCType(wint_t wc, wctype_t charClass) = 0; 150 virtual status_t ToWCTrans(wint_t wc, wctrans_t transition, 151 wint_t& result) = 0; 152 153 virtual status_t MultibyteToWchar(wchar_t* wcOut, const char* mb, 154 size_t mbLength, mbstate_t* mbState, 155 size_t& lengthOut) = 0; 156 virtual status_t MultibyteStringToWchar(wchar_t* wcDest, 157 size_t wcDestLength, const char** mbSource, 158 size_t mbSourceLength, mbstate_t* mbState, 159 size_t& lengthOut) = 0; 160 virtual status_t WcharToMultibyte(char* mbOut, wchar_t wc, 161 mbstate_t* mbState, size_t& lengthOut) = 0; 162 virtual status_t WcharStringToMultibyte(char* mbDest, 163 size_t mbDestLength, 164 const wchar_t** wcSource, 165 size_t wcSourceLength, mbstate_t* mbState, 166 size_t& lengthOut) = 0; 167 168 virtual const char* GetLanginfo(int index) = 0; 169 170 virtual status_t Strcoll(const char* a, const char* b, 171 int& out) = 0; 172 virtual status_t Strxfrm(char* out, const char* in, 173 size_t outSize, size_t& requiredSize) = 0; 174 virtual status_t Wcscoll(const wchar_t* a, const wchar_t* b, 175 int& out) = 0; 176 virtual status_t Wcsxfrm(wchar_t* out, const wchar_t* in, 177 size_t outSize, size_t& requiredSize) = 0; 178 179 virtual status_t TZSet(const char* timeZoneID, 180 const char* tz) = 0; 181 virtual status_t Localtime(const time_t* inTime, 182 struct tm* tmOut) = 0; 183 virtual status_t Gmtime(const time_t* inTime, 184 struct tm* tmOut) = 0; 185 virtual status_t Mktime(struct tm* inOutTm, time_t& timeOut) = 0; 186 187 virtual status_t Timegm(struct tm* inOutTm, time_t& timeOut) = 0; 188 189 virtual void Initialize(LocaleDataBridge* dataBridge) = 0; 190 191 static status_t LoadBackend(); 192 static status_t CreateBackend(LocaleBackend*& backendOut); 193 static void DestroyBackend(LocaleBackend* instance); 194 }; 195 196 197 // The real struct behind locale_t 198 struct LocaleBackendData { 199 int magic; 200 LocaleBackend* backend; 201 LocaleDataBridge* databridge; 202 }; 203 204 205 LocaleBackendData* GetCurrentLocaleInfo(); 206 void SetCurrentLocaleInfo(LocaleBackendData* newLocale); 207 LocaleBackend* GetCurrentLocaleBackend(); 208 extern LocaleBackend* gGlobalLocaleBackend; 209 extern LocaleDataBridge gGlobalLocaleDataBridge; 210 211 } // namespace Libroot 212 } // namespace BPrivate 213 214 215 #endif // _LOCALE_BACKEND_H 216