1/*
2******************************************************************************
3*   Copyright (C) 1997-2011, International Business Machines
4*   Corporation and others.  All Rights Reserved.
5******************************************************************************
6*   Date        Name        Description
7*   03/28/00    aliu        Creation.
8******************************************************************************
9*/
10
11#ifndef HASH_H
12#define HASH_H
13
14#include "unicode/unistr.h"
15#include "unicode/uobject.h"
16#include "cmemory.h"
17#include "uhash.h"
18
19U_NAMESPACE_BEGIN
20
21/**
22 * Hashtable is a thin C++ wrapper around UHashtable, a general-purpose void*
23 * hashtable implemented in C.  Hashtable is designed to be idiomatic and
24 * easy-to-use in C++.
25 *
26 * Hashtable is an INTERNAL CLASS.
27 */
28class U_COMMON_API Hashtable : public UMemory {
29    UHashtable* hash;
30    UHashtable hashObj;
31
32    inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
33
34public:
35    /**
36     * Construct a hashtable
37     * @param ignoreKeyCase If true, keys are case insensitive.
38     * @param status Error code
39    */
40    Hashtable(UBool ignoreKeyCase, UErrorCode& status);
41
42    /**
43     * Construct a hashtable
44     * @param keyComp Comparator for comparing the keys
45     * @param valueComp Comparator for comparing the values
46     * @param status Error code
47    */
48    Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
49
50    /**
51     * Construct a hashtable
52     * @param status Error code
53    */
54    Hashtable(UErrorCode& status);
55
56    /**
57     * Construct a hashtable, _disregarding any error_.  Use this constructor
58     * with caution.
59     */
60    Hashtable();
61
62    /**
63     * Non-virtual destructor; make this virtual if Hashtable is subclassed
64     * in the future.
65     */
66    ~Hashtable();
67
68    UObjectDeleter *setValueDeleter(UObjectDeleter *fn);
69
70    int32_t count() const;
71
72    void* put(const UnicodeString& key, void* value, UErrorCode& status);
73
74    int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status);
75
76    void* get(const UnicodeString& key) const;
77
78    int32_t geti(const UnicodeString& key) const;
79
80    void* remove(const UnicodeString& key);
81
82    int32_t removei(const UnicodeString& key);
83
84    void removeAll(void);
85
86    const UHashElement* find(const UnicodeString& key) const;
87
88    const UHashElement* nextElement(int32_t& pos) const;
89
90    UKeyComparator* setKeyComparator(UKeyComparator*keyComp);
91
92    UValueComparator* setValueComparator(UValueComparator* valueComp);
93
94    UBool equals(const Hashtable& that) const;
95private:
96    Hashtable(const Hashtable &other); // forbid copying of this class
97    Hashtable &operator=(const Hashtable &other); // forbid copying of this class
98};
99
100/*********************************************************************
101 * Implementation
102 ********************************************************************/
103
104inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp,
105                            UValueComparator *valueComp, UErrorCode& status) {
106    if (U_FAILURE(status)) {
107        return;
108    }
109    uhash_init(&hashObj, keyHash, keyComp, valueComp, &status);
110    if (U_SUCCESS(status)) {
111        hash = &hashObj;
112        uhash_setKeyDeleter(hash, uprv_deleteUObject);
113    }
114}
115
116inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp,
117                 UErrorCode& status) : hash(0) {
118    init( uhash_hashUnicodeString, keyComp, valueComp, status);
119}
120inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
121 : hash(0)
122{
123    init(ignoreKeyCase ? uhash_hashCaselessUnicodeString
124                        : uhash_hashUnicodeString,
125            ignoreKeyCase ? uhash_compareCaselessUnicodeString
126                        : uhash_compareUnicodeString,
127            NULL,
128            status);
129}
130
131inline Hashtable::Hashtable(UErrorCode& status)
132 : hash(0)
133{
134    init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
135}
136
137inline Hashtable::Hashtable()
138 : hash(0)
139{
140    UErrorCode status = U_ZERO_ERROR;
141    init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
142}
143
144inline Hashtable::~Hashtable() {
145    if (hash != NULL) {
146        uhash_close(hash);
147    }
148}
149
150inline UObjectDeleter *Hashtable::setValueDeleter(UObjectDeleter *fn) {
151    return uhash_setValueDeleter(hash, fn);
152}
153
154inline int32_t Hashtable::count() const {
155    return uhash_count(hash);
156}
157
158inline void* Hashtable::put(const UnicodeString& key, void* value, UErrorCode& status) {
159    return uhash_put(hash, new UnicodeString(key), value, &status);
160}
161
162inline int32_t Hashtable::puti(const UnicodeString& key, int32_t value, UErrorCode& status) {
163    return uhash_puti(hash, new UnicodeString(key), value, &status);
164}
165
166inline void* Hashtable::get(const UnicodeString& key) const {
167    return uhash_get(hash, &key);
168}
169
170inline int32_t Hashtable::geti(const UnicodeString& key) const {
171    return uhash_geti(hash, &key);
172}
173
174inline void* Hashtable::remove(const UnicodeString& key) {
175    return uhash_remove(hash, &key);
176}
177
178inline int32_t Hashtable::removei(const UnicodeString& key) {
179    return uhash_removei(hash, &key);
180}
181
182inline const UHashElement* Hashtable::find(const UnicodeString& key) const {
183    return uhash_find(hash, &key);
184}
185
186inline const UHashElement* Hashtable::nextElement(int32_t& pos) const {
187    return uhash_nextElement(hash, &pos);
188}
189
190inline void Hashtable::removeAll(void) {
191    uhash_removeAll(hash);
192}
193
194inline UKeyComparator* Hashtable::setKeyComparator(UKeyComparator*keyComp){
195    return uhash_setKeyComparator(hash, keyComp);
196}
197
198inline UValueComparator* Hashtable::setValueComparator(UValueComparator* valueComp){
199    return uhash_setValueComparator(hash, valueComp);
200}
201
202inline UBool Hashtable::equals(const Hashtable& that)const{
203   return uhash_equals(hash, that.hash);
204}
205U_NAMESPACE_END
206
207#endif
208
209