Back to index

im-sdk  12.3.91
IMLSubr.c
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include "SunIM.h"
00008 
00009 /***************************************
00010       duplicate handlers
00011 ***************************************/
00012 
00013 static iml_inst*
00014 imli_duplicate_short(
00015     iml_inst *pinst
00016 )
00017 {
00018     const int size = sizeof(iml_inst);
00019     iml_inst *pr = (iml_inst*) malloc(size);
00020     if (!pr) return NULL;
00021     memcpy(pr, pinst, size);
00022     return pr;
00023 }
00024 
00025 static iml_inst*
00026 imli_duplicate_set_status(
00027     iml_inst *pinst
00028 )
00029 {
00030     const int size = sizeof(iml_inst) + sizeof(iml_status_t);
00031     iml_inst *pr = (iml_inst*) malloc(size);
00032     if (!pr) return NULL;
00033     memcpy(pr, pinst, size);
00034     return pr;
00035 }
00036 
00037 static iml_inst*
00038 imli_duplicate_keypress(
00039     iml_inst *pinst
00040 )
00041 {
00042     const int size = sizeof(iml_inst) + sizeof(IMKeyEventStruct) + 1;
00043     iml_inst *pr = (iml_inst*) malloc(size);
00044     if (!pr) return NULL;
00045     memcpy(pr, pinst, size);
00046     return pr;
00047 }
00048 
00049 static iml_inst*
00050 imli_duplicate_preedit_draw(
00051     iml_inst *pinst
00052 )
00053 {
00054     IMPreeditDrawCallbackStruct *pd1, *pd2;
00055     const int size = sizeof(iml_inst) + sizeof(IMPreeditDrawCallbackStruct);
00056     iml_inst *pr = (iml_inst*) malloc(size);
00057     if (!pr) return NULL;
00058     memcpy(pr, pinst, size);
00059     pd1 = (IMPreeditDrawCallbackStruct*) &pr->operand;
00060     pd2 = (IMPreeditDrawCallbackStruct*) &pinst->operand;
00061     if (pd2->text) {
00062        pd1->text = IMText_duplicate(pd2->text);
00063        if (!pd1->text) {
00064            free(pr);
00065            return NULL;
00066        }
00067     }
00068     return pr;
00069 }
00070 
00071 static iml_inst*
00072 imli_duplicate_status_draw(
00073     iml_inst *pinst
00074 )
00075 {
00076     const int size = sizeof(iml_inst) + sizeof(IMStatusDrawCallbackStruct);
00077     IMStatusDrawCallbackStruct *pd1, *pd2;
00078     iml_inst *pr = (iml_inst*) malloc(size);
00079     if (!pr) return NULL;
00080     memcpy(pr, pinst, size);
00081     pd1 = (IMStatusDrawCallbackStruct*) &pr->operand;
00082     pd2 = (IMStatusDrawCallbackStruct*) &pinst->operand;
00083     pd1->text = IMText_duplicate(pd2->text);
00084     if (!pd1->text) {
00085        free(pr);
00086        return NULL;
00087     }
00088     return pr;
00089 }
00090 
00091 static iml_inst*
00092 imli_duplicate_lookup_start(
00093     iml_inst *pinst
00094 )
00095 {
00096     const int size = sizeof(iml_inst) + sizeof(IMLookupStartCallbackStruct);
00097     iml_inst *pr = (iml_inst*) malloc(size);
00098     if (!pr) return NULL;
00099     memcpy(pr, pinst, size);
00100     return pr;
00101 }
00102 
00103 static iml_inst*
00104 imli_duplicate_lookup_draw(
00105     iml_inst *pinst
00106 )
00107 {
00108     const int size = sizeof(iml_inst) + sizeof(IMLookupDrawCallbackStruct);
00109     int i;
00110     IMLookupDrawCallbackStruct *pd1, *pd2;
00111     IMChoiceObject *pc1, *pc2;
00112     iml_inst *pr;
00113 
00114     pr = (iml_inst*) malloc(size);
00115     if (!pr) return NULL;
00116     memcpy(pr, pinst, size);
00117     pd1 = (IMLookupDrawCallbackStruct*) &pr->operand;
00118     pd2 = (IMLookupDrawCallbackStruct*) &pinst->operand;
00119     pc1 = (IMChoiceObject*) malloc(sizeof(IMChoiceObject) * pd1->n_choices);
00120     pc2 = pd2->choices;
00121     if (!pc1) goto memory_error;
00122     memset(pc1, 0, sizeof(IMChoiceObject) * pd1->n_choices);
00123     pd1->choices = pc1;
00124 
00125     for (i = 0; i < pd1->n_choices; i++, pc1++, pc2++) {
00126        pc1->label = IMText_duplicate(pc2->label);
00127        if (!pc1->label) goto memory_error;
00128        pc1->value = IMText_duplicate(pc2->value);
00129        if (!pc1->value) goto memory_error;
00130     }
00131 
00132     return pr;
00133 
00134 memory_error:
00135     if (pd1->choices) {
00136        for (i = 0, pc1 = pd1->choices; i < pd1->n_choices; i++, pc1++) {
00137            if (pc1->label) IMText_delete(pc1->label);
00138            if (pc1->value) IMText_delete(pc1->value);
00139        }
00140        free(pd1->choices);
00141     }
00142 
00143     free(pr);
00144     return NULL;
00145 }
00146 
00147 static iml_inst*
00148 imli_duplicate_lookup_process(
00149     iml_inst *pinst
00150 )
00151 {
00152     const int size = sizeof(iml_inst) + sizeof(IMLookupProcessCallbackStruct);
00153     iml_inst *pr = (iml_inst*) malloc(size);
00154     if (!pr) return NULL;
00155     memcpy(pr, pinst, size);
00156     return pr;
00157 }
00158 
00159 static iml_inst*
00160 imli_duplicate_aux_basic(
00161     iml_inst *pinst
00162 )
00163 {
00164     IMAuxBasicCallbackStruct *pd1, *pd2;
00165     const int size = sizeof(iml_inst) + sizeof(IMAuxBasicCallbackStruct);
00166     iml_inst *pr = (iml_inst*) malloc(size);
00167     if (!pr) return NULL;
00168     memcpy(pr, pinst, size);
00169     pd1 = (IMAuxBasicCallbackStruct*) &pr->operand;
00170     pd2 = (IMAuxBasicCallbackStruct*) &pinst->operand;
00171     pd1->aux_name = strdup(pd1->aux_name);
00172     if (!pd1->aux_name) {
00173        free(pr);
00174        return NULL;
00175     }
00176     return pr;
00177 }
00178 
00179 static iml_inst*
00180 imli_duplicate_ns_listener(
00181     iml_inst *pinst
00182 )
00183 {
00184     IMNSListenerStruct *rn1, *rn2;
00185 
00186     const int size = sizeof(iml_inst) + sizeof(IMNSListenerStruct);
00187     iml_inst *pr = (iml_inst*) malloc(size);
00188     if (!pr) return NULL;
00189     memcpy(pr, pinst, size);
00190     rn1 = (IMNSListenerStruct *) &pr->operand;
00191     rn2 = (IMNSListenerStruct *) &pinst->operand;
00192     rn1->filename = strdup(rn2->filename);
00193     if (!rn1->filename) {
00194        free(pr);
00195        return NULL;
00196     }
00197     return pr;
00198 }
00199 
00200 static iml_inst*
00201 imli_duplicate_aux_draw(
00202     iml_inst *pinst
00203 )
00204 {
00205     IMAuxDrawCallbackStruct *pd1, *pd2;
00206     const int size = sizeof(iml_inst) + sizeof(IMAuxDrawCallbackStruct);
00207     iml_inst *pr = (iml_inst*) malloc(size);
00208     if (!pr) return NULL;
00209     memcpy(pr, pinst, size);
00210     pd1 = (IMAuxDrawCallbackStruct*) &pr->operand;
00211     pd2 = (IMAuxDrawCallbackStruct*) &pinst->operand;
00212 
00213     pd1->aux_name = strdup(pd1->aux_name);
00214     if (!pd1->aux_name) goto memory_error1;
00215 
00216     if (pd2->integer_values) {
00217        pd1->integer_values = malloc(sizeof(int) * pd1->count_integer_values);
00218        if (!pd1->integer_values) goto memory_error2;
00219        memcpy(pd1->integer_values, pd2->integer_values, 
00220               sizeof(int) * pd1->count_integer_values);
00221     }
00222 
00223     if (pd2->string_values) {
00224        int i;
00225        IMText *ptext1 = malloc(sizeof(IMText) * pd2->count_string_values);
00226        IMText *ptext2 = pd2->string_values;
00227        if (!ptext1) goto memory_error3;
00228        pd1->string_values = ptext1;
00229 
00230        for (i = 0; i < pd2->count_string_values; i++, ptext1++, ptext2++) {
00231            if (!IMText_duplicate2(ptext1, ptext2)) {
00232               int i2;
00233               ptext1 = pd1->string_values;
00234               for (i2 = 0; i2 < i; i2++, ptext1++) {
00235                   IMText_delete2(ptext1);
00236               }
00237               free(pd1->string_values);
00238               goto memory_error3;
00239            }
00240        }
00241     }
00242     return pr;
00243 
00244 memory_error3:
00245     free(pd1->integer_values);
00246 memory_error2:
00247     free(pd1->aux_name);
00248 memory_error1:
00249     free(pr);
00250     return NULL;
00251 }
00252 
00253 static iml_inst*
00254 imli_duplicate_operand_imtext(
00255     iml_inst *pinst
00256 )
00257 {
00258     IMText *pd1, *pd2;
00259     const int size = sizeof(iml_inst) + sizeof(IMText);
00260     iml_inst *pr = (iml_inst*) malloc(size);
00261     if (!pr) return NULL;
00262     memcpy(pr, pinst, size);
00263     pd1 = (IMText*) &pr->operand;
00264     pd2 = (IMText*) &pinst->operand;
00265     if (!IMText_duplicate2(pd1, pd2)) {
00266        free(pr);
00267        return NULL;
00268     }
00269 
00270     return pr;
00271 }
00272 
00273 iml_inst*
00274 iml_duplicate_inst(
00275     iml_inst *pinst
00276 )
00277 {
00278     int op = pinst->opcode & ~IMM_CB_RESULT_REQUIRED;
00279 
00280     switch (op) {
00281       case IMM_KEYPRESS:
00282        return imli_duplicate_keypress(pinst);
00283       case IMM_COMMIT:
00284       case IMM_RESET_RETURN:
00285        return imli_duplicate_operand_imtext(pinst);
00286       case IMM_SET_STATUS:
00287        return imli_duplicate_set_status(pinst);
00288       case IMM_PREEDIT_DRAW:
00289        return imli_duplicate_preedit_draw(pinst);
00290       case IMM_STATUS_DRAW:
00291        return imli_duplicate_status_draw(pinst);
00292       case IMM_LOOKUP_START:
00293        return imli_duplicate_lookup_start(pinst);
00294       case IMM_LOOKUP_DRAW:
00295        return imli_duplicate_lookup_draw(pinst);
00296       case IMM_LOOKUP_PROCESS:
00297        return imli_duplicate_lookup_process(pinst);
00298       case IMM_AUX_START_2:
00299       case IMM_AUX_DONE_2:
00300        return  imli_duplicate_aux_basic(pinst);
00301       case IMM_AUX_DRAW_2:
00302        return imli_duplicate_aux_draw(pinst);
00303       case IMM_NS_LISTENER:
00304        return imli_duplicate_ns_listener(pinst);
00305       default:
00306        return imli_duplicate_short(pinst);
00307     }
00308 
00309     /* notreached */
00310     return NULL;
00311 }
00312 
00313 /***************************************
00314       delete handlers
00315 ***************************************/
00316 
00317 static void
00318 imli_delete_short(
00319     iml_inst *pinst
00320 )
00321 {
00322     free(pinst);
00323 }
00324 
00325 static void
00326 imli_delete_preedit_draw(
00327     iml_inst *pinst
00328 )
00329 {
00330     IMPreeditDrawCallbackStruct *pd = (IMPreeditDrawCallbackStruct*) &pinst->operand;
00331     if (pd->text) IMText_delete(pd->text);
00332     free(pinst);
00333     return;
00334 }
00335 
00336 static void
00337 imli_delete_status_draw(
00338     iml_inst *pinst
00339 )
00340 {
00341     IMStatusDrawCallbackStruct *pd = (IMStatusDrawCallbackStruct*) &pinst->operand;
00342     if (pd->text) IMText_delete(pd->text);
00343     free(pinst);
00344     return;
00345 }
00346 
00347 static void
00348 imli_delete_lookup_draw(
00349     iml_inst *pinst
00350 )
00351 {
00352     IMLookupDrawCallbackStruct *pd = (IMLookupDrawCallbackStruct*) &pinst->operand;
00353     if (pd->choices) {
00354        IMChoiceObject *pc;
00355        int i;
00356        for (i = 0, pc = pd->choices; i < pd->n_choices; i++, pc++) {
00357            if (pc->label) IMText_delete(pc->label);
00358            if (pc->value) IMText_delete(pc->value);
00359        }
00360        free(pd->choices);
00361     }
00362     free(pinst);
00363     return;
00364 }
00365 
00366 static void
00367 imli_delete_aux_basic(
00368     iml_inst *pinst
00369 )
00370 {
00371     IMAuxBasicCallbackStruct *pd = (IMAuxBasicCallbackStruct*) &pinst->operand;
00372     free(pd->aux_name);
00373     free(pinst);
00374     return;
00375 }
00376 
00377 static void
00378 imli_delete_aux_draw(
00379     iml_inst *pinst
00380 )
00381 {
00382     IMAuxDrawCallbackStruct *pd = (IMAuxDrawCallbackStruct*) &pinst->operand;
00383     free(pd->aux_name);
00384     if (pd->integer_values) free(pd->integer_values);
00385     if (pd->string_values) {
00386        int i;
00387        IMText *ptext = pd->string_values;
00388        for (i = 0; i < pd->count_string_values; i++, ptext++) {
00389            IMText_delete2(ptext);
00390        }
00391        free(pd->string_values);
00392     }
00393     free(pinst);
00394     return;
00395 }
00396 
00397 static void
00398 imli_delete_operand_imtext(
00399     iml_inst *pinst
00400 )
00401 {
00402     IMText *pd = (IMText*) &pinst->operand;
00403     IMText_delete2(pd);
00404     free(pinst);
00405     return;
00406 }
00407 
00408 void
00409 iml_delete_inst(
00410     iml_inst *pinst
00411 )
00412 {
00413     int op = pinst->opcode & ~IMM_CB_RESULT_REQUIRED;
00414 
00415     switch (op) {
00416       case IMM_COMMIT:
00417       case IMM_RESET_RETURN:
00418        imli_delete_operand_imtext(pinst);
00419        return;
00420       case IMM_PREEDIT_DRAW:
00421        imli_delete_preedit_draw(pinst);
00422        return;
00423       case IMM_STATUS_DRAW:
00424        imli_delete_status_draw(pinst);
00425        return;
00426       case IMM_LOOKUP_DRAW:
00427        imli_delete_lookup_draw(pinst);
00428        return;
00429       case IMM_AUX_START_2:
00430       case IMM_AUX_DONE_2:
00431        imli_delete_aux_basic(pinst);
00432        return;
00433       case IMM_AUX_DRAW_2:
00434        imli_delete_aux_draw(pinst);
00435        return;
00436       case IMM_KEYPRESS:
00437       case IMM_LOOKUP_PROCESS:
00438       case IMM_LOOKUP_START:
00439       case IMM_SET_STATUS:
00440       default:
00441        imli_delete_short(pinst);
00442        return;
00443     }
00444 
00445     /* notreached */
00446     return;
00447 }
00448 
00449 /***************************************
00450       IMText functions.
00451 ***************************************/
00452 
00453 int
00454 IMText_duplicate2(
00455     IMText *pdest, IMText *psrc
00456 )
00457 {
00458     int i, j;
00459     IMFeedbackList *pfbl;
00460     IMFeedbackList *pfbls;
00461 
00462     *pdest = *psrc;
00463     pdest->text.utf_chars = NULL;
00464     pdest->feedback = NULL;
00465     pdest->annotations = NULL;
00466 
00467     if (psrc->char_length > 0) {
00468        if (psrc->text.utf_chars) {
00469            UTFCHAR *pu = (UTFCHAR*) malloc(sizeof(UTFCHAR)
00470                                        * psrc->char_length);
00471            if (!pu) {
00472               IMText_delete2(pdest);
00473               return 0;
00474            }
00475            memcpy(pu, psrc->text.utf_chars, sizeof(UTFCHAR) * psrc->char_length);
00476            pdest->text.utf_chars = pu;
00477        }
00478 
00479        if (psrc->feedback) {
00480            pfbl = (IMFeedbackList*) malloc(sizeof(IMFeedbackList)
00481                                        * psrc->char_length);
00482            if (!pfbl) {
00483               IMText_delete2(pdest);
00484               return 0;
00485            }
00486            memset(pfbl, 0, sizeof(IMFeedbackList) * psrc->char_length);
00487            pdest->feedback = pfbl;
00488 
00489            pfbls = psrc->feedback;
00490            for (i = 0;
00491                i < psrc->char_length;
00492                i++, pfbl++, pfbls++) {
00493               if (pfbls->count_feedbacks > 0) {
00494                   pfbl->feedbacks = (IMFeedback*) malloc(sizeof(IMFeedback) * pfbls->count_feedbacks);
00495                   if (!pfbl->feedbacks) {
00496                      IMText_delete2(pdest);
00497                      return 0;
00498                   }
00499                   memcpy(pfbl->feedbacks, pfbls->feedbacks,
00500                         sizeof(IMFeedback) * pfbls->count_feedbacks);
00501                   pfbl->count_feedbacks = pfbls->count_feedbacks;
00502               }
00503            }
00504        }
00505     }
00506 
00507     if (psrc->count_annotations > 0) {
00508        IMAnnotation *pima, *pimas;
00509        IMAnnotationValue *pimavs;
00510 
00511        pima = (IMAnnotation*) malloc(sizeof(IMAnnotation)
00512                                   * psrc->count_annotations);
00513        if (!pima) {
00514            IMText_delete2(pdest);
00515            return 0;
00516        }
00517        memset(pima, 0, sizeof(IMAnnotation) * psrc->count_annotations);
00518        pdest->annotations = pima;
00519        pimas = psrc->annotations;
00520        for (i = 0;
00521             i < psrc->count_annotations;
00522             i++, pima++, pimas++) {
00523            IMAnnotationValue *pimav = (IMAnnotationValue*) malloc(sizeof(IMAnnotationValue)
00524                                                            * pimas->num_values);
00525            if (!pimav) {
00526               IMText_delete2(pdest);
00527               return 0;
00528            }
00529            memset(pimav, 0, sizeof(IMAnnotationValue) * pimas->num_values);
00530            *pima = *pimas;
00531            pima->values = pimav;
00532            pimavs = pimas->values;
00533            for (j = 0;
00534                j < pimas->num_values;
00535                j++, pimav++, pimavs++) {
00536               *pimav = *pimavs;
00537               pimav->value = malloc(pimav->len);
00538               if (!pimav->value) {
00539                   IMText_delete2(pdest);
00540                   return 0;
00541               }
00542               memcpy(pimav->value, pimavs->value, pimav->len);
00543            }
00544        }
00545     }
00546 
00547     return 1;
00548 }
00549 
00550 IMText*
00551 IMText_duplicate(
00552     IMText *psrc
00553 )
00554 {
00555     IMText *pdest;
00556 
00557     if (!psrc) return NULL;
00558 
00559     pdest = (IMText*) malloc(sizeof(IMText));
00560     if (!pdest) return NULL;
00561     if (!IMText_duplicate2(pdest, psrc)) {
00562        free(pdest);
00563        return NULL;
00564     }
00565     return pdest;
00566 }
00567 
00568 void
00569 IMText_delete2(
00570     IMText *ptext
00571 )
00572 {
00573     int i, j;
00574 
00575     if (ptext->text.utf_chars)
00576        free(ptext->text.utf_chars);
00577 
00578     if (ptext->feedback) {
00579        IMFeedbackList *pfbl = ptext->feedback;
00580        for (i = 0;
00581             i < ptext->char_length;
00582             i++, pfbl++) {
00583            if (pfbl->feedbacks) free(pfbl->feedbacks);
00584        }
00585        free(ptext->feedback);
00586     }
00587 
00588     if (ptext->annotations) {
00589        IMAnnotation *pima = ptext->annotations;
00590        for (i = 0;
00591             i < ptext->count_annotations;
00592             i++, pima++) {
00593            IMAnnotationValue *pimav = pima->values;
00594            for (j = 0;
00595                j < pima->num_values;
00596                j++, pimav++) {
00597               if (pimav->value) free(pimav->value);
00598            }
00599            if (pima->values) free(pima->values);
00600        }
00601        free(ptext->annotations);
00602     }
00603 }
00604 
00605 void
00606 IMText_delete(
00607     IMText *ptext
00608 )
00609 {
00610     IMText_delete2(ptext);
00611     free(ptext);
00612 }
00613 
00614 /* Local Variables: */
00615 /* c-file-style: "iiim-project" */
00616 /* End: */