(linenum→info "unix/slp.c:2238")

anthy/9100e/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: }
Syntax (Markdown)