summaryrefslogtreecommitdiff
path: root/src-worddic/textdict.c
diff options
context:
space:
mode:
Diffstat (limited to 'src-worddic/textdict.c')
-rw-r--r--src-worddic/textdict.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/src-worddic/textdict.c b/src-worddic/textdict.c
new file mode 100644
index 0000000..4d3d04b
--- /dev/null
+++ b/src-worddic/textdict.c
@@ -0,0 +1,202 @@
+/*
+ * ソートされたテキストから検索を行う
+ */
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <anthy/filemap.h>
+#include <anthy/textdict.h>
+#include "dic_main.h"
+
+struct textdict {
+ char *fn;
+ char *ptr;
+ struct filemapping *mapping;
+};
+
+struct textdict *
+anthy_textdict_open(const char *fn, int create)
+{
+ struct textdict *td = malloc(sizeof(struct textdict));
+ if (!td) {
+ return NULL;
+ }
+ td->fn = strdup(fn);
+ if (!td->fn) {
+ free(td);
+ return NULL;
+ }
+ td->mapping = NULL;
+ return td;
+}
+
+
+static void
+unmap(struct textdict *td)
+{
+ if (td->mapping) {
+ anthy_munmap(td->mapping);
+ td->mapping = NULL;
+ }
+}
+
+void
+anthy_textdict_close(struct textdict *td)
+{
+ if (!td) {
+ return ;
+ }
+ unmap(td);
+ free(td->fn);
+ free(td);
+}
+
+static int
+update_mapping(struct textdict *td)
+{
+ if (td->mapping) {
+ anthy_munmap(td->mapping);
+ }
+ td->mapping = anthy_mmap(td->fn, 1);
+ if (!td->mapping) {
+ td->ptr = NULL;
+ return 1;
+ }
+ td->ptr = anthy_mmap_address(td->mapping);
+ return 0;
+}
+
+static int
+expand_file(struct textdict *td, int len)
+{
+ FILE *fp;
+ char buf[256];
+ int c;
+ fp = fopen(td->fn, "a+");
+ if (!fp) {
+ return -1;
+ }
+ memset(buf, '\n', 256);
+ c = 1;
+ if (len > 256) {
+ c *= fwrite(buf, 256, len / 256, fp);
+ }
+ if (len % 256) {
+ c *= fwrite(buf, len % 256, 1, fp);
+ }
+ fclose(fp);
+ if (c == 0) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+anthy_textdict_scan(struct textdict *td, int offset, void *ptr,
+ int (*fun)(void *, int, const char *, const char *))
+{
+ FILE *fp;
+ char buf[1024];
+ if (!td) {
+ return ;
+ }
+ fp = fopen(td->fn, "r");
+ if (!fp) {
+ return ;
+ }
+ if (fseek(fp, offset, SEEK_SET)) {
+ fclose(fp);
+ return ;
+ }
+ while (fgets(buf, 1024, fp)) {
+ char *p = strchr(buf, ' ');
+ int len, r;
+ len = strlen(buf);
+ offset += len;
+ buf[len - 1] = 0;
+ if (!p) {
+ continue;
+ }
+ *p = 0;
+ p++;
+ while (*p == ' ') {
+ p++;
+ }
+ /* call it */
+ r = fun(ptr, offset, buf, p);
+ if (r) {
+ break;
+ }
+ }
+ fclose(fp);
+}
+
+int
+anthy_textdict_delete_line(struct textdict *td, int offset)
+{
+ FILE *fp;
+ char buf[1024];
+ int len, size;
+ fp = fopen(td->fn, "r");
+ if (!fp) {
+ return -1;
+ }
+ if (fseek(fp, offset, SEEK_SET)) {
+ fclose(fp);
+ return -1;
+ }
+ if (!fgets(buf, 1024, fp)) {
+ fclose(fp);
+ return -1;
+ }
+ len = strlen(buf);
+ fclose(fp);
+ update_mapping(td);
+ if (!td->mapping) {
+ return -1;
+ }
+ size = anthy_mmap_size(td->mapping);
+ memmove(&td->ptr[offset], &td->ptr[offset+len], size - offset - len);
+ unmap(td);
+ if (size - len == 0) {
+ unlink(td->fn);
+ return 0;
+ }
+ truncate(td->fn, size - len);
+ return 0;
+}
+
+int
+anthy_textdict_insert_line(struct textdict *td, int offset,
+ const char *line)
+{
+ int len = strlen(line);
+ int size;
+ if (!td) {
+ return -1;
+ }
+ if (expand_file(td, len)) {
+ return -1;
+ }
+ update_mapping(td);
+ size = anthy_mmap_size(td->mapping);
+ memmove(&td->ptr[offset+len], &td->ptr[offset], size - offset - len);
+ memcpy(&td->ptr[offset], line, len);
+ return 0;
+}