(file) Return to intlstr.c CVS log (file) (dir) Up to [OMI] / omi / pal

  1 krisbash 1.1 /*
  2              **==============================================================================
  3              **
  4              ** Open Management Infrastructure (OMI)
  5              **
  6              ** Copyright (c) Microsoft Corporation
  7              ** 
  8              ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9              ** use this file except in compliance with the License. You may obtain a copy 
 10              ** of the License at 
 11              **
 12              **     http://www.apache.org/licenses/LICENSE-2.0 
 13              **
 14              ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15              ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16              ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17              ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18              **
 19              ** See the Apache 2 License for the specific language governing permissions 
 20              ** and limitations under the License.
 21              **
 22 krisbash 1.1 **==============================================================================
 23              */
 24              
 25              #include "intlstr.h"
 26              
 27              #include <assert.h>
 28              
 29              #if defined(_MSC_VER)
 30              
 31                  #include <windows.h>
 32              
 33                  _Use_decl_annotations_
 34                  const PAL_Char* _Intlstr_GetString_LoadString(HINSTANCE hInstance, UINT uID)
 35                  {
 36                      int err;
 37                      LPTSTR lpBuffer;
 38              
 39                      err = LoadString(hInstance, uID, (LPTSTR)&lpBuffer, 0);
 40                      if (err == 0)
 41                      {
 42                          /* TODO/FIXME - OI diagnostics */
 43 krisbash 1.1             return NULL;
 44                      }
 45              
 46                      return lpBuffer;
 47                  }
 48              
 49                  _Use_decl_annotations_
 50                  PAL_Char* _Intlstr_FormatString_FormatMessage(HINSTANCE hInstance, UINT uID, ...)
 51                  {
 52                      DWORD result;
 53                      int err;
 54                      LPTSTR lpTemplate;
 55                      LPTSTR lpFormattedString;
 56                      va_list ap; 
 57              
 58                      err = LoadString(hInstance, uID, (LPTSTR)&lpTemplate, 0);
 59                      if (err == 0)
 60                      {
 61                          /* TODO/FIXME - OI diagnostics */
 62                          return NULL;
 63                      }
 64 krisbash 1.1 
 65                      va_start(ap, uID); 
 66                      result = FormatMessage(
 67                          /* TODO/FIXME - FORMAT_MESSAGE_FROM_HMODULE can in theory help avoid the LoadString above, but I couldn't get it to work... */
 68                          FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, 
 69                          lpTemplate, 
 70                          0, /* dwMessageId;  ignored when FORMAT_MESSAGE_FROM_STRING is used */
 71                          0, /* dwLanguageId; ignored when FORMAT_MESSAGE_FROM_STRING is used */
 72                          (LPTSTR)&lpFormattedString,
 73                          0, /* nSize - maximum size of buffer to allocate;  0 means no limit */
 74                          &ap);
 75                      va_end(ap); 
 76                      if (result == 0)
 77                      {
 78                          /* TODO/FIXME - OI diagnostics */
 79                          return NULL;
 80                      }
 81              
 82                      return lpFormattedString;
 83                  }
 84              
 85 krisbash 1.1 #else /* !defined(_MSC_VER) */
 86              
 87                  #include <pal/format.h>
 88                  #include <pal/strings.h>
 89              
 90                  #if defined(CONFIG_ENABLE_GETTEXT)
 91              
 92                  #include <libintl.h>
 93                  #include <stdarg.h>
 94                  #include <pal/hashmap.h>
 95                  #include <pal/once.h>
 96                  #include <pal/lock.h>
 97              
 98                      #if defined(CONFIG_ENABLE_WCHAR)
 99              
100                          typedef struct _IntlstrBucket {
101                              HashBucket      bucket;
102                              int id;
103                              const char* domain_name;
104                              PAL_Char text[1];
105                          } IntlstrBucket;
106 krisbash 1.1 
107                          static size_t Intlstr_HashMapHashProc(const HashBucket* untypedBucket)
108                          {
109                              IntlstrBucket* bucket = (IntlstrBucket*)untypedBucket;
110                              return (size_t)bucket->id ^ HashMap_HashProc_AnsiString(bucket->domain_name);
111                          }
112              
113                          static int Intlstr_HashMapEqualProc(_In_ const HashBucket* untypedBucket1, _In_ const HashBucket* untypedBucket2)
114                          {
115                              IntlstrBucket* bucket1 = (IntlstrBucket*)untypedBucket1;
116                              IntlstrBucket* bucket2 = (IntlstrBucket*)untypedBucket2;
117                              return (bucket1->id == bucket2->id) &&
118                                  (0 == strcmp(bucket1->domain_name, bucket2->domain_name));
119                          }
120              
121                          static void Intlstr_HashMapReleaseProc(_In_ HashBucket* untypedBucket)
122                          {
123                              PAL_UNUSED(untypedBucket);
124                          }
125              
126                          static Once g_intlStr_once = ONCE_INITIALIZER;
127 krisbash 1.1             static HashMap g_intlStr_hashmap;
128                          static ReadWriteLock g_intlStr_lock;
129              
130                          static void ATEXIT_API _Intlstr_OnceCleanup(void)
131                          {
132                              HashMap_Destroy(&g_intlStr_hashmap);
133                          }
134              
135                          _Success_(return == 0) int _Intlstr_OnceInit(void* data, _Outptr_result_maybenull_ void** value)
136                          {
137                              int result = 0;
138              
139                              *value = NULL;
140              
141                              ReadWriteLock_Init(&g_intlStr_lock);
142              
143                              result = HashMap_Init(
144                                  &g_intlStr_hashmap, 
145                                  32, /* initial number of buckets */
146                                  Intlstr_HashMapHashProc,
147                                  Intlstr_HashMapEqualProc,
148 krisbash 1.1                     Intlstr_HashMapReleaseProc);
149              
150                              if (result == 0)
151                              {
152                                  result = PAL_Atexit(_Intlstr_OnceCleanup);
153                              }
154              
155                              return result;
156                          }
157              
158                      #endif /* ?defined(CONFIG_ENABLE_WCHAR) */
159              
160                      _Use_decl_annotations_
161                      const PAL_Char* _Intlstr_GetString_GetText(const char* domain_name, int id, const char* msgid)
162                      {
163                      #if defined(CONFIG_ENABLE_WCHAR)
164                          IntlstrBucket* bucket;
165              
166                          if (0 != Once_Invoke(&g_intlStr_once, _Intlstr_OnceInit, NULL))
167                          {
168                              /* TODO/FIXME - OI diagnostics */
169 krisbash 1.1                 return NULL;
170                          }
171              
172                          {
173                              IntlstrBucket referenceBucket;
174                              referenceBucket.id = id;
175                              referenceBucket.domain_name = domain_name;
176                              ReadWriteLock_AcquireRead(&g_intlStr_lock);
177                              bucket = (IntlstrBucket*) HashMap_Find(&g_intlStr_hashmap, (HashBucket*) &referenceBucket);
178                              ReadWriteLock_ReleaseRead(&g_intlStr_lock);
179                          }
180              
181                          if (bucket == NULL)
182                          {
183                              size_t wcharCount;
184                              size_t copiedCount;
185                              int insertResult;
186              
187                              char* localizedString = dgettext(domain_name, msgid);
188                              if (localizedString == NULL)
189                              {
190 krisbash 1.1                     /* TODO/FIXME - OI diagnostics */
191                                  return NULL;
192                              }
193              
194                              wcharCount = mbstowcs(NULL, localizedString, 0);
195                              if (wcharCount == ((size_t)-1))
196                              {
197                                  /* TODO/FIXME - OI diagnostics */
198                                  return NULL;
199                              }
200                              if ((((size_t)(-1)) - sizeof(IntlstrBucket) / 2) < wcharCount)
201                              {
202                                  /* TODO/FIXME - OI diagnostics */
203                                  return NULL;
204                              }
205              
206                              bucket = (IntlstrBucket*) PAL_Malloc(sizeof(IntlstrBucket) + sizeof(wchar_t) * wcharCount);
207                              if (!bucket)
208                              {
209                                  /* TODO/FIXME - OI diagnostics */
210                                  return NULL;
211 krisbash 1.1                 }
212                              bucket->id = id;
213                              bucket->domain_name = domain_name;
214              
215                              copiedCount = mbstowcs(bucket->text, localizedString, wcharCount + 1);
216                              assert(copiedCount == wcharCount);
217              
218                              ReadWriteLock_AcquireWrite(&g_intlStr_lock);
219                              insertResult = HashMap_Insert(&g_intlStr_hashmap, (HashBucket*) bucket);
220                              if (insertResult == 1) /* already exists? => use the old one / discard the new one */
221                              {
222                                  IntlstrBucket* oldBucket = (IntlstrBucket*) HashMap_Find(&g_intlStr_hashmap, (HashBucket*) bucket);
223                                  assert(oldBucket != NULL);
224                                  PAL_Free(bucket);
225                                  bucket = oldBucket;
226                              }
227                              ReadWriteLock_ReleaseWrite(&g_intlStr_lock);
228                          }
229              
230                          return bucket->text;
231                      #else /* !defined(CONFIG_ENABLE_WCHAR) */
232 krisbash 1.1             char* localizedString;
233                          
234                          PAL_UNUSED(id);
235              
236                          localizedString = dgettext(domain_name, msgid);
237                          if (localizedString == NULL)
238                          {
239                              /* TODO/FIXME - OI diagnostics */
240                              return NULL;
241                          }
242              
243                          return localizedString;
244                      #endif /* ?defined(CONFIG_ENABLE_WCHAR) */
245                      }
246              
247                      PAL_Char* _Intlstr_FormatString_gettext_and_snprintf(const char* domain_name, int id, const char* msgid, ...)
248                      {
249                          PAL_Char* templateString = NULL;
250                          PAL_Char* resultString = NULL;
251                          va_list ap; 
252              
253 krisbash 1.1             va_start(ap, msgid); 
254              
255                          templateString = _Intlstr_GetString_GetText(domain_name, id, msgid);
256                          if (!templateString)
257                          {
258                              /* TODO/FIXME - OI diagnostics */
259                              goto CleanUp;
260                          }
261              
262                          resultString = Vstprintf_StrDup(templateString, ap);
263                          if (!resultString)
264                          {
265                              /* TODO/FIXME - OI diagnostics */
266                              goto CleanUp;
267                          }
268              
269                      CleanUp:
270                          va_end(ap); 
271                          return resultString;
272                      }
273              
274 krisbash 1.1     #endif /* ?defined(CONFIG_ENABLE_GETTEXT) */
275              
276              #endif /* ?defined(_MSC_VER) */

ViewCVS 0.9.2