Applied fPIE, pie compier option
[platform/core/uifw/anthy.git] / src-worddic / textdict.c
1 /*
2  * ¥½¡¼¥È¤µ¤ì¤¿¥Æ¥­¥¹¥È¤«¤é¸¡º÷¤ò¹Ô¤¦
3  */
4 /*
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2 of the License, or (at your option) any later version.
9
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
18  */
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <anthy/filemap.h>
24 #include <anthy/textdict.h>
25 #include "dic_main.h"
26
27 struct textdict {
28   char *fn;
29   char *ptr;
30   struct filemapping *mapping;
31 };
32
33 struct textdict *
34 anthy_textdict_open(const char *fn, int create)
35 {
36   struct textdict *td = malloc(sizeof(struct textdict));
37   if (!td) {
38     return NULL;
39   }
40   td->fn = strdup(fn);
41   if (!td->fn) {
42     free(td);
43     return NULL;
44   }
45   td->mapping = NULL;
46   return td;
47 }
48
49
50 static void
51 unmap(struct textdict *td)
52 {
53   if (td->mapping) {
54     anthy_munmap(td->mapping);
55     td->mapping = NULL;
56   }
57 }
58
59 void
60 anthy_textdict_close(struct textdict *td)
61 {
62   if (!td) {
63     return ;
64   }
65   unmap(td);
66   free(td->fn);
67   free(td);
68 }
69
70 static int
71 update_mapping(struct textdict *td)
72 {
73   if (td->mapping) {
74     anthy_munmap(td->mapping);
75   }
76   td->mapping = anthy_mmap(td->fn, 1);
77   if (!td->mapping) {
78     td->ptr = NULL;
79     return 1;
80   }
81   td->ptr = anthy_mmap_address(td->mapping);
82   return 0;
83 }
84
85 static int
86 expand_file(struct textdict *td, int len)
87 {
88   FILE *fp;
89   char buf[256];
90   int c;
91   fp = fopen(td->fn, "a+");
92   if (!fp) {
93     return -1;
94   }
95   memset(buf, '\n', 256);
96   c = 1;
97   if (len > 256) {
98     c *= fwrite(buf, 256, len / 256, fp);
99   }
100   if (len % 256) {
101     c *= fwrite(buf, len % 256, 1, fp);
102   }
103   fclose(fp);
104   if (c == 0) {
105     return -1;
106   }
107   return 0;
108 }
109
110 void
111 anthy_textdict_scan(struct textdict *td, int offset, void *ptr,
112                     int (*fun)(void *, int, const char *, const char *))
113 {
114   FILE *fp;
115   char buf[1024];
116   if (!td) {
117     return ;
118   }
119   fp = fopen(td->fn, "r");
120   if (!fp) {
121     return ;
122   }
123   if (fseek(fp, offset, SEEK_SET)) {
124     fclose(fp);
125     return ;
126   }
127   while (fgets(buf, 1024, fp)) {
128     char *p = strchr(buf, ' ');
129     int len, r;
130     len = strlen(buf);
131     offset += len;
132     buf[len - 1] = 0;
133     if (!p) {
134       continue;
135     }
136     *p = 0;
137     p++;
138     while (*p == ' ') {
139       p++;
140     }
141     /* call it */
142     r = fun(ptr, offset, buf, p);
143     if (r) {
144       break;
145     }
146   }
147   fclose(fp);
148 }
149
150 int
151 anthy_textdict_delete_line(struct textdict *td, int offset)
152 {
153   FILE *fp;
154   char buf[1024];
155   int len, size;
156   fp = fopen(td->fn, "r");
157   if (!fp) {
158     return -1;
159   }
160   if (fseek(fp, offset, SEEK_SET)) {
161     fclose(fp);
162     return -1;
163   }
164   if (!fgets(buf, 1024, fp)) {
165     fclose(fp);
166     return -1;
167   }
168   len = strlen(buf);
169   fclose(fp);
170   update_mapping(td);
171   if (!td->mapping) {
172     return -1;
173   }
174   size = anthy_mmap_size(td->mapping);
175   memmove(&td->ptr[offset], &td->ptr[offset+len], size - offset - len);
176   unmap(td);
177   if (size - len == 0) {
178     unlink(td->fn);
179     return 0;
180   }
181   truncate(td->fn, size - len);
182   return 0;
183 }
184
185 int
186 anthy_textdict_insert_line(struct textdict *td, int offset,
187                            const char *line)
188 {
189   int len = strlen(line);
190   int size;
191   if (!td) {
192     return -1;
193   }
194   if (expand_file(td, len)) {
195     return -1;
196   }
197   update_mapping(td);
198   size = anthy_mmap_size(td->mapping);
199   memmove(&td->ptr[offset+len], &td->ptr[offset], size - offset - len);
200   memcpy(&td->ptr[offset], line, len);
201   return 0;
202 }