Imported version 0.2-1
[mstardict] / src / lib / collation.cpp
1 #include "my_global.h"
2 #include "m_ctype.h"
3
4 #include <string.h>
5 #include <glib.h>
6
7 #include "collation.h"
8
9 using namespace stardict_collation;
10
11 static CHARSET_INFO *get_cs(CollateFunctions func)
12 {
13         CHARSET_INFO *cs;
14         if (func == UTF8_GENERAL_CI)
15                 cs = &my_charset_utf8_general_ci;
16         else if (func == UTF8_BIN)
17                 cs = &my_charset_utf8_bin;
18         else if (func == UTF8_UNICODE_CI)
19                 cs = &my_charset_utf8_general_uca_ci;
20         else if (func == UTF8_ICELANDIC_CI)
21                 cs = &my_charset_utf8_icelandic_uca_ci;
22         else if (func == UTF8_LATVIAN_CI)
23                 cs = &my_charset_utf8_latvian_uca_ci;
24         else if (func == UTF8_ROMANIAN_CI)
25                 cs = &my_charset_utf8_romanian_uca_ci;
26         else if (func == UTF8_SLOVENIAN_CI)
27                 cs = &my_charset_utf8_slovenian_uca_ci;
28         else if (func == UTF8_POLISH_CI)
29                 cs = &my_charset_utf8_polish_uca_ci;
30         else if (func == UTF8_ESTONIAN_CI)
31                 cs = &my_charset_utf8_estonian_uca_ci;
32         else if (func == UTF8_SPANISH_CI)
33                 cs = &my_charset_utf8_spanish_uca_ci;
34         else if (func == UTF8_SWEDISH_CI)
35                 cs = &my_charset_utf8_swedish_uca_ci;
36         else if (func == UTF8_TURKISH_CI)
37                 cs = &my_charset_utf8_turkish_uca_ci;
38         else if (func == UTF8_CZECH_CI)
39                 cs = &my_charset_utf8_czech_uca_ci;
40         else if (func == UTF8_DANISH_CI)
41                 cs = &my_charset_utf8_danish_uca_ci;
42         else if (func == UTF8_LITHUANIAN_CI)
43                 cs = &my_charset_utf8_lithuanian_uca_ci;
44         else if (func == UTF8_SLOVAK_CI)
45                 cs = &my_charset_utf8_slovak_uca_ci;
46         else if (func == UTF8_SPANISH2_CI)
47                 cs = &my_charset_utf8_spanish2_uca_ci;
48         else if (func == UTF8_ROMAN_CI)
49                 cs = &my_charset_utf8_roman_uca_ci;
50         else if (func == UTF8_PERSIAN_CI)
51                 cs = &my_charset_utf8_persian_uca_ci;
52         else if (func == UTF8_ESPERANTO_CI)
53                 cs = &my_charset_utf8_esperanto_uca_ci;
54         else if (func == UTF8_HUNGARIAN_CI)
55                 cs = &my_charset_utf8_hungarian_uca_ci;
56         else
57                 cs = NULL;
58         return cs;
59 }
60
61 static GSList *my_once_root_block = NULL;
62
63 static void *my_once_alloc(uint size)
64 {
65         void *mem = g_malloc(size);
66         my_once_root_block = g_slist_prepend (my_once_root_block, mem);
67         return mem;
68 }
69
70 static void my_once_free()
71 {
72         GSList *list = my_once_root_block;
73         while (list) {
74                 g_free(list->data);
75                 list = list->next;
76         }
77         g_slist_free(my_once_root_block);
78         my_once_root_block = NULL;
79 }
80
81 int utf8_collate_init(CollateFunctions func)
82 {
83         CHARSET_INFO *cs = get_cs(func);
84         if (cs) {
85                 if ((cs->cset->init && cs->cset->init(cs, my_once_alloc)) ||
86                         (cs->coll->init && cs->coll->init(cs, my_once_alloc)))
87                         return TRUE;
88                 else
89                         return FALSE;
90         } else
91                 return TRUE;
92 }
93
94 int utf8_collate_init_all()
95 {
96         CHARSET_INFO *cs;
97         for (int func=0; func<COLLATE_FUNC_NUMS; func++) {
98                 cs = get_cs((CollateFunctions)func);
99                 if (cs) {
100                         if ((cs->cset->init && cs->cset->init(cs, my_once_alloc)) ||
101                                 (cs->coll->init && cs->coll->init(cs, my_once_alloc)))
102                                 return TRUE;
103                 } else
104                         return TRUE;
105         }
106         return FALSE;
107 }
108
109 int utf8_collate(const char *str1, const char *str2, CollateFunctions func)
110 {
111         CHARSET_INFO *cs = get_cs(func);
112         if (cs) {
113                 return cs->coll->strnncoll(cs, (const uchar*)str1, strlen(str1), (const uchar*)str2, strlen(str2), 0);
114         } else
115                 return 0; //Should never happen.
116 }
117
118 void utf8_collate_end()
119 {
120         my_once_free();
121 }