LCOV - code coverage report
Current view: top level - libreoffice/sal/rtl/source - locale.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 106 149 71.1 %
Date: 2012-12-17 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 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         556 : extern "C" void rtl_hashentry_destroy(RTL_HASHENTRY* entry)
      53             : {
      54         556 :     rtl_uString_release(entry->Entry->Language);
      55         556 :     rtl_uString_release(entry->Entry->Country);
      56         556 :     rtl_uString_release(entry->Entry->Variant);
      57         556 :     if (entry->Next)
      58           0 :         rtl_hashentry_destroy(entry->Next);
      59             : 
      60         556 :     rtl_freeMemory(entry->Entry);
      61         556 :     rtl_freeMemory(entry);
      62         556 : }
      63             : 
      64         552 : extern "C" void rtl_hashtable_destroy(RTL_HASHTABLE* table)
      65             : {
      66         552 :     sal_Int32 size = 0;
      67             : 
      68         552 :     if (!table)
      69         552 :         return;
      70             : 
      71         552 :     size = table->Size;
      72             : 
      73       18216 :     while (size)
      74             :     {
      75       17112 :         if (table->Table[size - 1])
      76         556 :             rtl_hashentry_destroy(table->Table[size - 1]);
      77       17112 :         size--;
      78             :     }
      79             : 
      80         552 :     rtl_freeMemory(table->Table);
      81         552 :     rtl_freeMemory(table);
      82             : }
      83             : 
      84         552 : extern "C" void rtl_hashtable_init(RTL_HASHTABLE** table, sal_Int8 sizeIndex)
      85             : {
      86         552 :     sal_Int32 nSize = RTL_HASHTABLE_SIZE[sizeIndex];
      87             : 
      88         552 :     if (*table)
      89           0 :         rtl_hashtable_destroy(*table);
      90             : 
      91         552 :     *table = (RTL_HASHTABLE*)rtl_allocateMemory( sizeof(RTL_HASHTABLE) );
      92             : 
      93         552 :     (*table)->iSize = sizeIndex;
      94         552 :     (*table)->Size = nSize;
      95         552 :     (*table)->Elements = 0;
      96         552 :     (*table)->Table = (RTL_HASHENTRY**)rtl_allocateMemory( (*table)->Size * sizeof(RTL_HASHENTRY*) );
      97             : 
      98       18216 :     while (nSize)
      99             :     {
     100       17112 :         (*table)->Table[nSize - 1] = NULL;
     101       17112 :         nSize--;
     102             :     }
     103         552 : }
     104             : 
     105        1144 : extern "C" sal_Int32 rtl_hashfunc(RTL_HASHTABLE* table, sal_Int32 key)
     106             : {
     107        1144 :     return ( (sal_uInt32) key % table->Size);
     108             : }
     109             : 
     110             : extern "C" sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table);
     111             : 
     112         556 : extern "C" rtl_Locale* rtl_hashtable_add(RTL_HASHTABLE** table, rtl_Locale* value)
     113             : {
     114         556 :     sal_Int32 key = 0;
     115             : 
     116         556 :     if (!(*table))
     117           0 :         return NULL;
     118             : 
     119         556 :     if ((*table)->Elements > ((*table)->Size / 2))
     120           0 :         rtl_hashtable_grow(table);
     121             : 
     122         556 :     key = rtl_hashfunc(*table, value->HashCode);
     123             : 
     124         556 :     if (!(*table)->Table[key])
     125             :     {
     126         556 :         RTL_HASHENTRY *newEntry = (RTL_HASHENTRY*)rtl_allocateMemory( sizeof(RTL_HASHENTRY) );
     127         556 :         newEntry->Entry = value;
     128         556 :         newEntry->Next = NULL;
     129         556 :         (*table)->Table[key] = newEntry;
     130         556 :         (*table)->Elements++;
     131         556 :         return NULL;
     132             :     } else
     133             :     {
     134           0 :         RTL_HASHENTRY *pEntry = (*table)->Table[key];
     135           0 :         RTL_HASHENTRY *newEntry = NULL;
     136             : 
     137           0 :         while (pEntry)
     138             :         {
     139           0 :             if (value->HashCode == pEntry->Entry->HashCode)
     140           0 :                 return pEntry->Entry;
     141             : 
     142           0 :             if (!pEntry->Next)
     143           0 :                 break;
     144             : 
     145           0 :             pEntry = pEntry->Next;
     146             :         }
     147             : 
     148           0 :         newEntry = (RTL_HASHENTRY*)rtl_allocateMemory( sizeof(RTL_HASHENTRY) );
     149           0 :         newEntry->Entry = value;
     150           0 :         newEntry->Next = NULL;
     151           0 :         pEntry->Next = newEntry;
     152           0 :         (*table)->Elements++;
     153           0 :         return NULL;
     154             :     }
     155             : }
     156             : 
     157           0 : sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table)
     158             : {
     159           0 :     RTL_HASHTABLE* pNewTable = NULL;
     160           0 :     sal_Int32 i = 0;
     161             : 
     162           0 :     rtl_hashtable_init(&pNewTable, (sal_Int8)((*table)->iSize + 1));
     163             : 
     164           0 :     while (i < (*table)->Size)
     165             :     {
     166           0 :         if ((*table)->Table[i])
     167             :         {
     168             :             RTL_HASHENTRY *pNext;
     169           0 :             RTL_HASHENTRY *pEntry = (*table)->Table[i];
     170             : 
     171           0 :             rtl_hashtable_add(&pNewTable, pEntry->Entry);
     172             : 
     173           0 :             while (pEntry->Next)
     174             :             {
     175           0 :                 rtl_hashtable_add(&pNewTable, pEntry->Next->Entry);
     176           0 :                 pNext = pEntry->Next;
     177           0 :                 rtl_freeMemory(pEntry);
     178           0 :                 pEntry = pNext;
     179             :             }
     180             : 
     181           0 :             rtl_freeMemory(pEntry);
     182             :         }
     183           0 :         i++;
     184             :     }
     185             : 
     186           0 :     rtl_freeMemory((*table)->Table);
     187           0 :     rtl_freeMemory((*table));
     188           0 :     (*table) = pNewTable;
     189             : 
     190           0 :     return sal_True;
     191             : }
     192             : 
     193         588 : extern "C" sal_Bool rtl_hashtable_find(RTL_HASHTABLE * table, sal_Int32 key, sal_Int32 hashCode, rtl_Locale** pValue)
     194             : {
     195         588 :     if (!table)
     196           0 :         return sal_False;
     197             : 
     198         588 :     if (table->Table[key])
     199             :     {
     200          32 :         RTL_HASHENTRY *pEntry = table->Table[key];
     201             : 
     202          64 :         while (pEntry && hashCode != pEntry->Entry->HashCode)
     203           0 :             pEntry = pEntry->Next;
     204             : 
     205          32 :         if (pEntry)
     206          32 :             *pValue = pEntry->Entry;
     207             :         else
     208           0 :             return sal_False;
     209             :     } else
     210         556 :         return sal_False;
     211             : 
     212          32 :     return sal_True;
     213             : }
     214             : 
     215             : /*************************************************************************
     216             :  *  rtl_locale_init
     217             :  */
     218         552 : void rtl_locale_init()
     219             : {
     220             :   OSL_ASSERT(g_pLocaleTable == 0);
     221         552 :   rtl_hashtable_init(&g_pLocaleTable, 1);
     222         552 : }
     223             : 
     224             : /*************************************************************************
     225             :  *  rtl_locale_fini
     226             :  */
     227         552 : void rtl_locale_fini()
     228             : {
     229         552 :   if (g_pLocaleTable != 0)
     230             :   {
     231         552 :     rtl_hashtable_destroy (g_pLocaleTable);
     232         552 :     g_pLocaleTable = 0;
     233             :   }
     234         552 : }
     235             : 
     236             : /*************************************************************************
     237             :  *  rtl_locale_register
     238             :  */
     239         588 : rtl_Locale * SAL_CALL rtl_locale_register( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant )
     240             : {
     241         588 :     sal_Unicode c = 0;
     242         588 :     rtl_uString* sLanguage = NULL;
     243         588 :     rtl_uString* sCountry = NULL;
     244         588 :     rtl_uString* sVariant = NULL;
     245         588 :     rtl_Locale *newLocale = NULL;
     246         588 :     sal_Int32 hashCode = -1;
     247         588 :     sal_Int32 key = 0;
     248             : 
     249         588 :     if ( !country )
     250           0 :         country = &c;
     251         588 :     if ( !variant )
     252           0 :         variant = &c;
     253             : 
     254         588 :     ensureLocaleSingleton();
     255         588 :     if (!g_pLocaleTable)
     256           0 :       return NULL;
     257             : 
     258         588 :     hashCode = rtl_ustr_hashCode(language) ^ rtl_ustr_hashCode(country) ^ rtl_ustr_hashCode(variant);
     259         588 :     key = rtl_hashfunc(g_pLocaleTable, hashCode);
     260             : 
     261         588 :     if (rtl_hashtable_find(g_pLocaleTable, key, hashCode, &newLocale))
     262          32 :         return newLocale;
     263             : 
     264         556 :     rtl_uString_newFromStr(&sLanguage, language);
     265         556 :     rtl_uString_newFromStr(&sCountry, country);
     266         556 :     rtl_uString_newFromStr(&sVariant, variant);
     267             : 
     268         556 :     newLocale = (rtl_Locale*)rtl_allocateMemory( sizeof(rtl_Locale) );
     269             : 
     270         556 :     newLocale->Language = sLanguage;
     271         556 :     newLocale->Country = sCountry;
     272         556 :     newLocale->Variant = sVariant;
     273         556 :     newLocale->HashCode = hashCode;
     274             : 
     275         556 :     rtl_hashtable_add(&g_pLocaleTable, newLocale);
     276             : 
     277         556 :     return newLocale;
     278             : }
     279             : 
     280             : /*************************************************************************
     281             :  *  rtl_locale_getDefault
     282             :  */
     283          20 : rtl_Locale * SAL_CALL rtl_locale_getDefault()
     284             : {
     285          20 :     return g_pDefaultLocale;
     286             : }
     287             : 
     288             : /*************************************************************************
     289             :  *  rtl_locale_setDefault
     290             :  */
     291          28 : void SAL_CALL rtl_locale_setDefault( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant )
     292             : {
     293          28 :     g_pDefaultLocale = rtl_locale_register(language, country, variant);
     294          28 : }
     295             : 
     296             : /*************************************************************************
     297             :  *  rtl_locale_getLanguage
     298             :  */
     299           2 : rtl_uString * SAL_CALL rtl_locale_getLanguage( rtl_Locale * This )
     300             : {
     301           2 :     rtl_uString_acquire(This->Language);
     302           2 :     return This->Language;
     303             : }
     304             : 
     305             : /*************************************************************************
     306             :  *  rtl_locale_getCountry
     307             :  */
     308           2 : rtl_uString * SAL_CALL rtl_locale_getCountry( rtl_Locale * This )
     309             : {
     310           2 :     rtl_uString_acquire(This->Country);
     311           2 :     return This->Country;
     312             : }
     313             : 
     314             : /*************************************************************************
     315             :  *  rtl_locale_getVariant
     316             :  */
     317           2 : rtl_uString * SAL_CALL rtl_locale_getVariant( rtl_Locale * This )
     318             : {
     319           2 :     rtl_uString_acquire(This->Variant);
     320           2 :     return This->Variant;
     321             : }
     322             : 
     323             : /*************************************************************************
     324             :  *  rtl_locale_hashCode
     325             :  */
     326           2 : sal_Int32 SAL_CALL rtl_locale_hashCode( rtl_Locale * This )
     327             : {
     328           2 :     return This->HashCode;
     329             : }
     330             : 
     331             : /*************************************************************************
     332             :  *  rtl_locale_equals
     333             :  */
     334           2 : sal_Int32 SAL_CALL rtl_locale_equals( rtl_Locale * This, rtl_Locale * obj  )
     335             : {
     336           2 :     return This == obj;
     337             : }
     338             : 
     339             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10