diff options
Diffstat (limited to 'src-worddic/textdict.c')
-rw-r--r-- | src-worddic/textdict.c | 202 |
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; +} |