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 private: 106 int localDaylight; 107 long localTimezone; 108 char* localTZName[2]; 109 char localTZName0[64]; 110 char localTZName1[64]; 111 112 public: 113 int* addrOfDaylight; 114 long* addrOfTimezone; 115 char** addrOfTZName; 116 bool isGlobal; 117 118 TimeConversionDataBridge(bool isGlobal); 119 }; 120 121 122 struct LocaleDataBridge { 123 LocaleCtypeDataBridge ctypeDataBridge; 124 LocaleMessagesDataBridge messagesDataBridge; 125 LocaleMonetaryDataBridge monetaryDataBridge; 126 LocaleNumericDataBridge numericDataBridge; 127 LocaleTimeDataBridge timeDataBridge; 128 TimeConversionDataBridge timeConversionDataBridge; 129 const char** const posixLanginfo; 130 bool isGlobal; 131 132 LocaleDataBridge(bool isGlobal); 133 134 void ApplyToCurrentThread(); 135 }; 136 137 138 class LocaleBackend { 139 public: 140 LocaleBackend(); 141 virtual ~LocaleBackend(); 142 143 virtual const char* SetLocale(int category, const char* locale) = 0; 144 virtual const struct lconv* LocaleConv() = 0; 145 virtual const struct lc_time_t* LCTimeInfo() = 0; 146 147 virtual int IsWCType(wint_t wc, wctype_t charClass) = 0; 148 virtual status_t ToWCTrans(wint_t wc, wctrans_t transition, 149 wint_t& result) = 0; 150 151 virtual status_t MultibyteToWchar(wchar_t* wcOut, const char* mb, 152 size_t mbLength, mbstate_t* mbState, 153 size_t& lengthOut) = 0; 154 virtual status_t MultibyteStringToWchar(wchar_t* wcDest, 155 size_t wcDestLength, const char** mbSource, 156 size_t mbSourceLength, mbstate_t* mbState, 157 size_t& lengthOut) = 0; 158 virtual status_t WcharToMultibyte(char* mbOut, wchar_t wc, 159 mbstate_t* mbState, size_t& lengthOut) = 0; 160 virtual status_t WcharStringToMultibyte(char* mbDest, 161 size_t mbDestLength, 162 const wchar_t** wcSource, 163 size_t wcSourceLength, mbstate_t* mbState, 164 size_t& lengthOut) = 0; 165 166 virtual const char* GetLanginfo(int index) = 0; 167 168 virtual status_t Strcoll(const char* a, const char* b, 169 int& out) = 0; 170 virtual status_t Strxfrm(char* out, const char* in, size_t size, 171 size_t& outSize) = 0; 172 virtual status_t Wcscoll(const wchar_t* a, const wchar_t* b, 173 int& out) = 0; 174 virtual status_t Wcsxfrm(wchar_t* out, const wchar_t* in, 175 size_t outSize, size_t& requiredSize) = 0; 176 177 virtual status_t TZSet(const char* timeZoneID, 178 const char* tz) = 0; 179 virtual status_t Localtime(const time_t* inTime, 180 struct tm* tmOut) = 0; 181 virtual status_t Gmtime(const time_t* inTime, 182 struct tm* tmOut) = 0; 183 virtual status_t Mktime(struct tm* inOutTm, time_t& timeOut) = 0; 184 185 virtual status_t Timegm(struct tm* inOutTm, time_t& timeOut) = 0; 186 187 virtual void Initialize(LocaleDataBridge* dataBridge) = 0; 188 189 static status_t LoadBackend(); 190 static status_t CreateBackend(LocaleBackend*& backendOut); 191 static void DestroyBackend(LocaleBackend* instance); 192 }; 193 194 195 // The real struct behind locale_t 196 struct LocaleBackendData { 197 int magic; 198 LocaleBackend* backend; 199 LocaleDataBridge* databridge; 200 }; 201 202 203 LocaleBackendData* GetCurrentLocaleInfo(); 204 void SetCurrentLocaleInfo(LocaleBackendData* newLocale); 205 LocaleBackend* GetCurrentLocaleBackend(); 206 extern LocaleBackend* gGlobalLocaleBackend; 207 extern LocaleDataBridge gGlobalLocaleDataBridge; 208 209 } // namespace Libroot 210 } // namespace BPrivate 211 212 213 #endif // _LOCALE_BACKEND_H 214