Back to index

im-sdk  12.3.91
neima_filter.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <iconv.h>
00003 
00004 #include "ime.h"
00005 #include "ime_buffer.h"
00006 
00007 #define PREFIX_COMPLETE     (0x20000)
00008 #define PREFIX_VALID        (0x10000)
00009 #define HEXCANDIDATES       (0x0FFFF)
00010 
00011 //lower 16 bit return value mask '0..9A..F' possiblities.
00012 //    When return valid, lower 16 bit contains value only when incoming hex-char
00013 //         could make the hex-string valid character.
00014 //    When non-valid or complete, lower 16 bit is of no use
00015 typedef int (*VALIDATE_PREFIX_FUNC)(unsigned char*);
00016 
00017 int validate_prefix_gb2312(unsigned char *prefix);
00018 int validate_prefix_gbk(unsigned char *prefix);
00019 int validate_prefix_gb18030(unsigned char *prefix);
00020 int validate_prefix_big5(unsigned char *prefix);
00021 int validate_prefix_big5hkscs(unsigned char *prefix);
00022 int validate_prefix_euctw(unsigned char *prefix);
00023 
00024 static unsigned char number_string[] = "0123456789ABCDEF";
00025 
00026 VALIDATE_PREFIX_FUNC validators[] = {  // Please check the definition of ImeEncoding
00027     validate_prefix_gb2312,
00028     validate_prefix_gbk,
00029     validate_prefix_gb18030,
00030     validate_prefix_big5,
00031     validate_prefix_big5hkscs,
00032     validate_prefix_euctw
00033 };
00034 
00035 int validate_prefix(int encode, unsigned char *prefix)
00036 {
00037     if (encode >= ENCODE_GB2312 && encode <= ENCODE_EUCTW)
00038         return validators[encode](prefix);
00039     return 0;
00040 }
00041 
00042 #define HEXVALUE(c)     ((c >= 'A')?(c-'A'+10):(c-'0'))
00043 int commit_all(ImeBufferRec *ime_buffer)
00044 {
00045     unsigned char *p = ime_buffer->preedit.preedit.text, *dst =ime_buffer->commit_buf;
00046 
00047     for(; *p; p+=2)
00048         *dst++ = (HEXVALUE(*p) << 4) + HEXVALUE(*(p+1));
00049     *dst = 0;
00050 
00051     ime_buffer->preedit.preedit.text[0] = '\0';
00052     ime_buffer->preedit.caret = 0;
00053     ime_buffer->candidates.count = 0;
00054     ime_buffer->return_status |= (IME_COMMIT | IME_PREEDIT_AREA | IME_LOOKUP_AREA);
00055 }
00056 
00057 int neima_filter(int encoding, unsigned char key, ImeBufferRec *ime_buffer)
00058 {
00059     int  i, ret, preedit_len;
00060     unsigned char *p, *dst;
00061 
00062     ime_buffer->return_status = 0;
00063     preedit_len = strlen(ime_buffer->preedit.preedit.text);
00064 
00065     DEBUG_printf("    ====>neima: filter key(0x%x)\n", key);
00066     if ((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F')) {
00067         DEBUG_printf("        ====>neima:ime_buffer->preedit.preedit.text: %s (len=%d) key=%c(0x%x)\n", ime_buffer->preedit.preedit.text, preedit_len, key, key);
00068 
00069         ime_buffer->preedit.preedit.text[preedit_len] = toupper(key);
00070         ime_buffer->preedit.preedit.text[++preedit_len] = 0;
00071 
00072         ret = validate_prefix(encoding, ime_buffer->preedit.preedit.text);
00073         DEBUG_printf("        ====>Validating Key...result 0x%x...", ret);
00074         if (!(ret & PREFIX_VALID)) {
00075             DEBUG_printf("Invalid\n", key);
00076             ime_buffer->preedit.preedit.text[--preedit_len] = 0;
00077             return IME_INVALID_KEY;
00078         }
00079         DEBUG_printf("valid Key\n", key);
00080         DEBUG_printf("        ====>neima:ime_buffer->preedit.preedit.text: %s (len=%d) key=%c(0x%x)\n", ime_buffer->preedit.preedit.text, preedit_len, key, key);
00081 
00082         ime_buffer->preedit.caret = preedit_len;
00083         ime_buffer->return_status |= IME_PREEDIT_AREA;
00084 
00085         if (ret & PREFIX_COMPLETE) {
00086             printf("  [Neima IME] Commit all...\n");
00087             commit_all(ime_buffer);
00088         } else if (ret & PREFIX_VALID) {
00089             ime_buffer->candidates.count = 0;
00090             ime_buffer->candidates.page_state = ImeCandidatesFirstPage | ImeCandidatesLastPage;
00091             for (i=0; i < 16; ++i) {
00092                 if (ret & 1) {
00093                     dst = ime_buffer->candidates.candidates[ime_buffer->candidates.count].text;
00094                     for(p=ime_buffer->preedit.preedit.text; *p && *(p+1); p+=2)
00095                         *dst++ = (HEXVALUE(*p) << 4) + HEXVALUE(*(p+1));
00096                     *dst++ = (HEXVALUE(*p) << 4) + i;
00097                     *dst = 0;
00098                     ime_buffer->candidates.numbers[ime_buffer->candidates.count] = number_string[i];
00099                     ime_buffer->candidates.numbers[ime_buffer->candidates.count+1] = 0;
00100                     ++ime_buffer->candidates.count;
00101                 }
00102                 ret >>= 1;
00103             }
00104             printf("    ====%d Candidates\n",  ime_buffer->candidates.count);
00105             if (ime_buffer->candidates.count) {
00106                 ime_buffer->return_status |= IME_LOOKUP_AREA;
00107 
00108                 #ifdef DEBUG
00109                 for (i=0; i < ime_buffer->candidates.count; ++i) {
00110                     printf("          %c %s\n", 
00111                           ime_buffer->candidates.numbers[i], 
00112                           ime_buffer->candidates.candidates[i].text);
00113                 }
00114                 #endif
00115             }
00116         }
00117         return(IME_OK);
00118     }
00119 
00120     if(key == IME_FILTERED_KEY_ESCAPE && preedit_len > 0) {
00121         clear_ime_buffer(ime_buffer);
00122         ime_buffer->return_status |= (IME_PREEDIT_AREA | IME_LOOKUP_AREA);
00123         return (IME_OK);
00124     }
00125 
00126     if ((key == IME_FILTERED_KEY_BACKSPACE || key == IME_FILTERED_KEY_DELETE) && (preedit_len > 0)) {
00127         ime_buffer->preedit.preedit.text[--preedit_len] = '\0';
00128         ime_buffer->return_status = IME_PREEDIT_AREA;
00129         ime_buffer->candidates.count = 0;
00130         ime_buffer->return_status |= IME_LOOKUP_AREA;
00131         return(IME_OK);
00132     }
00133 
00134     return (preedit_len == 0)?(IME_UNUSED_KEY):(IME_INVALID_KEY);
00135 }
00136 
00137 
00138 
00139 int validate_prefix_gb2312(unsigned char *prefix)
00140 {
00141     int idx, ret;
00142 
00143     for (idx = 0; *prefix; ++prefix, ++idx) {
00144         switch (idx) {
00145         case 0:
00146             if (*prefix < 'A' || *prefix > 'F')
00147                 return 0;
00148             break;
00149         case 1:
00150             if ((*(prefix-1) == 'A' && *prefix == '0') || (*(prefix-1) == 'F' && *prefix > '7'))
00151                 return 0;
00152             break;
00153         case 2:
00154             if (*prefix < 'A' || *prefix > 'F')
00155                 return 0;
00156             break;
00157         case 3:
00158             if ((*(prefix-1) == 'A' && *prefix == '0') || (*(prefix-1) == 'F' && *prefix == 'F'))
00159                 return 0;
00160             break;
00161         default:
00162             return 0;
00163         }
00164     }
00165     ret = PREFIX_VALID;
00166     if (idx == 3) {
00167         ret |= HEXCANDIDATES;
00168         if (*(prefix-1) == 'F') ret ^= 0x8000;
00169         if (*(prefix-1) == 'A') ret ^= 0x0001;
00170     } else if (idx == 4) {
00171         ret |= PREFIX_COMPLETE;
00172     }
00173     return ret;
00174 }
00175 
00176 int validate_prefix_gbk(unsigned char *prefix)
00177 {
00178     int idx, ret;
00179 
00180     for (idx = 0; *prefix; ++prefix, ++idx) {
00181         switch (idx) {
00182         case 0:
00183             if (*prefix < '8' || *prefix > 'F')
00184                 return 0;
00185             break;
00186         case 1:
00187             if ((*(prefix-1) == '8' && *prefix == '0') || (*(prefix-1) == 'F' && *prefix >= 'F'))
00188                 return 0;
00189             break;
00190         case 2:
00191             if (*prefix < '4' || *prefix > 'F')
00192                 return 0;
00193             break;
00194         case 3:
00195             if ((*(prefix-1) == '7' || *(prefix-1) == 'F') && *prefix >= 'F')
00196                 return 0;
00197             break;
00198         default:
00199             return 0;
00200         }
00201     }
00202     ret = PREFIX_VALID;
00203     if (idx == 3) {
00204         ret |= HEXCANDIDATES;
00205         if (*(prefix-1) == 'F' || *(prefix-1) == '7')
00206             ret ^= 0x8000;      //F could not be used
00207     } else if (idx == 4) {
00208         ret |= PREFIX_COMPLETE;
00209     }
00210     return ret;
00211 }
00212 
00213 int validate_prefix_gb18030(unsigned char *prefix)
00214 {
00215     int idx, ret;
00216 
00217     ret = validate_prefix_gbk(prefix);
00218     if (ret & PREFIX_VALID)
00219         return ret;
00220     for (idx = 0; *prefix; ++prefix, ++idx) {
00221         switch (idx) {
00222         case 0:
00223         case 4:
00224             if (*prefix < '8' || *prefix > 'F')
00225                 return 0;
00226             break;
00227         case 1:
00228         case 5:
00229             if ((*(prefix-1) == '8' && *prefix == '0') || (*(prefix-1) == 'F' && *prefix >= 'F'))
00230                 return 0;
00231             break;
00232         case 2:
00233         case 6:
00234             if (*prefix !='3')
00235                 return 0;
00236             break;
00237         case 3:
00238         case 7:
00239             if (*prefix < '0' || *prefix > '9')
00240                 return 0;
00241             break;
00242         default:
00243             return 0;
00244         }
00245     }
00246     ret = PREFIX_VALID;
00247     if (idx == 7) {
00248         ret |= 0x3FF;  //0~9
00249     } else if (idx == 8) {
00250         ret |= PREFIX_COMPLETE;
00251     }
00252     return ret;
00253 }
00254 
00255 int validate_prefix_big5(unsigned char *prefix)
00256 {
00257     int idx, ret;
00258 
00259     for (idx = 0; *prefix; ++prefix, ++idx) {
00260         switch (idx) {
00261         case 0:
00262             if (*prefix < 'A' || *prefix > 'F')
00263                 return 0;
00264             break;
00265         case 1:
00266             if ((*(prefix-1) == 'A' && *prefix == '0') || (*(prefix-1) == 'F' && *prefix > 'E'))
00267                 return 0;
00268             break;
00269         case 2:
00270             if (*prefix < '4' || *prefix > 'F' || *prefix == '8' || *prefix == '9')
00271                 return 0;
00272             break;
00273         case 3:
00274             if ((*(prefix-1) == '7' && *prefix == 'F') 
00275                      || (*(prefix-1) == 'A' && *prefix == '0') 
00276                      || (*(prefix-1) == 'F' && *prefix == 'F'))
00277                 return 0;
00278             break;
00279         default:
00280             return 0;
00281         }
00282     }
00283     ret = PREFIX_VALID;
00284     if (idx == 3) {
00285         ret |= HEXCANDIDATES;
00286         if (*(prefix-1) == 'F' || *(prefix-1)=='7') ret ^= 0x8000;
00287         if (*(prefix-1) == 'A') ret ^= 0x0001;
00288     } else if (idx == 4) {
00289         ret |= PREFIX_COMPLETE;
00290     }
00291     return ret;
00292 }
00293 
00294 int validate_prefix_big5hkscs(unsigned char *prefix)
00295 {
00296     int idx, ret;
00297 
00298     for (idx = 0; *prefix; ++prefix, ++idx) {
00299         switch (idx) {
00300         case 0:
00301             if (*prefix < '8' || *prefix > 'F')
00302                 return 0;
00303             break;
00304         case 1:
00305             if ((*(prefix-1) == '8' && *prefix == '0') 
00306                      || (*(prefix-1) == 'F' && *prefix > 'E'))
00307                 return 0;
00308             break;
00309         case 2:
00310             if (*prefix < '4' || *prefix > 'F')
00311                 return 0;
00312             break;
00313         case 3:
00314             if ((*(prefix-1) == 'F' && *prefix == 'F'))
00315                 return 0;
00316             break;
00317         default:
00318             return 0;
00319         }
00320     }
00321     ret = PREFIX_VALID;
00322     if (idx == 3) {
00323         ret |= HEXCANDIDATES;
00324         if (*(prefix-1) == 'F') ret ^= 0x8000;
00325     } else if (idx == 4) {
00326         ret |= PREFIX_COMPLETE;
00327     }
00328     return ret;
00329 }
00330 
00331 int validate_prefix_euctw(unsigned char *prefix)
00332 {
00333     // we do not support this now
00334     return 0;
00335 }