1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
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:
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: }