summaryrefslogtreecommitdiff
path: root/src/lib/ecore_input/ecore_input_compose.c
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-09-04 11:40:07 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-09-04 11:42:08 +0900
commitfabda81a4e9175244031a3572f9f8730842cd9d8 (patch)
tree930eda52ce5610c270b3e1d13ce3e4ceb88fcfb7 /src/lib/ecore_input/ecore_input_compose.c
parent441f10e3abb1f0566e557acffe18a4e762db8d1c (diff)
ecore-input - compose seq handler now uses compact str - saves about 100k
Diffstat (limited to 'src/lib/ecore_input/ecore_input_compose.c')
-rw-r--r--src/lib/ecore_input/ecore_input_compose.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/src/lib/ecore_input/ecore_input_compose.c b/src/lib/ecore_input/ecore_input_compose.c
index 5335a7fe0c..13b90bca09 100644
--- a/src/lib/ecore_input/ecore_input_compose.c
+++ b/src/lib/ecore_input/ecore_input_compose.c
@@ -19,39 +19,82 @@
19EAPI Ecore_Compose_State 19EAPI Ecore_Compose_State
20ecore_compose_get(const Eina_List *seq, char **seqstr_ret) 20ecore_compose_get(const Eina_List *seq, char **seqstr_ret)
21{ 21{
22 Comp *c, *cend; 22 const char *p, *pend;
23 const unsigned char *psz;
23 Eina_List *l; 24 Eina_List *l;
24 const char *s; 25 const char *s;
25 int i = 0; 26 int i = 0;
27 static int complen = 0;
26 28
27 if (!seq) return ECORE_COMPOSE_NONE; 29 if (!seq) return ECORE_COMPOSE_NONE;
28 l = (Eina_List *)seq; 30 l = (Eina_List *)seq;
29 s = l->data; 31 s = l->data;
30 cend = (Comp *)comp + (sizeof(comp) / sizeof(comp[0])); 32
31 for (c = (Comp *)comp; c->s && s;) 33 // calc comp string len first time around
34 if (complen == 0)
32 { 35 {
33 // doesn't match -> jump to next level entry 36 int zeros = 0;
34 if (!(!strcmp(s, c->s))) 37
38 for (p = comp; ; p++)
35 { 39 {
36 c += c->jump + 1; 40 if (!(*p)) zeros++;
37 if (c >= cend) 41 else zeros = 0;
42 // end marker - 4 0 bytes in a row
43 if (zeros == 4)
38 { 44 {
39 return ECORE_COMPOSE_NONE; 45 complen = p - comp - 3;
46 break;
40 } 47 }
41 } 48 }
49 }
50 // walk special comp string/byte array looking for our match
51 pend = comp + complen;
52 for (p = comp; (p < pend) && s;)
53 {
54 int len, jump = -1, bsize = -1;
55
56 len = strlen(p);
57 psz = (unsigned char *)(p + len + 1);
58 // decode jump amount to next entry
59 if (!(psz[0] & 0x80)) // < 0x80
60 {
61 jump = psz[0];
62 bsize = 1;
63 }
64 else if ((psz[0] & 0xc0) == 0xc0) // < 0x200000
65 {
66 jump = (((psz[0] & 0x1f) << 16) | (psz[1] << 8) | (psz[2]));
67 bsize = 3;
68 }
69 else // >= 0x4000
70 {
71 jump = (((psz[0] & 0x3f) << 8) | (psz[1]));
72 bsize = 2;
73 }
74
75 // doesn't match -> jump to next level entry
76 if (!(!strcmp(s, p)))
77 {
78 p = p + jump;
79 if (p >= pend) return ECORE_COMPOSE_NONE;
80 }
81 // matches
42 else 82 else
43 { 83 {
44 cend = c + c->jump; 84 pend = p + jump;
45 // advance to next sequence member 85 // advance to next sequence member
46 l = l->next; 86 l = l->next;
47 i++; 87 i++;
48 if (l) s = l->data; 88 if (l) s = l->data;
49 else s = NULL; 89 else s = NULL;
50 c++; 90 p = p + len + 1 + bsize;
51 // if advanced item jump is an endpoint - it's the string we want 91 len = strlen(p);
52 if (c->jump == 0) 92 psz = (unsigned char *)(p + len + 1);
93 // leaf nodes all are short so psz[0] has the full value
94 if ((len + 2) == psz[0])
53 { 95 {
54 if (seqstr_ret) *seqstr_ret = strdup(c->s); 96 // final leaf node, so return string here
97 if (seqstr_ret) *seqstr_ret = strdup(p);
55 return ECORE_COMPOSE_DONE; 98 return ECORE_COMPOSE_DONE;
56 } 99 }
57 } 100 }