Back to index

im-sdk  12.3.91
CodeTable.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 #define _POSIX_PTHREAD_SEMANTICS
00043 
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <stdio.h>
00047 #include <fcntl.h>
00048 
00049 #ifdef WIN32
00050 #include <windows.h>
00051 #include <stdlib.h>
00052 #include <string.h>
00053 #include <direct.h>
00054 #else
00055 #include <dirent.h>
00056 #include <sys/types.h>
00057 #include <unistd.h>
00058 #endif
00059 
00060 #include "CodeTable.h"
00061 #include "UDEngine.h"
00062 
00063 extern engine_info **im;
00064 
00065 #ifndef WIN32
00066 char** get_list_of_codetable(char * pathname) {
00067        DIR *dir;
00068        struct dirent *result;
00069        struct dirent *entry;
00070        int ret_val;
00071        char *ext;
00072        int i;
00073        char **ct_list;
00074 
00075        ct_list = (char **) malloc(sizeof(char *) * 100);
00076        dir = opendir(pathname);
00077        if (!dir) {
00078               printf("can not open dir %s\n", pathname);
00079               free(ct_list);
00080               return NULL;
00081        }
00082        entry = (struct dirent *) malloc(sizeof(struct dirent) + FILENAME_MAX);
00083        i = 0;
00084        while ((ret_val = readdir_r(dir, entry, &result)) == 0) {
00085               if (!result)
00086                      break;
00087               ext = strrchr(result->d_name, (int) '.');
00088               if (ext) {
00089                      if ( (i < 99) && (!strcmp(".mb", ext)) )   {
00090                             printf("file : %s\n", result->d_name);
00091                             ct_list[i] = (char *) malloc(strlen(pathname) + strlen(result->d_name) + 1);
00092                             strcpy(ct_list[i], pathname);
00093                             strcat(ct_list[i], "/");
00094                             strcat(ct_list[i], result->d_name);
00095                             i ++;
00096                      }
00097               }
00098        }
00099        ct_list[i] = NULL;
00100        if( i == 0 ) {
00101               free(ct_list);
00102               ct_list = NULL;
00103        }
00104        free(entry);
00105        closedir(dir);
00106        return (char **)ct_list;
00107 }
00108 
00109 #else
00110 char** get_list_of_codetable(char * pathname) {
00111        char *ext;
00112        char *compl_pathname;
00113        int i = 0;
00114        char *name;
00115        BOOL hasMore;
00116        WIN32_FIND_DATA finddata;
00117        char *filter = "\\*.mb";
00118        char **ct_list;
00119 
00120        ct_list = (char **) malloc(sizeof(char *) * 100);
00121        compl_pathname = (char*) malloc([strlen(pathname) + strlen(filter) + 1]);
00122        sprintf(compl_pathname, "%s%s", pathname, filter);
00123 
00124        /* Check if the path is valid */
00125            DWORD dattrib = GetFileAttributes(pathname);
00126        if (dattrib == -1)
00127               return NULL;
00128        if (!(dattrib & FILE_ATTRIBUTE_DIRECTORY))
00129               return NULL;
00130 
00131        HANDLE dirhand = FindFirstFile(compl_pathname, &finddata);
00132        if (dirhand == (HANDLE) - 1)
00133               return NULL;
00134        do {
00135               name = (LPSTR) & finddata.cFileName;
00136               ext = strrchr(name, (int) '.');
00137               if (ext) {
00138                      if ( (i < 99) && (!strcmp(".mb", ext)) )   {
00139                             printf("file : %s\n", name);
00140                             ct_list[i] = (char *) malloc(strlen(pathname) + strlen(name) + 1);
00141                             strcpy(ct_list[i], pathname);
00142                             strcat(ct_list[i], "/");
00143                             strcat(ct_list[i], name);
00144                             i ++;
00145                      }
00146               }
00147               hasMore = FindNextFile(dirhand, &finddata);
00148        } while (hasMore);
00149 
00150        ct_list[i] = NULL;
00151        if( i == 0 ) {
00152               free(ct_list);
00153               ct_list = NULL;
00154        }
00155        return (char **)ct_list;
00156 }
00157 #endif
00158 
00159 int is_preedit_char(int imid, char c) {
00160        if(im[imid]->tab_idx[idx(c)].used) return 1;
00161        else return 0;
00162 }
00163 
00164 int read_code_table(int imid)
00165 {
00166        int     fd, i;
00167        int     tablen, data_len, max_len;
00168        char    header[80];
00169        char *ct_file_name;
00170        char    *buf, *tmp;
00171 
00172        ct_file_name = (char*) im[imid]->ct_file;
00173 
00174        if ((fd = open(ct_file_name, O_RDONLY)) == -1) {
00175               return -1;
00176        }
00177 
00178        read(fd, header, strlen(CODE_TABLE_HEAD));
00179        if (strncmp(header, CODE_TABLE_HEAD, strlen(CODE_TABLE_HEAD)) != 0) {
00180               close(fd);
00181               if( make_code_table(im[imid], ct_file_name) == -1) return -1;
00182               return 0;
00183        }
00184        read(fd, &tablen, sizeof(int));
00185        read(fd, &data_len, sizeof(int));
00186        read(fd, &max_len, sizeof(int));
00187        read(fd, im[imid]->tab_idx, sizeof(table_index) * MAXIDX);
00188        im[imid]->c_tab = (code_table *) malloc(sizeof(code_table) * tablen);
00189        im[imid]->data = (char *) malloc(data_len);
00190        read(fd, im[imid]->c_tab, sizeof(code_table) * tablen);
00191        read(fd, im[imid]->data, data_len);
00192        close(fd);
00193        return 0;
00194 }
00195 
00196 find_candidate(imid, str, low, high)
00197 int           imid;
00198 unsigned char   *str;
00199 int             *low;
00200 int             *high;
00201 {
00202        int     d, i, h, l;
00203 
00204        for (l = im[imid]->tab_idx[idx(str[0]) - 1].edge,
00205            h = im[imid]->tab_idx[idx(str[0])].edge - 1; l < h; ) {
00206               i = (l + h) / 2;
00207               if ((d = match(imid, (char *)&str[1], i)) == 0)
00208                      break;
00209               if (d > 0)
00210                      l = i + 1;
00211               else h = i - 1;
00212        }
00213 
00214        if (l < h) {
00215               for (l = i; l > im[imid]->tab_idx[idx(str[0]) - 1].edge; l--) {
00216                      if (match(imid, (char *)&str[1], l-1) != 0)
00217                             break;
00218               }
00219               for (h = i; h < im[imid]->tab_idx[idx(str[0])].edge - 1; h++) {
00220                      if (match(imid, (char *)&str[1], h+1) != 0)
00221                             break;
00222               }
00223               *low = l;
00224               *high = h;
00225               return;
00226        }
00227 
00228        if (l == h && match(imid, (char *)&str[1], l) == 0) {
00229               *low = *high = l;
00230               return;
00231        }
00232 
00233        *low = 1;
00234        *high = 0;
00235 }
00236 
00237 match(imid, keystr, idx)
00238 int     imid;
00239 char    *keystr;
00240 int     idx;
00241 {
00242        code_table      *ct_item = (code_table *) &(im[imid]->c_tab[idx]);
00243        char            *data = im[imid]->data;
00244        int     i;
00245        int     len = strlen(keystr);
00246        char    *tab_str, buf[8];
00247 
00248        if (ct_item->key & KEYSTR_MASK) {
00249               tab_str = (char *)(ct_item->key - KEYSTR_MASK + data);
00250        } else {
00251               for (i = 0; i < 4; i++) {
00252                      buf[i] = (ct_item->key >> (7 * (3 - i))) & 0x7f;
00253               }
00254               buf[4] = '\0';
00255               tab_str = buf;
00256        }
00257 
00258        return strncmp(keystr, tab_str,len);
00259 }
00260 
00261 make_selections(imid, selections, low, high, dir, len, encode, max_number)
00262 int    imid;
00263 char    **selections;
00264 int     *low, high;
00265 int     dir;
00266 int     len;
00267 char*   encode;
00268 int    max_number;
00269 {
00270        int     i, j, k;
00271        char    *p, buf[64], t[64], t1[64];
00272        int     number;
00273        int    direction;
00274        int    flag;
00275 
00276 #ifdef DEBUG
00277 printf("high = %d, low = %d, dir = %d, encode = %s\n", high, *low, dir, encode);
00278 #endif
00279 
00280        if(dir == 1) {
00281               number = high - *low + 1;
00282               direction = 1;
00283        }
00284        else {
00285               number = *low - high + 1;
00286               direction = -1;
00287        }
00288        for (i = 0, j = 0; (i * direction) < number; i += direction) {
00289               flag = 0;
00290               p = (char *)(im[imid]->data +
00291                   im[imid]->c_tab[*low + i].code);
00292               if (len == 0 || keylen(im[imid]->c_tab[*low + i].key, *encode, p, buf) >= len) {
00293                      if (len != 0) p = buf;
00294                      sscanf(p, "%s%s", t, t1);
00295                      if((len != 0) && (len < strlen(encode))) {
00296                             for(k = len; k < strlen(encode); k ++) {
00297                                    if(!t1[k]) { flag = 1; break; }
00298                                    else if((encode[k] != encode[len - 1]) && (t1[k] != encode[k])) { 
00299                                           flag = 1; break; 
00300                                    }
00301                             }
00302                      }
00303                      if(!flag) {
00304                             strcpy(selections[j], p);
00305 #ifdef DEBUG
00306 printf("%s \n", selections[j]);
00307 #endif
00308                             selections[j][20] = '\0';
00309                             j++;
00310                      }
00311               }
00312               if(j == max_number) {
00313                      i += direction;
00314                      break;
00315               }
00316        }
00317 #ifdef DEBUG
00318 printf("\n j = %d\n", j);
00319 #endif
00320        *low += i;
00321 #ifdef DEBUG
00322 printf("\n low = %d\n", *low);
00323 #endif
00324        if (j == 0) return 0;
00325        if(direction == -1) {
00326               for(i = 0; i < j / 2; i ++) {
00327                      strcpy(t, selections[i]);
00328                      strcpy(selections[i], selections[j - i - 1]);
00329                      strcpy(selections[j - i - 1], t);
00330               }
00331        }
00332        return j;
00333 }
00334 
00335 keylen(k, fc, cstr, buf)
00336 int     k;
00337 char    fc, *cstr, *buf;
00338 {
00339        int     i;
00340        char    c, *s;
00341 
00342        sprintf(buf, "%s %c", cstr, fc);
00343        s = &buf[strlen(buf)];
00344        for (i = 1; i < 5; i++) {
00345               if ((c = ((k >> (4 - i) * 7) & 0x7f)) == 0)
00346                      break;
00347               *s++ = c;
00348        }
00349        *s = '\0';
00350        return i;
00351 }
00352