Tizen 2.1 base
[platform/core/uifw/ise-engine-sunpinyin.git] / src / lexicon / pytrie.cpp
1 #include <stdio.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <deque>
5
6 #include "pytrie.h"
7 #include "pinyin_data.h"
8
9 #ifdef HAVE_SYS_MMAN_H
10 #include <sys/mman.h>
11 #endif
12
13 bool
14 CPinyinTrie::isValid(const TNode* pnode,
15                      bool allowNonComplete,
16                      unsigned csLevel)
17 {
18     if ((pnode != NULL) && (csLevel <= pnode->m_csLevel))
19         return(allowNonComplete || (pnode->m_bFullSyllableTransfer == 1));
20     return false;
21 }
22
23 int
24 CPinyinTrie::lengthAt(unsigned int idx) const
25 {
26     if (idx < getWordCount() - 1) {
27         return (m_words[idx + 1] - m_words[idx]) - 1;
28     } else if (idx == getWordCount() - 1) {
29         return (((TWCHAR*)(m_mem + m_Size)) - m_words[idx]) - 1;
30     }
31     return 0;
32 }
33
34 unsigned int
35 CPinyinTrie::getSymbolId(const TWCHAR* wstr)
36 {
37     std::map<wstring, unsigned>::const_iterator it;
38
39     it = m_SymbolMap.find(wstring(wstr));
40     if (it != m_SymbolMap.end())
41         return it->second;
42     return 0;
43 }
44
45 unsigned int
46 CPinyinTrie::getSymbolId(const wstring & wstr)
47 {
48     std::map<wstring, unsigned>::const_iterator it;
49
50     it = m_SymbolMap.find(wstr);
51     if (it != m_SymbolMap.end())
52         return it->second;
53     return 0;
54 }
55
56 void
57 CPinyinTrie::free(void)
58 {
59     if (m_mem) {
60 #ifdef HAVE_SYS_MMAN_H
61         munmap(m_mem, m_Size);
62 #else
63         delete [] m_mem;
64 #endif
65         m_mem = NULL;
66     }
67     if (m_words) {
68         delete [] m_words;
69         m_words = NULL;
70     }
71     m_SymbolMap.clear();
72 }
73
74 bool
75 CPinyinTrie::load(const char *fname)
76 {
77     free();
78
79     bool suc = false;
80     int fd = open(fname, O_RDONLY);
81     if (fd == -1) return false;
82
83     m_Size = lseek(fd, 0, SEEK_END);
84     lseek(fd, 0, SEEK_SET);
85
86 #ifdef HAVE_SYS_MMAN_H
87     suc =
88         (m_mem =
89              (char*)mmap(NULL, m_Size, PROT_READ, MAP_SHARED, fd,
90                          0)) != MAP_FAILED;
91 #else
92     suc = (m_mem = new char [m_Size]) != NULL;
93     suc = suc && (read(fd, m_mem, m_Size) > 0);
94 #endif
95     close(fd);
96
97     suc = suc && ((m_words = new TWCHAR*[getWordCount()]) != NULL);
98
99     if (suc) {
100         TWCHAR *p = (TWCHAR*)(m_mem + getStringOffset());
101         for (int i = 0, sz = getWordCount(); i < sz; ++i) {
102             m_words[i] = p;
103             while (*p++)
104                 ;
105         }
106         for (unsigned i = 1; i < 100; ++i) {
107             if (*m_words[i] != WCH_NULL && *m_words[i] != WCH_LESSTHAN)
108                 m_SymbolMap[wstring(m_words[i])] = i;
109         }
110     }
111     return suc;
112 }
113
114 void
115 CPinyinTrie::print(FILE *fp) const
116 {
117     std::string prefix;
118     print(getRootNode(), prefix, fp);
119 }
120
121 void
122 CPinyinTrie::print(const TNode* pRoot, std::string& prefix, FILE *fp) const
123 {
124     static char buf[1024];
125     if (pRoot->m_nWordId > 0) {
126         fprintf(fp, "%s", prefix.c_str());
127         if (pRoot->m_csLevel)
128             fprintf(fp, "(GBK+)");
129         unsigned int sz = pRoot->m_nWordId;
130         const TWordIdInfo *pwids = pRoot->getWordIdPtr();
131         for (unsigned int i = 0; i < sz; ++i) {
132             unsigned int id = pwids[i].m_id;
133             const TWCHAR *pw = operator[](id);
134             int len = WCSLEN(pw);
135             if (len != lengthAt(id)) {
136                 printf(" (lengthAt %d error) ", id);
137             }
138             WCSTOMBS(buf, pw, 1024);
139             fprintf(fp, " %s", buf);
140             if (pwids[i].m_bSeen == 0)
141                 fprintf(fp, "[x]");
142             else
143                 fprintf(fp, "[o]");
144
145             fprintf(fp, "(%d)", pwids[i].m_cost);
146         }
147         fprintf(fp, "\n");
148     }
149     unsigned int sz = pRoot->m_nTransfer;
150     const TTransUnit* ptrans = pRoot->getTrans();
151     for (unsigned int i = 0; i < sz; ++i) {
152         unsigned s = ptrans[i].m_Syllable;
153         const TNode *pch = transfer(pRoot, s);
154         const char *str = CPinyinData::decodeSyllable(s);
155         if (!str) break;
156         prefix = prefix + str + '\'';
157         print(pch, prefix, fp);
158         prefix.resize(prefix.size() - strlen(str) - 1);
159     }
160 }