-
Notifications
You must be signed in to change notification settings - Fork 0
/
dfi-builder-string-table.c
177 lines (141 loc) · 4.89 KB
/
dfi-builder-string-table.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "dfi-builder-string-table.h"
#include <string.h>
static guint
str_hash0 (gconstpointer a)
{
return a ? g_str_hash (a) : 0;
}
static gboolean
str_equal0 (gconstpointer a,
gconstpointer b)
{
return g_strcmp0 (a, b) == 0;
}
GHashTable *
desktop_file_index_string_tables_create (void)
{
return g_hash_table_new_full (str_hash0, str_equal0, g_free, (GDestroyNotify) g_hash_table_unref);
}
static gchar *
get_locale_group (const gchar *for_locale)
{
/* This function decides how to group the string tables of locales in
* order to improve sharing of strings between similar locales while
* preventing too much overlap between unrelated ones (thus improving
* locality of access).
*
* This function doesn't need to be "correct" in any sense (beyond
* being deterministic); this grouping is merely an optimisation.
*/
/* Untranslated strings... */
g_assert (for_locale);
if (!for_locale)
return NULL;
/* English translations will share 99% of strings with the C locale,
* so avoid duplicating them. Note: careful to avoid en@shaw.
*/
if (g_str_equal (for_locale, "en") || g_str_has_prefix (for_locale, "en_"))
return g_strdup ("");
/* Valencian is just a dialect of Catalan, so make sure they get
* grouped together.
*/
if (g_str_equal (for_locale, "ca@valencia"))
return g_strdup ("ca");
/* Other uses of '@' indicate different character sets. Not much will
* be gained by grouping them, so keep them separate.
*/
if (for_locale[0] && for_locale[1] && for_locale[2] == '@')
return g_strdup (for_locale);
/* Otherwise, we have cases like pt_BR and fr_CH. Group these by
* language code for hope that they will be similar.
*/
if (for_locale[0] && for_locale[1] && for_locale[2] == '_')
return g_strndup (for_locale, 2);
/* Otherwise, it's something else. Return it, I guess... */
return g_strdup (for_locale);
}
GHashTable *
desktop_file_index_string_tables_get_table (GHashTable *string_tables,
const gchar *locale)
{
GHashTable *string_table;
string_table = g_hash_table_lookup (string_tables, locale);
if (!string_table)
{
gchar *locale_group = get_locale_group (locale);
string_table = g_hash_table_lookup (string_tables, locale_group);
if (!string_table)
{
string_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_insert (string_tables, g_strdup (locale_group), string_table);
}
g_free (locale_group);
g_hash_table_insert (string_tables, g_strdup (locale), g_hash_table_ref (string_table));
}
return string_table;
}
void
desktop_file_index_string_tables_add_string (GHashTable *string_tables,
const gchar *locale,
const gchar *string)
{
GHashTable *string_table;
string_table = desktop_file_index_string_tables_get_table (string_tables, locale);
desktop_file_index_string_table_add_string (string_table, string);
}
void
desktop_file_index_string_table_add_string (GHashTable *string_table,
const gchar *string)
{
g_hash_table_insert (string_table, g_strdup (string), NULL);
}
guint
desktop_file_index_string_tables_get_offset (GHashTable *string_tables,
const gchar *locale,
const gchar *string)
{
GHashTable *string_table;
string_table = desktop_file_index_string_tables_get_table (string_tables, locale);
return desktop_file_index_string_table_get_offset (string_table, string);
}
guint
desktop_file_index_string_table_get_offset (GHashTable *string_table,
const gchar *string)
{
gpointer offset;
offset = g_hash_table_lookup (string_table, string);
g_assert (offset);
return GPOINTER_TO_UINT (offset);
}
gboolean
desktop_file_index_string_table_is_written (GHashTable *string_table)
{
GHashTableIter iter;
gpointer val;
g_hash_table_iter_init (&iter, string_table);
if (!g_hash_table_iter_next (&iter, NULL, &val))
g_error ("mysterious empty string table...");
return val != NULL;
}
void
desktop_file_index_string_table_write (GHashTable *string_table,
GHashTable *shared_table,
GString *file)
{
GHashTableIter iter;
gpointer key, val;
g_hash_table_iter_init (&iter, string_table);
while (g_hash_table_iter_next (&iter, &key, &val))
{
g_assert (val == NULL);
if (shared_table)
val = g_hash_table_lookup (shared_table, key);
if (val == NULL)
{
g_hash_table_iter_replace (&iter, GUINT_TO_POINTER (file->len));
g_string_append_len (file, key, strlen (key) + 1);
}
else
g_hash_table_iter_replace (&iter, val);
}
}