Tizen 2.1 base
[platform/core/uifw/ise-engine-sunpinyin.git] / src / pinyin / datrie_impl.h
1 // -*- mode: c++ -*-
2 /*
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4  *
5  * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
6  *
7  * The contents of this file are subject to the terms of either the GNU Lesser
8  * General Public License Version 2.1 only ("LGPL") or the Common Development and
9  * Distribution License ("CDDL")(collectively, the "License"). You may not use this
10  * file except in compliance with the License. You can obtain a copy of the CDDL at
11  * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
12  * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
13  * specific language governing permissions and limitations under the License. When
14  * distributing the software, include this License Header Notice in each file and
15  * include the full text of the License in the License file as well as the
16  * following notice:
17  *
18  * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
19  * (CDDL)
20  * For Covered Software in this distribution, this License shall be governed by the
21  * laws of the State of California (excluding conflict-of-law provisions).
22  * Any litigation relating to this License shall be subject to the jurisdiction of
23  * the Federal Courts of the Northern District of California and the state courts
24  * of the State of California, with venue lying in Santa Clara County, California.
25  *
26  * Contributor(s):
27  *
28  * If you wish your version of this file to be governed by only the CDDL or only
29  * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
30  * include this software in this distribution under the [CDDL or LGPL Version 2.1]
31  * license." If you don't indicate a single choice of license, a recipient has the
32  * option to distribute your version of this file under either the CDDL or the LGPL
33  * Version 2.1, or to extend the choice of license to its licensees as provided
34  * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
35  * Version 2 license, then the option applies only if the new code is made subject
36  * to such option by the copyright holder.
37  */
38
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <stdlib.h>
43
44 #ifdef HAVE_CONFIG_H
45 #include <config.h>
46 #endif
47
48 #ifdef HAVE_SYS_MMAN_H
49 #include <sys/mman.h>
50 #endif
51
52 #include "datrie.h"
53
54 template <typename T, encoder_func_ptr encoder>
55 bool CDATrie<T, encoder>::load(const char * fname){
56     free();
57
58     bool suc = false;
59     int fd = open(fname, O_RDONLY);
60     if (fd == -1) return false;
61
62     m_memSize = lseek(fd, 0, SEEK_END);
63     lseek(fd, 0, SEEK_SET);
64
65 #ifdef HAVE_SYS_MMAN_H
66     suc =
67         (m_mem =
68              (char *) mmap(NULL, m_memSize, PROT_READ, MAP_SHARED, fd,
69                            0)) != MAP_FAILED;
70 #else
71     suc = (m_mem = new char [m_memSize]) != NULL;
72     suc = suc && (read(fd, m_mem, m_memSize) > 0);
73 #endif /* HAVE_SYS_MMAN_H */
74     close(fd);
75
76     if (!suc)
77         return suc;
78
79     m_len = *((unsigned *) m_mem);
80     unsigned short elm_size = *((unsigned short *) (m_mem + sizeof(m_len)));
81     unsigned short has_value =
82         *((unsigned short *) (m_mem + sizeof(m_len) + sizeof(elm_size)));
83
84     if (sizeof(T) != elm_size)
85         return false;
86
87     m_base = (T *) (m_mem + sizeof(m_len) + sizeof(elm_size) + sizeof(has_value));
88     m_check = m_base + m_len;
89     m_value = has_value ? (int *) (m_check + m_len) : NULL;
90
91     return suc;
92 }
93
94 template <typename T, encoder_func_ptr encoder>
95 void CDATrie<T, encoder>::free(){
96     if (m_mem) {
97 #ifdef HAVE_SYS_MMAN_H
98         munmap(m_mem, m_memSize);
99 #else
100         delete [] m_mem;
101 #endif
102         m_mem = NULL;
103     }
104
105     m_len = 0;
106     m_base = m_check = NULL;
107     m_value = NULL;
108 }
109
110 template <typename T, encoder_func_ptr encoder>
111 unsigned CDATrie<T, encoder>::walk(unsigned s, unsigned ch, int &v){
112     unsigned c = encoder(ch);
113     unsigned t = abs(m_base[s]) + c;
114
115     if (t < m_len && m_check[t] == (T) s && m_base[t]) {
116         if (m_value)
117             v = m_value[t];
118         else
119             v = m_base[t] < 0 ? -1 : 0;
120
121         return t;
122     }
123
124     v = 0;
125     return 0;
126 }
127
128 template <typename T, encoder_func_ptr encoder>
129 int CDATrie<T, encoder>::match_longest(const char *str, unsigned &length){
130     return match_longest(str, str + strlen(str), length);
131 }
132
133 template <typename T, encoder_func_ptr encoder>
134 int CDATrie<T, encoder>::match_longest(wstring wstr, unsigned &length){
135     return match_longest(wstr.begin(), wstr.end(), length);
136 }
137
138 template <typename T, encoder_func_ptr encoder>
139 template <typename InputIterator>
140 int CDATrie<T, encoder>::match_longest(InputIterator first,
141                                        InputIterator last,
142                                        unsigned &length){
143     int l = 0, ret_v = 0, curr_state = 0;
144     length = 0;
145
146     for (; first != last; ++first) {
147         unsigned ch = *first;
148         int val;
149         curr_state = walk(curr_state, ch, val);
150         if (!curr_state) break;
151
152         l += 1;
153         if (val) {
154             length = l;
155             ret_v = val;
156         }
157     }
158
159     return ret_v;
160 }