xref: /trunk/main/sal/rtl/source/hash.cxx (revision 22076bf1)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sal.hxx"
26 
27 #include "hash.h"
28 #include "strimp.h"
29 
30 #include <hash_set>
31 
32 namespace {
33 
34 struct UStringHash
35 {
operator ()__anon642635e30111::UStringHash36     size_t operator()(rtl_uString * const &rString) const
37     { return (size_t)rtl_ustr_hashCode_WithLength( rString->buffer, rString->length ); }
38 };
39 
40 struct UStringEqual
41 {
operator ()__anon642635e30111::UStringEqual42     sal_Bool operator() ( rtl_uString * const &pStringA,
43                           rtl_uString * const &pStringB) const
44     {
45         if (pStringA == pStringB)
46             return true;
47         if (pStringA->length != pStringB->length)
48             return false;
49         return !rtl_ustr_compare_WithLength( pStringA->buffer, pStringA->length,
50                                              pStringB->buffer, pStringB->length);
51     }
52 };
53 
54 typedef std::hash_set< rtl_uString *, UStringHash, UStringEqual > StringHashTable;
55 
56 StringHashTable *
getHashTable()57 getHashTable ()
58 {
59     static StringHashTable *pInternPool = NULL;
60     if (pInternPool == NULL) {
61         static StringHashTable aImpl(1024);
62         pInternPool = &aImpl;
63     }
64     return pInternPool;
65 }
66 
67 }
68 
69 extern "C" {
70 
71 rtl_uString *
rtl_str_hash_intern(rtl_uString * pString,int can_return)72 rtl_str_hash_intern (rtl_uString       *pString,
73                      int                can_return)
74 {
75     StringHashTable *pHash = getHashTable();
76     StringHashTable::iterator aIter;
77     aIter = pHash->find(pString);
78     if (aIter != pHash->end())
79     {
80         rtl_uString *pHashStr = *aIter;
81         rtl_uString_acquire (pHashStr);
82         return pHashStr;
83     }
84     if (!can_return)
85     {
86         rtl_uString *pCopy = NULL;
87         rtl_uString_newFromString( &pCopy, pString );
88         pString = pCopy;
89         if (!pString)
90             return NULL;
91     }
92 
93     if (!SAL_STRING_IS_STATIC (pString))
94         pString->refCount |= SAL_STRING_INTERN_FLAG;
95     pHash->insert(pString);
96 
97     return pString;
98 }
99 
100 void
rtl_str_hash_remove(rtl_uString * pString)101 rtl_str_hash_remove (rtl_uString       *pString)
102 {
103     getHashTable()->erase(pString);
104 }
105 
106 }
107