LCOV - code coverage report
Current view: top level - sal/rtl - locale.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 107 139 77.0 %
Date: 2014-11-03 Functions: 16 17 94.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "rtl/locale.h"
      21             : 
      22             : #include "osl/diagnose.h"
      23             : #include "rtl/alloc.h"
      24             : 
      25             : #include "internal/rtllifecycle.h"
      26             : 
      27             : static const sal_Int32 RTL_HASHTABLE_SIZE[] =
      28             : {
      29             :     7, 31, 127, 251, 509, 1021, 2039, 4093
      30             : };
      31             : 
      32             : struct RTL_HASHENTRY
      33             : {
      34             :     rtl_Locale* Entry;
      35             :     RTL_HASHENTRY* Next;
      36             : };
      37             : 
      38             : struct RTL_HASHTABLE
      39             : {
      40             :     sal_Int8        iSize;
      41             :     sal_Int32       Size;
      42             :     sal_Int32       Elements;
      43             :     RTL_HASHENTRY** Table;
      44             : };
      45             : 
      46             : static RTL_HASHTABLE* g_pLocaleTable = NULL;
      47             : 
      48             : static rtl_Locale* g_pDefaultLocale = NULL;
      49             : 
      50             : /*************************************************************************
      51             :  */
      52        2841 : extern "C" void rtl_hashentry_destroy(RTL_HASHENTRY* entry)
      53             : {
      54        2841 :     rtl_uString_release(entry->Entry->Language);
      55        2841 :     rtl_uString_release(entry->Entry->Country);
      56        2841 :     rtl_uString_release(entry->Entry->Variant);
      57        2841 :     if (entry->Next)
      58           0 :         rtl_hashentry_destroy(entry->Next);
      59             : 
      60        2841 :     rtl_freeMemory(entry->Entry);
      61        2841 :     rtl_freeMemory(entry);
      62        2841 : }
      63             : 
      64        2837 : extern "C" void rtl_hashtable_destroy(RTL_HASHTABLE* table)
      65             : {
      66        2837 :     sal_Int32 size = 0;
      67             : 
      68        2837 :     if (!table)
      69        2837 :         return;
      70             : 
      71        2837 :     size = table->Size;
      72             : 
      73       93621 :     while (size)
      74             :     {
      75       87947 :         if (table->Table[size - 1])
      76        2841 :             rtl_hashentry_destroy(table->Table[size - 1]);
      77       87947 :         size--;
      78             :     }
      79             : 
      80        2837 :     rtl_freeMemory(table->Table);
      81        2837 :     rtl_freeMemory(table);
      82             : }
      83             : 
      84        2837 : extern "C" void rtl_hashtable_init(RTL_HASHTABLE** table, sal_Int8 sizeIndex)
      85             : {
      86        2837 :     sal_Int32 nSize = RTL_HASHTABLE_SIZE[sizeIndex];
      87             : 
      88        2837 :     if (*table)
      89           0 :         rtl_hashtable_destroy(*table);
      90             : 
      91        2837 :     *table = (RTL_HASHTABLE*)rtl_allocateMemory( sizeof(RTL_HASHTABLE) );
      92             : 
      93        2837 :     (*table)->iSize = sizeIndex;
      94        2837 :     (*table)->Size = nSize;
      95        2837 :     (*table)->Elements = 0;
      96        2837 :     (*table)->Table = (RTL_HASHENTRY**)rtl_allocateMemory( (*table)->Size * sizeof(RTL_HASHENTRY*) );
      97             : 
      98       93621 :     while (nSize)
      99             :     {
     100       87947 :         (*table)->Table[nSize - 1] = NULL;
     101       87947 :         nSize--;
     102             :     }
     103        2837 : }
     104             : 
     105        5714 : extern "C" sal_Int32 rtl_hashfunc(RTL_HASHTABLE* table, sal_Int32 key)
     106             : {
     107        5714 :     return ( (sal_uInt32) key % table->Size);
     108             : }
     109             : 
     110             : extern "C" sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table);
     111             : 
     112        2841 : extern "C" rtl_Locale* rtl_hashtable_add(RTL_HASHTABLE** table, rtl_Locale* value)
     113             : {
     114        2841 :     sal_Int32 key = 0;
     115             : 
     116        2841 :     if (!(*table))
     117           0 :         return NULL;
     118             : 
     119        2841 :     if ((*table)->Elements > ((*table)->Size / 2))
     120           0 :         rtl_hashtable_grow(table);
     121             : 
     122        2841 :     key = rtl_hashfunc(*table, value->HashCode);
     123             : 
     124        2841 :     RTL_HASHENTRY **pEntry = &(*table)->Table[key];
     125        5682 :     while (*pEntry)
     126             :     {
     127           0 :         if (value->HashCode == (*pEntry)->Entry->HashCode)
     128           0 :             return (*pEntry)->Entry;
     129           0 :         pEntry = &(*pEntry)->Next;
     130             :     }
     131             : 
     132        2841 :     RTL_HASHENTRY *newEntry = (RTL_HASHENTRY*)rtl_allocateMemory( sizeof(RTL_HASHENTRY) );
     133        2841 :     newEntry->Entry = value;
     134        2841 :     newEntry->Next = NULL;
     135        2841 :     *pEntry = newEntry;
     136        2841 :     (*table)->Elements++;
     137        2841 :     return NULL;
     138             : }
     139             : 
     140           0 : sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table)
     141             : {
     142           0 :     RTL_HASHTABLE* pNewTable = NULL;
     143           0 :     sal_Int32 i = 0;
     144             : 
     145           0 :     rtl_hashtable_init(&pNewTable, (sal_Int8)((*table)->iSize + 1));
     146             : 
     147           0 :     while (i < (*table)->Size)
     148             :     {
     149           0 :         if ((*table)->Table[i])
     150             :         {
     151             :             RTL_HASHENTRY *pNext;
     152           0 :             RTL_HASHENTRY *pEntry = (*table)->Table[i];
     153             : 
     154           0 :             rtl_hashtable_add(&pNewTable, pEntry->Entry);
     155             : 
     156           0 :             while (pEntry->Next)
     157             :             {
     158           0 :                 rtl_hashtable_add(&pNewTable, pEntry->Next->Entry);
     159           0 :                 pNext = pEntry->Next;
     160           0 :                 rtl_freeMemory(pEntry);
     161           0 :                 pEntry = pNext;
     162             :             }
     163             : 
     164           0 :             rtl_freeMemory(pEntry);
     165             :         }
     166           0 :         i++;
     167             :     }
     168             : 
     169           0 :     rtl_freeMemory((*table)->Table);
     170           0 :     rtl_freeMemory((*table));
     171           0 :     (*table) = pNewTable;
     172             : 
     173           0 :     return sal_True;
     174             : }
     175             : 
     176        2873 : extern "C" sal_Bool rtl_hashtable_find(RTL_HASHTABLE * table, sal_Int32 key, sal_Int32 hashCode, rtl_Locale** pValue)
     177             : {
     178        2873 :     if (!table)
     179           0 :         return sal_False;
     180             : 
     181        2873 :     if (table->Table[key])
     182             :     {
     183          32 :         RTL_HASHENTRY *pEntry = table->Table[key];
     184             : 
     185          64 :         while (pEntry && hashCode != pEntry->Entry->HashCode)
     186           0 :             pEntry = pEntry->Next;
     187             : 
     188          32 :         if (pEntry)
     189          32 :             *pValue = pEntry->Entry;
     190             :         else
     191           0 :             return sal_False;
     192             :     } else
     193        2841 :         return sal_False;
     194             : 
     195          32 :     return sal_True;
     196             : }
     197             : 
     198             : /*************************************************************************
     199             :  *  rtl_locale_init
     200             :  */
     201        2837 : void rtl_locale_init()
     202             : {
     203             :   OSL_ASSERT(g_pLocaleTable == 0);
     204        2837 :   rtl_hashtable_init(&g_pLocaleTable, 1);
     205        2837 : }
     206             : 
     207             : /*************************************************************************
     208             :  *  rtl_locale_fini
     209             :  */
     210        2837 : void rtl_locale_fini()
     211             : {
     212        2837 :   if (g_pLocaleTable != 0)
     213             :   {
     214        2837 :     rtl_hashtable_destroy (g_pLocaleTable);
     215        2837 :     g_pLocaleTable = 0;
     216             :   }
     217        2837 : }
     218             : 
     219             : /*************************************************************************
     220             :  *  rtl_locale_register
     221             :  */
     222        2873 : rtl_Locale * SAL_CALL rtl_locale_register( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant )
     223             : {
     224        2873 :     sal_Unicode c = 0;
     225        2873 :     rtl_uString* sLanguage = NULL;
     226        2873 :     rtl_uString* sCountry = NULL;
     227        2873 :     rtl_uString* sVariant = NULL;
     228        2873 :     rtl_Locale *newLocale = NULL;
     229        2873 :     sal_Int32 hashCode = -1;
     230        2873 :     sal_Int32 key = 0;
     231             : 
     232        2873 :     if ( !country )
     233           0 :         country = &c;
     234        2873 :     if ( !variant )
     235           0 :         variant = &c;
     236             : 
     237        2873 :     ensureLocaleSingleton();
     238        2873 :     if (!g_pLocaleTable)
     239           0 :       return NULL;
     240             : 
     241        2873 :     hashCode = rtl_ustr_hashCode(language) ^ rtl_ustr_hashCode(country) ^ rtl_ustr_hashCode(variant);
     242        2873 :     key = rtl_hashfunc(g_pLocaleTable, hashCode);
     243             : 
     244        2873 :     if (rtl_hashtable_find(g_pLocaleTable, key, hashCode, &newLocale))
     245          32 :         return newLocale;
     246             : 
     247        2841 :     rtl_uString_newFromStr(&sLanguage, language);
     248        2841 :     rtl_uString_newFromStr(&sCountry, country);
     249        2841 :     rtl_uString_newFromStr(&sVariant, variant);
     250             : 
     251        2841 :     newLocale = (rtl_Locale*)rtl_allocateMemory( sizeof(rtl_Locale) );
     252             : 
     253        2841 :     newLocale->Language = sLanguage;
     254        2841 :     newLocale->Country = sCountry;
     255        2841 :     newLocale->Variant = sVariant;
     256        2841 :     newLocale->HashCode = hashCode;
     257             : 
     258        2841 :     rtl_hashtable_add(&g_pLocaleTable, newLocale);
     259             : 
     260        2841 :     return newLocale;
     261             : }
     262             : 
     263             : /*************************************************************************
     264             :  *  rtl_locale_getDefault
     265             :  */
     266          20 : rtl_Locale * SAL_CALL rtl_locale_getDefault()
     267             : {
     268          20 :     return g_pDefaultLocale;
     269             : }
     270             : 
     271             : /*************************************************************************
     272             :  *  rtl_locale_setDefault
     273             :  */
     274          28 : void SAL_CALL rtl_locale_setDefault( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant )
     275             : {
     276          28 :     g_pDefaultLocale = rtl_locale_register(language, country, variant);
     277          28 : }
     278             : 
     279             : /*************************************************************************
     280             :  *  rtl_locale_getLanguage
     281             :  */
     282           2 : rtl_uString * SAL_CALL rtl_locale_getLanguage( rtl_Locale * This )
     283             : {
     284           2 :     rtl_uString_acquire(This->Language);
     285           2 :     return This->Language;
     286             : }
     287             : 
     288             : /*************************************************************************
     289             :  *  rtl_locale_getCountry
     290             :  */
     291           2 : rtl_uString * SAL_CALL rtl_locale_getCountry( rtl_Locale * This )
     292             : {
     293           2 :     rtl_uString_acquire(This->Country);
     294           2 :     return This->Country;
     295             : }
     296             : 
     297             : /*************************************************************************
     298             :  *  rtl_locale_getVariant
     299             :  */
     300           2 : rtl_uString * SAL_CALL rtl_locale_getVariant( rtl_Locale * This )
     301             : {
     302           2 :     rtl_uString_acquire(This->Variant);
     303           2 :     return This->Variant;
     304             : }
     305             : 
     306             : /*************************************************************************
     307             :  *  rtl_locale_hashCode
     308             :  */
     309           2 : sal_Int32 SAL_CALL rtl_locale_hashCode( rtl_Locale * This )
     310             : {
     311           2 :     return This->HashCode;
     312             : }
     313             : 
     314             : /*************************************************************************
     315             :  *  rtl_locale_equals
     316             :  */
     317           2 : sal_Int32 SAL_CALL rtl_locale_equals( rtl_Locale * This, rtl_Locale * obj  )
     318             : {
     319           2 :     return This == obj;
     320             : }
     321             : 
     322             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10