PhoneBookSearch.c
上传用户:lqx1163
上传日期:2014-08-13
资源大小:9183k
文件大小:182k
源码类别:

MTK

开发平台:

C/C++

  1.             mdi_audio_stop_string();
  2.         }
  3.     #endif /* defined(__MMI_INTELLIGENT_CALL_ALERT__) */ 
  4.     }
  5.     else if (gInsertSimAppFlag != 1
  6. #ifdef __FLIGHT_MODE_SUPPORT__
  7.              && mmi_bootup_get_active_flight_mode() != 1
  8. #endif 
  9.         )
  10.     {
  11.         SetKeyHandler(mmi_phb_list_pre_choose_number, KEY_SEND, KEY_EVENT_UP);
  12.     }
  13.     return result_count;
  14. }
  15. /*****************************************************************************
  16.  * FUNCTION
  17.  *  mmi_phb_quick_search_get_index
  18.  * DESCRIPTION
  19.  *  
  20.  * PARAMETERS
  21.  *  nIndex      [IN]        
  22.  * RETURNS
  23.  *  void
  24.  *****************************************************************************/
  25. void mmi_phb_quick_search_get_index(S32 nIndex)
  26. {
  27.     /*----------------------------------------------------------------*/
  28.     /* Local Variables                                                */
  29.     /*----------------------------------------------------------------*/
  30.     U16 i, count;
  31.     /*----------------------------------------------------------------*/
  32.     /* Code Body                                                      */
  33.     /*----------------------------------------------------------------*/
  34.     count = 0;
  35.     for (i = 0; i < PhoneBookEntryCount; i++)
  36.     {
  37.         /* if(g_phb_qsearch[i] == 1) */
  38.         if (g_phb_qsearch_bitmask[i >> BYTE_SIZE_SHIFT_ARITHMETIC] & (1 << (i % BYTE_SIZE)))
  39.         {
  40.             if (count == nIndex)
  41.             {
  42.                 break;
  43.             }
  44.             count++;
  45.         }
  46.     }
  47.     g_phb_cntx.active_index = i;
  48. #if defined(__MMI_INTELLIGENT_CALL_ALERT__)
  49.     StopTimer(PHB_LIST_SPEAK_NAME_TIMER);
  50.     if (g_phb_is_speaking_name)
  51.     {
  52.         mdi_audio_stop_string();
  53.     }
  54.     if (g_phb_cntx.speak_name)
  55.     {
  56.         StartTimer(PHB_LIST_SPEAK_NAME_TIMER, UI_POPUP_NOTIFYDURATION_TIME, mmi_phb_list_speak_name);
  57.     }
  58. #endif /* defined(__MMI_INTELLIGENT_CALL_ALERT__) */ 
  59. }
  60. /*****************************************************************************
  61.  * FUNCTION
  62.  *  mmi_phb_quick_search_list_pre_entry
  63.  * DESCRIPTION
  64.  *  
  65.  * PARAMETERS
  66.  *  void
  67.  * RETURNS
  68.  *  void
  69.  *****************************************************************************/
  70. void mmi_phb_quick_search_list_pre_entry(void)
  71. {
  72.     /*----------------------------------------------------------------*/
  73.     /* Local Variables                                                */
  74.     /*----------------------------------------------------------------*/
  75.     /*----------------------------------------------------------------*/
  76.     /* Code Body                                                      */
  77.     /*----------------------------------------------------------------*/
  78. #ifdef __SYNCML_SUPPORT__
  79.     if (mmi_syncml_is_phb_sync_now())
  80.     {
  81.         mmi_phb_entry_not_ready(STR_ID_SYNC_PLEASE_WAIT);
  82.     }
  83.     else
  84. #endif /* __SYNCML_SUPPORT__ */
  85.     if (g_phb_cntx.phb_ready && !g_phb_cntx.processing)
  86.     {
  87.         if (PhoneBookEntryCount)
  88.         {
  89.             mmi_phb_entry_quick_search_list();
  90.         }
  91.         else
  92.         {
  93.             DisplayPopup(
  94.                 (PU8) GetString(STR_NO_ENTRIES_MESSAGE),
  95.                 IMG_GLOBAL_EMPTY,
  96.                 TRUE,
  97.                 PHB_NOTIFY_TIMEOUT,
  98.                 EMPTY_LIST_TONE);
  99.         }
  100.     }
  101.     else
  102.     {
  103.         mmi_phb_entry_not_ready(STR_PROCESSING_PHONEBOOK);
  104.     }
  105. }
  106. /*****************************************************************************
  107.  * FUNCTION
  108.  *  mmi_phb_entry_quick_search_list
  109.  * DESCRIPTION
  110.  *  
  111.  * PARAMETERS
  112.  *  void
  113.  * RETURNS
  114.  *  void
  115.  *****************************************************************************/
  116. void mmi_phb_entry_quick_search_list(void)
  117. {
  118.     /*----------------------------------------------------------------*/
  119.     /* Local Variables                                                */
  120.     /*----------------------------------------------------------------*/
  121.     U8 *guiBuffer;
  122.     U16 entryCount;
  123.     /*----------------------------------------------------------------*/
  124.     /* Code Body                                                      */
  125.     /*----------------------------------------------------------------*/
  126.     EntryNewScreen(
  127.         SCR_ID_PHB_QUICK_SEARCH_LIST,
  128.         mmi_phb_exit_quick_search_list,
  129.         mmi_phb_quick_search_list_pre_entry,
  130.         NULL);
  131.     guiBuffer = GetCurrGuiBuffer(SCR_ID_PHB_QUICK_SEARCH_LIST);
  132.     RegisterHighlightHandler(mmi_phb_quick_search_get_index);
  133.     RegisterCat200SearchFunction(mmi_phb_quick_search_find_entry);
  134.     /* First Time enter or any entry has been modified.. */
  135.     if ((guiBuffer == NULL) || (g_phb_cntx.refresh_list == MMI_PHB_ENTRY_REFRESH))
  136.     {
  137.         g_phb_cntx.highlight_entry = 0;
  138.         memset(g_phb_qsearch_input, 0, ENCODING_LENGTH);
  139.         // memset(g_phb_qsearch,1,MAX_PB_ENTRIES);  /*All records are in the subset at the beginning*/
  140.         memset(g_phb_qsearch_bitmask, 0xff, (MAX_PB_ENTRIES + 7) / 8);
  141.         entryCount = PhoneBookEntryCount;
  142.         guiBuffer = NULL;
  143.         g_phb_cntx.refresh_list = MMI_PHB_ENTRY_QSEARCH;    /* '2' is used only for this screen. */
  144.     }
  145.     else
  146.     {
  147.         entryCount = (U16) mmi_phb_quick_search_find_entry(g_phb_qsearch_input);
  148.     }
  149. #ifdef __MMI_UI_HINTS_IN_MENUITEM__
  150.     set_force_icon_on_highlight_only_in_menuitem();
  151. #endif 
  152.     ShowCategory200Screen(
  153.         STR_SCR_PBOOK_VIEW_CAPTION,
  154.         IMG_SCR_PBOOK_CAPTION,
  155.         STR_GLOBAL_OPTIONS,
  156.         IMG_GLOBAL_OPTIONS,
  157.         STR_GLOBAL_BACK,
  158.         IMG_GLOBAL_BACK,
  159.         entryCount,
  160.         mmi_phb_quick_search_list_get_item,
  161.         mmi_phb_quick_search_list_get_hint,
  162.         g_phb_cntx.highlight_entry,
  163.         IMG_ID_PHB_QUICK_SEARCH_FIND,
  164.         (U8*) g_phb_qsearch_input,
  165.         MMI_PHB_QUICK_SEARCH_INPUT_LENGTH,
  166.         guiBuffer);
  167.     SetCategory200RightSoftkeyFunction(GoBackHistory, KEY_EVENT_UP);
  168. #if defined(__MMI_MULTITAP_FOR_STAR_AND_POUND__)
  169.     SetCategory200LeftSoftkeyFunction(mmi_phb_entry_quick_search_option, KEY_EVENT_UP);
  170.     SetLeftSoftkeyFunction(mmi_phb_entry_quick_search_option, KEY_EVENT_UP);
  171. #else /* defined(__MMI_MULTITAP_FOR_STAR_AND_POUND__) */ 
  172.     SetCategory200LeftSoftkeyFunction(mmi_phb_entry_op_option, KEY_EVENT_UP);
  173.     SetLeftSoftkeyFunction(mmi_phb_entry_op_option, KEY_EVENT_UP);
  174. #endif /* defined(__MMI_MULTITAP_FOR_STAR_AND_POUND__) */ 
  175.     if (gInsertSimAppFlag != 1 && entryCount > 0
  176. #ifdef __FLIGHT_MODE_SUPPORT__
  177.         && mmi_bootup_get_active_flight_mode() != 1
  178. #endif 
  179.         )
  180.     {
  181.         SetKeyHandler(mmi_phb_list_pre_choose_number, KEY_SEND, KEY_EVENT_UP);
  182.     }
  183.     //MTK Elvis 20040517--it is incorrect to regist RSK here
  184.     //SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);
  185.     /* Make cache according to the current input method, after input method initialized in ShowCategoryScreen. */
  186.     if (guiBuffer == NULL)
  187.     {
  188.         g_phb_qsearch_is_cache = 0;
  189.         mmi_phb_quick_search_make_cache();
  190.     }
  191. }
  192. /*****************************************************************************
  193.  * FUNCTION
  194.  *  mmi_phb_exit_quick_search_list
  195.  * DESCRIPTION
  196.  *  
  197.  * PARAMETERS
  198.  *  void
  199.  * RETURNS
  200.  *  void
  201.  *****************************************************************************/
  202. void mmi_phb_exit_quick_search_list(void)
  203. {
  204. #if defined(__MMI_PHB_RSK_QUICK_SEARCH__)
  205.     /*----------------------------------------------------------------*/
  206.     /* Local Variables                                                */
  207.     /*----------------------------------------------------------------*/
  208.     /*----------------------------------------------------------------*/
  209.     /* Code Body                                                      */
  210.     /*----------------------------------------------------------------*/
  211.     if (g_idle_context.ToNameScrFromIdleApp)
  212.     {
  213.         g_phb_cntx.start_scr_id = SCR_ID_PHB_QUICK_SEARCH_LIST;
  214.     }
  215.     g_phb_cntx.end_scr_id = SCR_ID_PHB_QUICK_SEARCH_LIST;
  216.     g_idle_context.ToNameScrFromIdleApp = 0;
  217.     g_idle_context.RskPressedFromIdleApp = 0;
  218.     StopTimer(KEYPAD_LOCK_TIMER);
  219. #if defined(__MMI_VRSD_DIAL__)
  220.     StopTimer(VRSD_DIAL_PLAYBACK_TIMER);
  221. #endif 
  222. #endif /* defined(__MMI_PHB_RSK_QUICK_SEARCH__) */ 
  223. #if defined(__MMI_INTELLIGENT_CALL_ALERT__)
  224.     StopTimer(PHB_LIST_SPEAK_NAME_TIMER);
  225.     if (g_phb_is_speaking_name)
  226.     {
  227.         mdi_audio_stop_string();
  228.     }
  229. #endif /* defined(__MMI_INTELLIGENT_CALL_ALERT__) */ 
  230. }
  231. /*****************************************************************************
  232.  * FUNCTION
  233.  *  mmi_phb_quick_search_list_get_item
  234.  * DESCRIPTION
  235.  *  
  236.  * PARAMETERS
  237.  *  item_index          [IN]        
  238.  *  str_buff            [IN]        
  239.  *  img_buff_p          [?]         
  240.  *  str_img_mask        [IN]        
  241.  * RETURNS
  242.  *  
  243.  *****************************************************************************/
  244. pBOOL mmi_phb_quick_search_list_get_item(S32 item_index, UI_string_type str_buff, PU8 *img_buff_p, U8 str_img_mask)
  245. {
  246.     /*----------------------------------------------------------------*/
  247.     /* Local Variables                                                */
  248.     /*----------------------------------------------------------------*/
  249.     U16 i, count, store_index;
  250.     /*----------------------------------------------------------------*/
  251.     /* Code Body                                                      */
  252.     /*----------------------------------------------------------------*/
  253.     count = 0;
  254.     for (i = 0; i < PhoneBookEntryCount; i++)
  255.     {
  256.         /* if(g_phb_qsearch[i] == 1) */
  257.         if (g_phb_qsearch_bitmask[i >> BYTE_SIZE_SHIFT_ARITHMETIC] & (1 << (i % BYTE_SIZE)))
  258.         {
  259.             if (count == item_index)
  260.             {
  261.                 break;
  262.             }
  263.             count++;
  264.         }
  265.     }
  266.     store_index = g_phb_name_index[i];
  267.     if (pfnUnicodeStrlen((S8*) PhoneBook[store_index].alpha_id.name))
  268.     {
  269.         pfnUnicodeStrcpy((S8*) str_buff, (S8*) PhoneBook[store_index].alpha_id.name);
  270.     }
  271.     else
  272.     {
  273.         mmi_phb_convert_get_ucs2_number((S8*) str_buff, store_index);
  274.     }
  275.     if (store_index >= MAX_PB_PHONE_ENTRIES)    /* In SIM */
  276.     {
  277.         *img_buff_p = get_image(IMG_STORAGE_SIM);
  278.     }
  279.     else
  280.     {
  281.         *img_buff_p = get_image(IMG_STORAGE_HANDSET);
  282.     }
  283.     return TRUE;
  284. }
  285. /*****************************************************************************
  286.  * FUNCTION
  287.  *  mmi_phb_quick_search_list_get_hint
  288.  * DESCRIPTION
  289.  *  
  290.  * PARAMETERS
  291.  *  item_index      [IN]        
  292.  *  hint_array      [?]         
  293.  * RETURNS
  294.  *  
  295.  *****************************************************************************/
  296. S32 mmi_phb_quick_search_list_get_hint(S32 item_index, UI_string_type *hint_array)
  297. {
  298.     /*----------------------------------------------------------------*/
  299.     /* Local Variables                                                */
  300.     /*----------------------------------------------------------------*/
  301.     U16 i, count, store_index;
  302.     S8 temp_number[(MAX_PB_NUMBER_LENGTH + 1 + 1) * ENCODING_LENGTH];
  303.     /*----------------------------------------------------------------*/
  304.     /* Code Body                                                      */
  305.     /*----------------------------------------------------------------*/
  306.     count = 0;
  307.     for (i = 0; i < PhoneBookEntryCount; i++)
  308.     {
  309.         /* if(g_phb_qsearch[i] == 1) */
  310.         if (g_phb_qsearch_bitmask[i >> BYTE_SIZE_SHIFT_ARITHMETIC] & (1 << (i % BYTE_SIZE)))
  311.         {
  312.             if (count == item_index)
  313.             {
  314.                 break;
  315.             }
  316.             count++;
  317.         }
  318.     }
  319.     store_index = g_phb_name_index[i];
  320.     mmi_phb_convert_get_ucs2_number((S8*) temp_number, store_index);
  321.     if (pfnUnicodeStrlen((S8*) PhoneBook[store_index].alpha_id.name) && pfnUnicodeStrlen((S8*) temp_number))
  322.     {
  323.         pfnUnicodeStrcpy((S8*) hint_array[0], (S8*) temp_number);
  324.     }
  325.     else
  326.     {
  327.         return 0;
  328.     }
  329.     return 1;   /* One hint data only, can be more hints. */
  330. }
  331. /*****************************************************************************
  332.  * FUNCTION
  333.  *  mmi_phb_quick_search_change_input_mode
  334.  * DESCRIPTION
  335.  *  
  336.  * PARAMETERS
  337.  *  void
  338.  * RETURNS
  339.  *  void
  340.  *****************************************************************************/
  341. void mmi_phb_quick_search_change_input_mode(void)
  342. {
  343.     /*----------------------------------------------------------------*/
  344.     /* Local Variables                                                */
  345.     /*----------------------------------------------------------------*/
  346.     /*----------------------------------------------------------------*/
  347.     /* Code Body                                                      */
  348.     /*----------------------------------------------------------------*/
  349.     // memset(g_phb_qsearch,1,MAX_PB_ENTRIES);  /*All records are in the subset at the beginning*/
  350.     memset(g_phb_qsearch_bitmask, 0xff, (MAX_PB_ENTRIES + 7) / 8);
  351.     g_phb_qsearch_is_cache = 0;
  352.     /*
  353.      * Make cache according to the current input method.
  354.      * Start a timer to avoid convert cache each time when user change input method quickly.
  355.      */
  356.     StopTimer(PHB_QUICK_SEARCH_TIMER);
  357.     StartTimer(PHB_QUICK_SEARCH_TIMER, 500, mmi_phb_quick_search_make_cache);
  358. }
  359. #if defined(__MMI_MULTITAP_FOR_STAR_AND_POUND__)
  360. extern void EntryQuickSearchInputMethodScreen(void);
  361. /*****************************************************************************
  362.  * FUNCTION
  363.  *  mmi_phb_quick_search_go_back_editor
  364.  * DESCRIPTION
  365.  *  Go back screen after change input method.
  366.  * PARAMETERS
  367.  *  void
  368.  * RETURNS
  369.  *  void
  370.  *****************************************************************************/
  371. void mmi_phb_quick_search_go_back_editor(void)
  372. {
  373.     /*----------------------------------------------------------------*/
  374.     /* Local Variables                                                */
  375.     /*----------------------------------------------------------------*/
  376.     /*----------------------------------------------------------------*/
  377.     /* Code Body                                                      */
  378.     /*----------------------------------------------------------------*/
  379.     GoBackToHistory(SCR_ID_PHB_QUICK_SEARCH_LIST);
  380. }
  381. /*****************************************************************************
  382.  * FUNCTION
  383.  *  mmi_phb_highlight_quick_search_input_method
  384.  * DESCRIPTION
  385.  *  Highlight function to enter change input method
  386.  * PARAMETERS
  387.  *  void
  388.  * RETURNS
  389.  *  void
  390.  *****************************************************************************/
  391. void mmi_phb_highlight_quick_search_input_method(void)
  392. {
  393.     /*----------------------------------------------------------------*/
  394.     /* Local Variables                                                */
  395.     /*----------------------------------------------------------------*/
  396.     /*----------------------------------------------------------------*/
  397.     /* Code Body                                                      */
  398.     /*----------------------------------------------------------------*/
  399.     SetLeftSoftkeyFunction(EntryQuickSearchInputMethodScreen, KEY_EVENT_UP);
  400.     SetKeyHandler(EntryQuickSearchInputMethodScreen, KEY_RIGHT_ARROW, KEY_EVENT_DOWN);
  401.     RegisterInputMethodScreenCloseFunction(mmi_phb_quick_search_go_back_editor);
  402. }
  403. /*****************************************************************************
  404.  * FUNCTION
  405.  *  mmi_phb_highlight_quick_search_op_option
  406.  * DESCRIPTION
  407.  *  Highlight function to enter entry option.
  408.  * PARAMETERS
  409.  *  void
  410.  * RETURNS
  411.  *  void
  412.  *****************************************************************************/
  413. void mmi_phb_highlight_quick_search_op_option(void)
  414. {
  415.     /*----------------------------------------------------------------*/
  416.     /* Local Variables                                                */
  417.     /*----------------------------------------------------------------*/
  418.     /*----------------------------------------------------------------*/
  419.     /* Code Body                                                      */
  420.     /*----------------------------------------------------------------*/
  421.     SetLeftSoftkeyFunction(mmi_phb_entry_op_option, KEY_EVENT_UP);
  422.     SetKeyHandler(mmi_phb_entry_op_option, KEY_RIGHT_ARROW, KEY_EVENT_DOWN);
  423. }
  424. /*****************************************************************************
  425.  * FUNCTION
  426.  *  mmi_phb_entry_quick_search_option
  427.  * DESCRIPTION
  428.  *  Entry function of phonebook quick search option.
  429.  * PARAMETERS
  430.  *  void
  431.  * RETURNS
  432.  *  void
  433.  *****************************************************************************/
  434. void mmi_phb_entry_quick_search_option(void)
  435. {
  436.     /*----------------------------------------------------------------*/
  437.     /* Local Variables                                                */
  438.     /*----------------------------------------------------------------*/
  439.     U8 *guiBuffer;
  440.     U16 nStrItemList[10];   /* Need Expand when has more options. */
  441.     U16 nNumofItem;
  442.     /*----------------------------------------------------------------*/
  443.     /* Code Body                                                      */
  444.     /*----------------------------------------------------------------*/
  445.     EntryNewScreen(
  446.         SCR_ID_PHB_QUICK_SEARCH_OPTION,
  447.         mmi_phb_exit_quick_search_option,
  448.         mmi_phb_entry_quick_search_option,
  449.         NULL);
  450.     guiBuffer = GetCurrGuiBuffer(SCR_ID_PHB_QUICK_SEARCH_OPTION);
  451.     nNumofItem = GetNumOfChild(MENU_ID_PHB_QUICK_SEARCH_OPTION);
  452.     GetSequenceStringIds(MENU_ID_PHB_QUICK_SEARCH_OPTION, nStrItemList);
  453.     SetParentHandler(MENU_ID_PHB_QUICK_SEARCH_OPTION);
  454.     RegisterHighlightHandler(ExecuteCurrHiliteHandler);
  455.     ShowCategory15Screen(
  456.         STR_GLOBAL_OPTIONS,
  457.         IMG_SCR_PBOOK_CAPTION,
  458.         STR_GLOBAL_OK,
  459.         IMG_GLOBAL_OK,
  460.         STR_GLOBAL_BACK,
  461.         IMG_GLOBAL_BACK,
  462.         nNumofItem,
  463.         nStrItemList,
  464.         (U16*) gIndexIconsImageList,
  465.         LIST_MENU,
  466.         0,
  467.         guiBuffer);
  468.     SetRightSoftkeyFunction(GoBackHistory, KEY_EVENT_UP);
  469.     SetKeyHandler(GoBackHistory, KEY_LEFT_ARROW, KEY_EVENT_DOWN);
  470. }
  471. /*****************************************************************************
  472.  * FUNCTION
  473.  *  mmi_phb_exit_quick_search_option
  474.  * DESCRIPTION
  475.  *  Exit function of phonebook quick search option
  476.  * PARAMETERS
  477.  *  void
  478.  * RETURNS
  479.  *  void
  480.  *****************************************************************************/
  481. void mmi_phb_exit_quick_search_option(void)
  482. {
  483.     /*----------------------------------------------------------------*/
  484.     /* Local Variables                                                */
  485.     /*----------------------------------------------------------------*/
  486.     /*----------------------------------------------------------------*/
  487.     /* Code Body                                                      */
  488.     /*----------------------------------------------------------------*/
  489.     g_phb_cntx.end_scr_id = SCR_ID_PHB_QUICK_SEARCH_OPTION;
  490. }
  491. #endif /* defined(__MMI_MULTITAP_FOR_STAR_AND_POUND__) */ 
  492. #endif /* defined(__MMI_PHB_QUICK_SEARCH__) */
  493. #define MMI_PHB_UTIL_SEARCH
  494. /*---------------------------------------------------- General Compare String Functions -------------------------------------------------*/
  495. /*****************************************************************************
  496.  * FUNCTION
  497.  *  mmi_phb_compare_chars
  498.  * PARAMETERS
  499.  *  char1       [IN]        
  500.  *  char2       [IN]        
  501.  * RETURNS
  502.  *  
  503.  *****************************************************************************/
  504. S32 mmi_phb_compare_chars(U16 char1, U16 char2)
  505. {
  506.     /*----------------------------------------------------------------*/
  507.     /* Local Variables                                                */
  508.     /*----------------------------------------------------------------*/
  509.     /*----------------------------------------------------------------*/
  510.     /* Code Body                                                      */
  511.     /*----------------------------------------------------------------*/
  512.     /* try UCS2 matching */
  513.     if (char1 == char2)
  514.     {
  515.         return 0;
  516.     }
  517.     /* if not, try ASCII case-insensitive matching */
  518.     else if ((char1 < 0x007E) && (char2 < 0x007E))
  519.     {
  520.         if ((char1 <= 0x007b) && (char1 >= 0x0061))
  521.         {
  522.             char1 -= 0x20;
  523.         }
  524.         if ((char2 <= 0x007b) && (char2 >= 0x0061))
  525.         {
  526.             char2 -= 0x20;
  527.         }
  528.         return char1 - char2;
  529.     }
  530.     /* no match */
  531.     return char1 - char2;
  532. }
  533. /*****************************************************************************
  534.  * FUNCTION
  535.  *  mmi_phb_compare_ucs2_strings
  536.  * PARAMETERS
  537.  *  string1         [?]     
  538.  *  string2         [?]     
  539.  *  same_count      [?]     
  540.  *  distance        [?]     
  541.  * RETURNS
  542.  *  void
  543.  *****************************************************************************/
  544. void mmi_phb_compare_ucs2_strings(S8 *string1, S8 *string2, U8 *same_count, S32 *distance)
  545. {
  546.     /*----------------------------------------------------------------*/
  547.     /* Local Variables                                                */
  548.     /*----------------------------------------------------------------*/
  549.     U8 len1, len2;
  550.     U8 max_len, min_len;
  551.     U8 i;
  552.     U16 code1, code2;
  553.     /*----------------------------------------------------------------*/
  554.     /* Code Body                                                      */
  555.     /*----------------------------------------------------------------*/
  556.     *same_count = 0;
  557.     *distance = 0;
  558.     len1 = (U8) pfnUnicodeStrlen(string1);
  559.     len2 = (U8) pfnUnicodeStrlen(string2);
  560.     if (len1 > len2)
  561.     {
  562.         max_len = len1;
  563.         min_len = len2;
  564.     }
  565.     else
  566.     {
  567.         max_len = len2;
  568.         min_len = len1;
  569.     }
  570.     for (i = 0; i < max_len && i < MAX_PB_EMAIL_LENGTH; i++)    /* Use Max Phonebook Strlen as upper bound */
  571.         /* for (i = 0; i < max_len; i++) */
  572.     {
  573.         /* If all characters are identical from 0 to min_len. */
  574.         if (i >= min_len)
  575.         {
  576.             /* First is greater than second */
  577.             if (len1 > len2)
  578.             {
  579.                 *distance = (U16) string1[i * ENCODING_LENGTH];
  580.             }
  581.             /* First and second is congruence */
  582.             else if (len1 == len2)
  583.             {
  584.                 *distance = 0;
  585.             }
  586.             /* len1 < len2: First is less than second */
  587.             else
  588.             {
  589.                 *distance = -(U16) string2[i * ENCODING_LENGTH];
  590.             }
  591.             //if (min_len == 0)
  592.             //     *distance = - *distance;
  593.             break;
  594.         }
  595.         /* First, compare from 0 to min_len */
  596.         else
  597.         {
  598.             memcpy(&code1, (string1 + i * ENCODING_LENGTH), 2);
  599.             memcpy(&code2, (string2 + i * ENCODING_LENGTH), 2);
  600.             if ((*distance = mmi_phb_compare_chars(code1, code2)) == 0)
  601.             {
  602.                 *same_count = *same_count + 1;
  603.             }
  604.             /* First and second is not equal, return distance */
  605.             else
  606.             {
  607.                 break;
  608.             }
  609.         }
  610.     }
  611. }
  612. /*****************************************************************************
  613.  * FUNCTION
  614.  *  mmi_phb_compare_ascii_strings
  615.  * PARAMETERS
  616.  *  string1         [?]     > string2 ; <0 if sting1 < string2
  617.  *  string2         [?]     
  618.  *  same_count      [?]     
  619.  *  distance        [?]     
  620.  *****************************************************************************/
  621. void mmi_phb_compare_ascii_strings(S8 *string1, S8 *string2, U16 *same_count, S32 *distance)
  622. {
  623.     /*----------------------------------------------------------------*/
  624.     /* Local Variables                                                */
  625.     /*----------------------------------------------------------------*/
  626.     U16 len1, len2;
  627.     U16 max_len, min_len;
  628.     U16 i;
  629.     U16 code1, code2;
  630.     /*----------------------------------------------------------------*/
  631.     /* Code Body                                                      */
  632.     /*----------------------------------------------------------------*/
  633.     *same_count = 0;
  634.     *distance = 0;
  635.     len1 = strlen(string1);
  636.     len2 = strlen(string2);
  637.     if (len1 > len2)
  638.     {
  639.         max_len = len1;
  640.         min_len = len2;
  641.     }
  642.     else
  643.     {
  644.         max_len = len2;
  645.         min_len = len1;
  646.     }
  647.     for (i = 0; i < max_len; i++)
  648.     {
  649.         if (i >= min_len)   /* If all characters are identical from 0 to min_len. */
  650.         {
  651.             if (len1 > len2)    /* First is greater than second */
  652.             {
  653.                 *distance = (U16) string1[i];
  654.             }
  655.             else if (len1 == len2)  /* First and second is congruence */
  656.             {
  657.                 *distance = 0;
  658.             }
  659.             else    /* len1 < len2: First is less than second */
  660.             {
  661.                 *distance = -(U16) string2[i];
  662.             }
  663.             if (min_len == 0)
  664.             {
  665.                 *distance = -*distance;
  666.             }
  667.             break;
  668.         }
  669.         else    /* First, compare from 0 to min_len */
  670.         {
  671.             code1 = (U16) string1[i];
  672.             code2 = (U16) string2[i];
  673.             if ((*distance = mmi_phb_compare_chars(code1, code2)) == 0)
  674.             {
  675.                 *same_count = *same_count + 1;
  676.             }
  677.             else    /* First and second is not equal, return distance */
  678.             {
  679.                 break;
  680.             }
  681.         }
  682.     }
  683. }
  684. #if defined(__MMI_PHB_PINYIN_SORT__)
  685. /*****************************************************************************
  686.  * FUNCTION
  687.  *  mmi_phb_util_make_pinyin_cache
  688.  * DESCRIPTION
  689.  *  
  690.  * PARAMETERS
  691.  *  store_index     [IN]        
  692.  * RETURNS
  693.  *  void
  694.  *****************************************************************************/
  695. void mmi_phb_util_make_pinyin_cache(U16 store_index)
  696. {
  697.     /*----------------------------------------------------------------*/
  698.     /* Local Variables                                                */
  699.     /*----------------------------------------------------------------*/
  700.     U16 count;
  701.     /*----------------------------------------------------------------*/
  702.     /* Code Body                                                      */
  703.     /*----------------------------------------------------------------*/
  704.     if ((PhoneBook[store_index].alpha_id.name_length != 0) &&
  705.         (PhoneBook[store_index].alpha_id.name_dcs != MMI_PHB_ASCII))
  706.     {
  707.         count = mmi_phb_util_convert_to_pinyin(
  708.                     PhoneBook[store_index].alpha_id.name,
  709.                     &g_phb_name_pinyin_index[store_index][0],
  710.                     MMI_PHB_SORT_LENGTH * ENCODING_LENGTH);
  711.         g_phb_name_pinyin_index[store_index][count++] = 0x00;
  712.         g_phb_name_pinyin_index[store_index][count++] = 0x00;
  713.     }
  714.     else
  715.     {
  716.         memset(&g_phb_name_pinyin_index[store_index][0], 0, 2);
  717.     }
  718. }
  719. /*****************************************************************************
  720.  * FUNCTION
  721.  *  mmi_phb_util_get_pinyin_cache
  722.  * DESCRIPTION
  723.  *  
  724.  * PARAMETERS
  725.  *  store_index     [IN]        
  726.  *  pinyin_ptr      [IN]        
  727.  * RETURNS
  728.  *  void
  729.  *****************************************************************************/
  730. void mmi_phb_util_get_pinyin_cache(U16 store_index, U8 **pinyin_ptr)
  731. {
  732.     /*----------------------------------------------------------------*/
  733.     /* Local Variables                                                */
  734.     /*----------------------------------------------------------------*/
  735.     /*----------------------------------------------------------------*/
  736.     /* Code Body                                                      */
  737.     /*----------------------------------------------------------------*/
  738.     *pinyin_ptr = &g_phb_name_pinyin_index[store_index][0];
  739. }
  740. /*****************************************************************************
  741.  * FUNCTION
  742.  *  mmi_phb_util_convert_to_pinyin
  743.  * DESCRIPTION
  744.  *  This function convert the input string into Chinese Pinyin string according to the library
  745.  *  Between each pinyin string result, it will append the original encoding to seperate two
  746.  *  Chinese pinyin result.
  747.  * PARAMETERS
  748.  *  inputString         [?]         The input string buffer in ucs2 format.
  749.  *  outputString        [?]         The output string buffer, it will be ucs2 format
  750.  *  out_length          [IN]        The output string buffer size, in bytes.
  751.  * RETURNS
  752.  *  void
  753.  *****************************************************************************/
  754. #if defined(__MMI_T9__)
  755. #if defined(__MMI_T9_V7__)
  756. U16 mmi_phb_util_convert_to_pinyin(U8 *inputString, U8 *outputString, U16 out_length)
  757. {
  758.     /*----------------------------------------------------------------*/
  759.     /* Local Variables                                                */
  760.     /*----------------------------------------------------------------*/
  761.     T9STATUS t9ReturnCodes;
  762.     U8 i, out = 0;
  763.     /*----------------------------------------------------------------*/
  764.     /* Code Body                                                      */
  765.     /*----------------------------------------------------------------*/
  766.     T9ChangeLanguageToSMChinesePinYin();
  767.     while (!((*inputString == 0) && (*(inputString + 1) == 0)) && ((out + 1) < out_length))
  768.     {
  769.         t9ReturnCodes = T9CCGetCharSpell(&FieldInfo.CCFieldInfo, (U16*) inputString, 0);
  770.         if (t9ReturnCodes == 0) /* (code >= 0x4e00) && (code <= 0x9fa5) */
  771.         {
  772.             i = 0;
  773.             while ((FieldInfo.CCFieldInfo.pbSpellBuf[i] != 0x00) && ((out + 1) < out_length))
  774.             {
  775.                 outputString[out++] = FieldInfo.CCFieldInfo.pbSpellBuf[i++];
  776.                 outputString[out++] = 0x00;
  777.             }
  778.         }
  779.         /* Add character encoding beetween pinyin strings */
  780.         if ((out + 1) < out_length)
  781.         {
  782.             outputString[out++] = inputString[0];
  783.             outputString[out++] = inputString[1];
  784.         }
  785.         inputString += 2;
  786.     }
  787.     return out;
  788. }
  789. #else /* defined(__MMI_T9_V7__) */ 
  790. /*****************************************************************************
  791.  * FUNCTION
  792.  *  mmi_phb_util_convert_to_pinyin
  793.  * DESCRIPTION
  794.  *  
  795.  * PARAMETERS
  796.  *  inputString         [?]         
  797.  *  outputString        [?]         
  798.  *  out_length          [IN]        
  799.  * RETURNS
  800.  *  
  801.  *****************************************************************************/
  802. U16 mmi_phb_util_convert_to_pinyin(U8 *inputString, U8 *outputString, U16 out_length)
  803. {
  804.     /*----------------------------------------------------------------*/
  805.     /* Local Variables                                                */
  806.     /*----------------------------------------------------------------*/
  807.     T9Event t9EventInput;
  808.     T9STATUS t9ReturnCodes;
  809.     U8 i, out = 0;
  810.     /*----------------------------------------------------------------*/
  811.     /* Code Body                                                      */
  812.     /*----------------------------------------------------------------*/
  813.     T9ChangeLanguageToSMChinesePinYin();
  814.     while (!((*inputString == 0) && (*(inputString + 1) == 0)) && ((out + 1) < out_length))
  815.     {
  816.         t9EventInput.mType = T9EVTSPELLING;
  817.         t9EventInput.data.sLDBData.psBuf = (U16*) inputString;
  818.         t9EventInput.data.sLDBData.mCtrlID = 0;
  819.         t9ReturnCodes = T9HandleEvent(&FieldInfo, &t9EventInput);
  820.         if (t9ReturnCodes == 0) /* (code >= 0x4e00) && (code <= 0x9fa5) */
  821.         {
  822.             i = 0;
  823.             while ((FieldInfo.uLangData.pAuxChinese->pbSpellBuf[i] != 0x00) && ((out + 1) < out_length))
  824.             {
  825.                 outputString[out++] = FieldInfo.uLangData.pAuxChinese->pbSpellBuf[i++];
  826.                 outputString[out++] = 0x00;
  827.             }
  828.         }
  829.         /* Add character encoding beetween pinyin strings */
  830.         if ((out + 1) < out_length)
  831.         {
  832.             outputString[out++] = inputString[0];
  833.             outputString[out++] = inputString[1];
  834.         }
  835.         inputString += 2;
  836.     }
  837.     return out;
  838. }
  839. #endif /* defined(__MMI_T9_V7__) */ 
  840. #elif defined(__MMI_ZI__)
  841. /*****************************************************************************
  842.  * FUNCTION
  843.  *  mmi_phb_util_convert_to_pinyin
  844.  * DESCRIPTION
  845.  *  
  846.  * PARAMETERS
  847.  *  inputString         [?]         
  848.  *  outputString        [?]         
  849.  *  out_length          [IN]        
  850.  * RETURNS
  851.  *  
  852.  *****************************************************************************/
  853. U16 mmi_phb_util_convert_to_pinyin(U8 *inputString, U8 *outputString, U16 out_length)
  854. {
  855.     /*----------------------------------------------------------------*/
  856.     /* Local Variables                                                */
  857.     /*----------------------------------------------------------------*/
  858.     U8 i, out = 0;
  859.     U16 code;
  860.     U16 pCharInfoBuffer[MMI_PHB_CONVERT_BUFF_ZI];
  861.     U16 PinYin_Base = ZI8_BASE_PINYIN - 0x0061;
  862.     /*----------------------------------------------------------------*/
  863.     /* Code Body                                                      */
  864.     /*----------------------------------------------------------------*/
  865.     while (!((*inputString == 0) && (*(inputString + 1) == 0)) && ((out + 1) < out_length))
  866.     {
  867.         memcpy(&code, inputString, 2);
  868.         if ((code >= 0x4e00) && (code <= 0x9fa5) &&
  869.             Zi8GetCharInfo(code, (U16*) pCharInfoBuffer, MMI_PHB_CONVERT_BUFF_ZI, ZI8_GETMODE_PINYIN))
  870.         {
  871.             i = 0;
  872.             while ((pCharInfoBuffer[i] != 0x0000) && (out < out_length) && ((pCharInfoBuffer[i] < 0xf431) || (pCharInfoBuffer[i] > 0xf435)))    /* No tone needed */
  873.             {
  874.                 outputString[out++] = (U8) (pCharInfoBuffer[i++] - PinYin_Base);
  875.                 outputString[out++] = 0x00;
  876.             }
  877.         }
  878.         /* Add character encoding beetween pinyin strings */
  879.         if ((out + 1) < out_length)
  880.         {
  881.             outputString[out++] = inputString[0];
  882.             outputString[out++] = inputString[1];
  883.         }
  884.         inputString += 2;
  885.     }
  886.     return out;
  887. }
  888. //KP Jerry add on 2007-3-8 start
  889. #elif defined(__MMI_CSTAR__)
  890. U16 mmi_phb_util_convert_to_pinyin(U8* inputString, U8* outputString, U16 out_length)
  891. {
  892.     U16 out;
  893.     int i;
  894.     U16 code;
  895.     U16 buf[16];
  896.     out = 0;
  897.     while ( !((inputString[0] == 0) && (inputString[1] == 0)) && (out + 1 < out_length) )
  898.     {
  899.         memcpy(&code, inputString, 2);
  900.         if (CstarQueryCharInfo(code, buf, 16, INPUT_MODE_MMI_MULTITAP_PINYIN) > 0)
  901.         {
  902.             i = 0;
  903.             while ( (buf[i] != 0) && (out < out_length) )
  904.             {
  905.                 outputString[out++] = (U8)(buf[i++]);
  906.                 outputString[out++] = 0x00; 
  907.             }
  908.         }
  909.         if (out + 1 < out_length)
  910.         {
  911.             outputString[out++] = inputString[0];
  912.             outputString[out++] = inputString[1];
  913.         }
  914.             
  915.         inputString += 2;
  916.     }
  917.     return out;
  918. }
  919. //KP Jerry add on 2007-3-8 end
  920. #elif defined(__MMI_ITAP__)
  921. /* under construction !*/
  922. /* under construction !*/
  923. /* under construction !*/
  924. /* under construction !*/
  925. /* under construction !*/
  926. /* under construction !*/
  927. /* under construction !*/
  928. /* under construction !*/
  929. /* under construction !*/
  930. /* under construction !*/
  931. /* under construction !*/
  932. /* under construction !*/
  933. /* under construction !*/
  934. /* under construction !*/
  935. /* under construction !*/
  936. /* under construction !*/
  937. /* under construction !*/
  938. /* under construction !*/
  939. /* under construction !*/
  940. /* under construction !*/
  941. /* under construction !*/
  942. /* under construction !*/
  943. /* under construction !*/
  944. /* under construction !*/
  945. /* under construction !*/
  946. /* under construction !*/
  947. /* under construction !*/
  948. /* under construction !*/
  949. /* under construction !*/
  950. /* under construction !*/
  951. /* under construction !*/
  952. /* under construction !*/
  953. /* under construction !*/
  954. /* under construction !*/
  955. /* under construction !*/
  956. /* under construction !*/
  957. /* under construction !*/
  958. /* under construction !*/
  959. /* under construction !*/
  960. /* under construction !*/
  961. /* under construction !*/
  962. /* under construction !*/
  963. /* under construction !*/
  964. /* under construction !*/
  965. /* under construction !*/
  966. /* under construction !*/
  967. /* under construction !*/
  968. /* under construction !*/
  969. /* under construction !*/
  970. /* under construction !*/
  971. /* under construction !*/
  972. /* under construction !*/
  973. /* under construction !*/
  974. /* under construction !*/
  975. /* under construction !*/
  976. /* under construction !*/
  977. /* under construction !*/
  978. /* under construction !*/
  979. /* under construction !*/
  980. /* under construction !*/
  981. /* under construction !*/
  982. /* under construction !*/
  983. /* under construction !*/
  984. /* under construction !*/
  985. /* under construction !*/
  986. /* under construction !*/
  987. /* under construction !*/
  988. #else 
  989. /*****************************************************************************
  990.  * FUNCTION
  991.  *  mmi_phb_util_convert_to_pinyin
  992.  * DESCRIPTION
  993.  *  
  994.  * PARAMETERS
  995.  *  inputString         [?]         
  996.  *  outputString        [?]         
  997.  *  out_length          [IN]        
  998.  * RETURNS
  999.  *  
  1000.  *****************************************************************************/
  1001. U16 mmi_phb_util_convert_to_pinyin(U8 *inputString, U8 *outputString, U16 out_length)
  1002. {
  1003.     /*----------------------------------------------------------------*/
  1004.     /* Local Variables                                                */
  1005.     /*----------------------------------------------------------------*/
  1006.     /*----------------------------------------------------------------*/
  1007.     /* Code Body                                                      */
  1008.     /*----------------------------------------------------------------*/
  1009.     pfnUnicodeStrncpy((S8*) outputString, (S8*) inputString, out_length);
  1010.     return out_length;
  1011. }
  1012. #endif 
  1013. #endif /* defined(__MMI_PHB_PINYIN_SORT__) */ 
  1014. #define MMI_PHB_LOOKUP_TABLE
  1015. /*****************************************************************************
  1016.  * FUNCTION
  1017.  *  mmi_phb_lookup_table_sort
  1018.  * DESCRIPTION
  1019.  *  Sorts the look-up table
  1020.  *  
  1021.  *  This is a fast Quick-Sort as suggested by
  1022.  *  Pluto. It will perform insertion sort for
  1023.  *  array chunks of size less than 4 and quick
  1024.  *  sort for size greater than 4.
  1025.  * PARAMETERS
  1026.  *  void
  1027.  * RETURNS
  1028.  *  void
  1029.  *****************************************************************************/
  1030. void mmi_phb_lookup_table_sort(void)
  1031. {
  1032.     /*----------------------------------------------------------------*/
  1033.     /* Local Variables                                                */
  1034.     /*----------------------------------------------------------------*/
  1035.     /*----------------------------------------------------------------*/
  1036.     /* Code Body                                                      */
  1037.     /*----------------------------------------------------------------*/
  1038.     if (g_phb_cntx.lookup_table_count)
  1039.     {
  1040.         /* Set to zero beore sorting, check if this flag larger than phonebook entries to see if finish sorting. */
  1041.         g_phb_cntx.populate_count = 0;
  1042.         /* Begin to sort. */
  1043.         mmi_phb_lookup_table_quicksort(0, (U16) (g_phb_cntx.lookup_table_count - 1));
  1044.         mmi_phb_lookup_table_insertionsort(0, (U16) (g_phb_cntx.lookup_table_count - 1));
  1045.         /* After sorting, set it to total phonebook entries. */
  1046.         g_phb_cntx.populate_count = 0xffff;
  1047.     }
  1048. }
  1049. /*****************************************************************************
  1050.  * FUNCTION
  1051.  *  mmi_phb_lookup_table_quicksort
  1052.  * DESCRIPTION
  1053.  *  Sorts the lookup table using quick sort algorithm
  1054.  * PARAMETERS
  1055.  *  l       [IN]        
  1056.  *  r       [IN]        
  1057.  * RETURNS
  1058.  *  void
  1059.  *****************************************************************************/
  1060. void mmi_phb_lookup_table_quicksort(U16 l, U16 r)
  1061. {
  1062.     /*----------------------------------------------------------------*/
  1063.     /* Local Variables                                                */
  1064.     /*----------------------------------------------------------------*/
  1065.     U16 i, j;
  1066.     U32 pivot;
  1067.     /*----------------------------------------------------------------*/
  1068.     /* Code Body                                                      */
  1069.     /*----------------------------------------------------------------*/
  1070.     if ((r - l) > 4)
  1071.     {
  1072.         i = (r + l) / 2;
  1073.         if (LookUpTable[l].number > LookUpTable[i].number)
  1074.         {
  1075.             mmi_phb_lookup_table_swap_node(l, i);
  1076.         }
  1077.         if (LookUpTable[l].number > LookUpTable[r].number)
  1078.         {
  1079.             mmi_phb_lookup_table_swap_node(l, r);
  1080.         }
  1081.         if (LookUpTable[i].number > LookUpTable[r].number)
  1082.         {
  1083.             mmi_phb_lookup_table_swap_node(i, r);
  1084.         }
  1085.         j = r - 1;
  1086.         mmi_phb_lookup_table_swap_node(i, j);
  1087.         i = l;
  1088.         pivot = LookUpTable[j].number;
  1089.         for (;;)
  1090.         {
  1091.             do
  1092.             {
  1093.             } while (LookUpTable[++i].number < pivot);
  1094.             do
  1095.             {
  1096.             } while (LookUpTable[--j].number > pivot);
  1097.             if (j < i)
  1098.             {
  1099.                 break;
  1100.             }
  1101.             mmi_phb_lookup_table_swap_node(i, j);
  1102.         }
  1103.         mmi_phb_lookup_table_swap_node(i, (U16) (r - 1));
  1104.         mmi_phb_lookup_table_quicksort(l, j);
  1105.         mmi_phb_lookup_table_quicksort((U16) (i + 1), r);
  1106.     }
  1107. }
  1108. /*****************************************************************************
  1109.  * FUNCTION
  1110.  *  mmi_phb_lookup_table_insertionsort
  1111.  * DESCRIPTION
  1112.  *  Sorts the lookup table using insertion sort algorithm
  1113.  * PARAMETERS
  1114.  *  lo      [IN]        
  1115.  *  hi      [IN]        
  1116.  * RETURNS
  1117.  *  void
  1118.  *****************************************************************************/
  1119. void mmi_phb_lookup_table_insertionsort(U16 lo, U16 hi)
  1120. {
  1121.     /*----------------------------------------------------------------*/
  1122.     /* Local Variables                                                */
  1123.     /*----------------------------------------------------------------*/
  1124.     U16 i, j;
  1125.     MMI_PHB_LOOKUP_NODE_STRUCT elem;
  1126.     /*----------------------------------------------------------------*/
  1127.     /* Code Body                                                      */
  1128.     /*----------------------------------------------------------------*/
  1129.     for (i = lo + 1; i <= hi; ++i)
  1130.     {
  1131.         memcpy(&elem, &LookUpTable[i], sizeof(MMI_PHB_LOOKUP_NODE_STRUCT));
  1132.         j = i;
  1133.         while (j > lo)
  1134.         {
  1135.             if (LookUpTable[j - 1].number <= elem.number)
  1136.             {
  1137.                 break;
  1138.             }
  1139.             memcpy(&LookUpTable[j], &LookUpTable[j - 1], sizeof(MMI_PHB_LOOKUP_NODE_STRUCT));
  1140.             j--;
  1141.         }
  1142.         memcpy(&LookUpTable[j], &elem, sizeof(MMI_PHB_LOOKUP_NODE_STRUCT));
  1143.     }
  1144. }
  1145. /*****************************************************************************
  1146.  * FUNCTION
  1147.  *  mmi_phb_lookup_table_swap_node
  1148.  * DESCRIPTION
  1149.  *  Swaps the look-up table nodes
  1150.  * PARAMETERS
  1151.  *  i       [IN]        
  1152.  *  j       [IN]        
  1153.  * RETURNS
  1154.  *  void
  1155.  *****************************************************************************/
  1156. void mmi_phb_lookup_table_swap_node(U16 i, U16 j)
  1157. {
  1158.     /*----------------------------------------------------------------*/
  1159.     /* Local Variables                                                */
  1160.     /*----------------------------------------------------------------*/
  1161.     MMI_PHB_LOOKUP_NODE_STRUCT temp;
  1162.     /*----------------------------------------------------------------*/
  1163.     /* Code Body                                                      */
  1164.     /*----------------------------------------------------------------*/
  1165.     memcpy(&temp, &LookUpTable[i], sizeof(MMI_PHB_LOOKUP_NODE_STRUCT));
  1166.     memcpy(&LookUpTable[i], &LookUpTable[j], sizeof(MMI_PHB_LOOKUP_NODE_STRUCT));
  1167.     memcpy(&LookUpTable[j], &temp, sizeof(MMI_PHB_LOOKUP_NODE_STRUCT));
  1168. }
  1169. /* Advance Search Phone Numbe. For Mobile Field Only!!! */
  1170. #if defined(__MMI_PHB_ADV_NUM_MATCH_MOBILE__)
  1171. /*****************************************************************************
  1172.  * FUNCTION
  1173.  *  mmi_phb_number_has_extension
  1174.  * DESCRIPTION
  1175.  *  Find out if a phone number has extension field.
  1176.  * PARAMETERS
  1177.  *  number      [?]     
  1178.  * RETURNS
  1179.  *  The position of the first extension character.
  1180.  *  Ex. *31#+81234567890p123 => 16
  1181.  *****************************************************************************/
  1182. U16 mmi_phb_number_has_extension(S8 *number)
  1183. {
  1184.     /*----------------------------------------------------------------*/
  1185.     /* Local Variables                                                */
  1186.     /*----------------------------------------------------------------*/
  1187.     U16 temp;
  1188.     U16 pos = 0;
  1189.     /*----------------------------------------------------------------*/
  1190.     /* Code Body                                                      */
  1191.     /*----------------------------------------------------------------*/
  1192.     /* Ignore *31# and #31# */
  1193.     while (((number[0] == '*') && (number[1] == '3') && (number[2] == '1') && (number[3] == '#')) ||
  1194.            ((number[0] == '#') && (number[1] == '3') && (number[2] == '1') && (number[3] == '#')))
  1195.     {
  1196.         number += 4;
  1197.         pos += 4;
  1198.     }
  1199.     /* Ignore '+' */
  1200.     if (number[0] == '+')
  1201.     {
  1202.         number++;
  1203.         pos++;
  1204.     }
  1205.     /* Find position of first extension character */
  1206.     temp = strcspn((PS8) number, "+pw*#");
  1207.     if (temp)
  1208.     {
  1209.         number = number + temp;
  1210.         pos = pos + temp;
  1211.     }
  1212.     /* Check if extension character exists. */
  1213.     if (number[0] == '+' || number[0] == 'p' || number[0] == 'w' || number[0] == '*' || number[0] == '#')
  1214.     {
  1215.         return pos;
  1216.     }
  1217.     else
  1218.     {
  1219.         return 0;
  1220.     }
  1221. }
  1222. /*****************************************************************************
  1223.  * FUNCTION
  1224.  *  mmi_phb_number_compare_extension
  1225.  * DESCRIPTION
  1226.  *  
  1227.  * PARAMETERS
  1228.  *  number1     [?]     
  1229.  *  number2     [?]     
  1230.  * RETURNS
  1231.  *  
  1232.  *****************************************************************************/
  1233. BOOL mmi_phb_number_compare_extension(S8 *number1, S8 *number2)
  1234. {
  1235.     /*----------------------------------------------------------------*/
  1236.     /* Local Variables                                                */
  1237.     /*----------------------------------------------------------------*/
  1238.     U8 temp;
  1239.     /*----------------------------------------------------------------*/
  1240.     /* Code Body                                                      */
  1241.     /*----------------------------------------------------------------*/
  1242.     /* Ignore *31# and #31# when compare. */
  1243.     while (((number1[0] == '*') && (number1[1] == '3') && (number1[2] == '1') && (number1[3] == '#')) ||
  1244.            ((number1[0] == '#') && (number1[1] == '3') && (number1[2] == '1') && (number1[3] == '#')))
  1245.     {
  1246.         number1 += 4;
  1247.     }
  1248.     while (((number2[0] == '*') && (number2[1] == '3') && (number2[2] == '1') && (number2[3] == '#')) ||
  1249.            ((number2[0] == '#') && (number2[1] == '3') && (number2[2] == '1') && (number2[3] == '#')))
  1250.     {
  1251.         number2 += 4;
  1252.     }
  1253.     /* Ignore '+' when compare. */
  1254.     if (number1[0] == '+')
  1255.     {
  1256.         number1++;
  1257.     }
  1258.     if (number2[0] == '+')
  1259.     {
  1260.         number2++;
  1261.     }
  1262.     /* Only Compare Extension part. */
  1263.     temp = strcspn((PS8) number1, "+pw*#");
  1264.     if (temp)
  1265.     {
  1266.         number1 = number1 + temp;
  1267.     }
  1268.     temp = strcspn((PS8) number2, "+pw*#");
  1269.     if (temp)
  1270.     {
  1271.         number2 = number2 + temp;
  1272.     }
  1273.     /* Compare if the number is full match. */
  1274.     if (!strcmp((PS8) number1, (PS8) number2))
  1275.     {
  1276.         return TRUE;
  1277.     }
  1278.     else
  1279.     {
  1280.         return FALSE;
  1281.     }
  1282. }
  1283. /*****************************************************************************
  1284.  * FUNCTION
  1285.  *  mmi_phb_number_compare_before_extension
  1286.  * DESCRIPTION
  1287.  *  Compare number before extension part
  1288.  *  If two numbers are less than 9 digts, do not need to
  1289.  *  do extra handling
  1290.  * PARAMETERS
  1291.  *  number1     [?]     
  1292.  *  number2     [?]     
  1293.  * RETURNS
  1294.  *  
  1295.  *****************************************************************************/
  1296. BOOL mmi_phb_number_compare_before_extension(S8 *number1, S8 *number2)
  1297. {
  1298.     /*----------------------------------------------------------------*/
  1299.     /* Local Variables                                                */
  1300.     /*----------------------------------------------------------------*/
  1301.     U16 i;
  1302.     U16 len1, len2;
  1303.     U16 ext_pos1, ext_pos2;
  1304.     /*----------------------------------------------------------------*/
  1305.     /* Code Body                                                      */
  1306.     /*----------------------------------------------------------------*/
  1307.     /* Ignore *31# and #31# */
  1308.     while (((number2[0] == '*') && (number2[1] == '3') && (number2[2] == '1') && (number2[3] == '#')) ||
  1309.             ((number2[0] == '#') && (number2[1] == '3') && (number2[2] == '1') && (number2[3] == '#')) )
  1310.     {
  1311.         number2 += 4;
  1312.     }
  1313.     /* compare length shorter than 9
  1314.       if(g_phb_compare_length <= 9)
  1315.        return TRUE;
  1316.       although already compared when enter this function, still need to confirm the number type
  1317.       and need to do more comparation */
  1318.     ext_pos1 = mmi_phb_number_has_extension(number1);
  1319.     ext_pos2 = mmi_phb_number_has_extension(number2);
  1320.     if ((ext_pos1 == 0 && ext_pos2 != 0 && (number2[ext_pos2] == '#' || number2[ext_pos2] == '*'))
  1321.         || (ext_pos2 == 0 && ext_pos1 != 0 && (number2[ext_pos1] == '#' || number2[ext_pos1] == '*')))
  1322.     {   /* only one with extension '#' or '*'. Not match! */
  1323.         return FALSE;
  1324.     }
  1325.     len1 = (ext_pos1 == 0) ? strlen(number1) : ext_pos1;
  1326.     len2 = (ext_pos2 == 0) ? strlen(number2) : ext_pos2;
  1327.     if ((len1 < g_phb_compare_length) || (len2 < g_phb_compare_length))
  1328.     {
  1329.         U16 num_len1 = (number1[0] == '+') ? (len1 - 1) : len1;
  1330.         U16 num_len2 = (number2[0] == '+') ? (len2 - 1) : len2;
  1331.         if (num_len1 != num_len2)
  1332.         {
  1333.             return FALSE;
  1334.         }
  1335.         else    /* the same length except "+" sign */
  1336.         {
  1337.             for (i = 1; i <= len1 && i <= len2; i++)
  1338.             {
  1339.                 if (number1[len1 - i] != number2[len2 - i])
  1340.                 {
  1341.                     return FALSE;
  1342.                 }
  1343.             }
  1344.         }
  1345.         return TRUE;
  1346.     }
  1347.     /* (len1 >= g_phb_compare_length) && (len2 >= g_phb_compare_length) */
  1348.     for (i = 1; i <= g_phb_compare_length; i++)
  1349.     {
  1350.         if (number1[len1 - i] != number2[len2 - i])
  1351.         {
  1352.             return FALSE;
  1353.         }
  1354.     }
  1355.     return TRUE;
  1356. }
  1357. /*****************************************************************************
  1358.  * FUNCTION
  1359.  *  mmi_phb_number_check_full_match_with_extension
  1360.  * DESCRIPTION
  1361.  *  
  1362.  * PARAMETERS
  1363.  *  lookup_index        [IN]        
  1364.  *  number_in           [?]         
  1365.  * RETURNS
  1366.  *  
  1367.  *****************************************************************************/
  1368. BOOL mmi_phb_number_check_full_match_with_extension(U16 lookup_index, S8 *number_in)
  1369. {
  1370.     /*----------------------------------------------------------------*/
  1371.     /* Local Variables                                                */
  1372.     /*----------------------------------------------------------------*/
  1373.     U8 number_buff[MAX_PB_NUMBER_LENGTH + 1 + 1];
  1374.     U16 store_index = LookUpTable[lookup_index].store_index;
  1375.     /*----------------------------------------------------------------*/
  1376.     /* Code Body                                                      */
  1377.     /*----------------------------------------------------------------*/
  1378.     /* Check if mobile field is match */
  1379.     if (PhoneBook[store_index].tel.type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1380.     {
  1381.         number_buff[0] = '+';
  1382.         mmi_phb_convert_to_digit((U8*) (number_buff + 1), PhoneBook[store_index].tel.number, MAX_PB_NUMBER_LENGTH + 1);
  1383.     }
  1384.     else
  1385.     {
  1386.         mmi_phb_convert_to_digit(number_buff, PhoneBook[store_index].tel.number, MAX_PB_NUMBER_LENGTH + 1);
  1387.     }
  1388.     if (!mmi_phb_number_has_extension((S8*) number_buff) &&
  1389.         mmi_phb_number_compare_before_extension(number_in, (S8*) number_buff))
  1390.     {
  1391.         return TRUE;
  1392.     }
  1393. #ifdef __MMI_PHB_USIM_FIELD__
  1394.     /* Check number in the anr field */
  1395.     if (store_index >= MAX_PB_PHONE_ENTRIES)
  1396.     {
  1397.         if (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_ANRA)
  1398.         {
  1399.             if (phb_anr[store_index - MAX_PB_PHONE_ENTRIES][0].type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1400.             {
  1401.                 number_buff[0] = '+';
  1402.                 mmi_phb_convert_to_digit(
  1403.                     (U8*) (number_buff + 1),
  1404.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][0].number,
  1405.                     MAX_PB_NUMBER_LENGTH + 1);
  1406.             }
  1407.             else
  1408.             {
  1409.                 mmi_phb_convert_to_digit(
  1410.                     (U8*) number_buff,
  1411.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][0].number,
  1412.                     MAX_PB_NUMBER_LENGTH + 1);
  1413.             }
  1414.             if (!mmi_phb_number_has_extension((S8*) number_buff) &&
  1415.                 mmi_phb_number_compare_before_extension(number_in, (S8*) number_buff))
  1416.             {
  1417.                 return TRUE;
  1418.             }
  1419.         }
  1420.         if (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_ANRB)
  1421.         {
  1422.             if (phb_anr[store_index - MAX_PB_PHONE_ENTRIES][1].type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1423.             {
  1424.                 number_buff[0] = '+';
  1425.                 mmi_phb_convert_to_digit(
  1426.                     (U8*) (number_buff + 1),
  1427.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][1].number,
  1428.                     MAX_PB_NUMBER_LENGTH + 1);
  1429.             }
  1430.             else
  1431.             {
  1432.                 mmi_phb_convert_to_digit(
  1433.                     (U8*) number_buff,
  1434.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][1].number,
  1435.                     MAX_PB_NUMBER_LENGTH + 1);
  1436.             }
  1437.             if (!mmi_phb_number_has_extension((S8*) number_buff) &&
  1438.                 mmi_phb_number_compare_before_extension(number_in, (S8*) number_buff))
  1439.             {
  1440.                 return TRUE;
  1441.             }
  1442.         }
  1443.         if (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_ANRC)
  1444.         {
  1445.             if (phb_anr[store_index - MAX_PB_PHONE_ENTRIES][2].type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1446.             {
  1447.                 number_buff[0] = '+';
  1448.                 mmi_phb_convert_to_digit(
  1449.                     (U8*) (number_buff + 1),
  1450.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][2].number,
  1451.                     MAX_PB_NUMBER_LENGTH + 1);
  1452.             }
  1453.             else
  1454.             {
  1455.                 mmi_phb_convert_to_digit(
  1456.                     (U8*) number_buff,
  1457.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][2].number,
  1458.                     MAX_PB_NUMBER_LENGTH + 1);
  1459.             }
  1460.             if (!mmi_phb_number_has_extension((S8*) number_buff) &&
  1461.                 mmi_phb_number_compare_before_extension(number_in, (S8*) number_buff))
  1462.             {
  1463.                 return TRUE;
  1464.             }
  1465.         }
  1466.     }
  1467. #endif /* __MMI_PHB_USIM_FIELD__ */ 
  1468. #if !defined(__MMI_PHB_NO_OPTIONAL_FIELD__)
  1469.     /* Check number in the optional field */
  1470.     if ((store_index < MAX_PB_PHONE_ENTRIES) &&
  1471.         ((PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_HOME) ||
  1472.          (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_OFFICE) ||
  1473.          (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_FAX)))
  1474.     {
  1475.         S16 pError;
  1476.         ReadRecord(
  1477.             NVRAM_EF_PHB_FIELDS_LID,
  1478.             (U16) (store_index + 1),
  1479.             (void*)&PhoneBookOptionalFields,
  1480.             OPTIONAL_FIELDS_RECORD_SIZE,
  1481.             &pError);
  1482.         if (PhoneBook[store_index].field | MMI_PHB_ENTRY_FIELD_HOME)
  1483.         {
  1484.             if (!mmi_phb_number_has_extension((S8*) PhoneBookOptionalFields.homeNumber) &&
  1485.                 mmi_phb_number_compare_before_extension(number_in, (S8*) PhoneBookOptionalFields.homeNumber))
  1486.             {
  1487.                 g_phb_cntx.searched_number_type = MMI_PHB_ENTRY_FIELD_HOME;
  1488.                 return TRUE;
  1489.             }
  1490.         }
  1491.         if (PhoneBook[store_index].field | MMI_PHB_ENTRY_FIELD_OFFICE)
  1492.         {
  1493.             if (!mmi_phb_number_has_extension((S8*) PhoneBookOptionalFields.officeNumber) &&
  1494.                 mmi_phb_number_compare_before_extension(number_in, (S8*) PhoneBookOptionalFields.officeNumber))
  1495.             {
  1496.                 g_phb_cntx.searched_number_type = MMI_PHB_ENTRY_FIELD_OFFICE;
  1497.                 return TRUE;
  1498.             }
  1499.         }
  1500.         if (PhoneBook[store_index].field | MMI_PHB_ENTRY_FIELD_FAX)
  1501.         {
  1502.             if (!mmi_phb_number_has_extension((S8*) PhoneBookOptionalFields.faxNumber) &&
  1503.                 mmi_phb_number_compare_before_extension(number_in, (S8*) PhoneBookOptionalFields.faxNumber))
  1504.             {
  1505.                 g_phb_cntx.searched_number_type = MMI_PHB_ENTRY_FIELD_FAX;
  1506.                 return TRUE;
  1507.             }
  1508.         }
  1509.     }
  1510. #endif /* !defined(__MMI_PHB_NO_OPTIONAL_FIELD__) */ 
  1511.     return FALSE;
  1512. }
  1513. /*****************************************************************************
  1514.  * FUNCTION
  1515.  *  mmi_phb_number_find_first_without_extension
  1516.  * DESCRIPTION
  1517.  *  
  1518.  * PARAMETERS
  1519.  *  mid             [IN]        
  1520.  *  number          [IN]        
  1521.  *  number_in       [?]         
  1522.  * RETURNS
  1523.  *  
  1524.  *****************************************************************************/
  1525. S16 mmi_phb_number_find_first_without_extension(S16 mid, U32 number, S8 *number_in)
  1526. {
  1527.     /*----------------------------------------------------------------*/
  1528.     /* Local Variables                                                */
  1529.     /*----------------------------------------------------------------*/
  1530.     S16 i, new_mid, min_index;
  1531.     S16 counter = 0;
  1532.     U16 j;
  1533.     BOOL is_match = FALSE;
  1534.     /*----------------------------------------------------------------*/
  1535.     /* Code Body                                                      */
  1536.     /*----------------------------------------------------------------*/
  1537.     new_mid = mid;
  1538.     min_index = MAX_PB_ENTRIES;
  1539.     /* Compare number before mid */
  1540.     i = mid;
  1541.     while ((i >= 0) && (LookUpTable[i].number == number))
  1542.     {
  1543.         if (mmi_phb_number_check_full_match_with_extension(i, number_in))
  1544.         {
  1545.             for (j = 0; j < PhoneBookEntryCount; j++)
  1546.                 if (g_phb_name_index[j] == LookUpTable[i].store_index)
  1547.                 {
  1548.                     is_match = TRUE;
  1549.                     break;
  1550.                 }
  1551.             if (j < min_index)
  1552.             {
  1553.                 min_index = j;
  1554.                 new_mid = i;
  1555.             }
  1556.         }
  1557.         i--;
  1558.         counter++;
  1559.         if (counter >= MAX_PHB_NUMBER_COMP)
  1560.         {
  1561.             break;
  1562.         }
  1563.     }
  1564.     /* Compare number after mid */
  1565.     i = mid + 1;
  1566.     while ((i < g_phb_cntx.lookup_table_count) && (LookUpTable[i].number == number))
  1567.     {
  1568.         if (mmi_phb_number_check_full_match_with_extension(i, number_in))
  1569.         {
  1570.             for (j = 0; j < PhoneBookEntryCount; j++)
  1571.                 if (g_phb_name_index[j] == LookUpTable[i].store_index)
  1572.                 {
  1573.                     is_match = TRUE;
  1574.                     break;
  1575.                 }
  1576.             if (j < min_index)
  1577.             {
  1578.                 min_index = j;
  1579.                 new_mid = i;
  1580.             }
  1581.         }
  1582.         i++;
  1583.         counter++;
  1584.         if (counter >= MAX_PHB_NUMBER_COMP)
  1585.         {
  1586.             break;
  1587.         }
  1588.     }
  1589.     if (is_match)
  1590.     {
  1591.         return new_mid; /* Always return, even only number with extension exists. */
  1592.     }
  1593.     else
  1594.     {
  1595.         return -1;
  1596.     }
  1597.     /*
  1598.      * if(counter <= 1)  //Only one entry match.
  1599.      * return new_mid;
  1600.      * else if(min_index < MAX_PB_ENTRIES)
  1601.      * return new_mid;
  1602.      * else
  1603.      * return -1;
  1604.      */
  1605. }
  1606. /*****************************************************************************
  1607.  * FUNCTION
  1608.  *  mmi_phb_number_check_full_match_without_extension
  1609.  * DESCRIPTION
  1610.  *  
  1611.  * PARAMETERS
  1612.  *  lookup_index        [IN]        
  1613.  *  number_list         [?]         
  1614.  *  number_in           [?]         
  1615.  * RETURNS
  1616.  *  
  1617.  *****************************************************************************/
  1618. BOOL mmi_phb_number_check_full_match_without_extension(U16 lookup_index, S8 *number_list, S8 *number_in)
  1619. {
  1620.     /*----------------------------------------------------------------*/
  1621.     /* Local Variables                                                */
  1622.     /*----------------------------------------------------------------*/
  1623.     U16 store_index = LookUpTable[lookup_index].store_index;
  1624.     /*----------------------------------------------------------------*/
  1625.     /* Code Body                                                      */
  1626.     /*----------------------------------------------------------------*/
  1627.     /* Check if mobile field is match */
  1628.     if (PhoneBook[store_index].tel.type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1629.     {
  1630.         number_list[0] = '+';
  1631.         mmi_phb_convert_to_digit((U8*) (number_list + 1), PhoneBook[store_index].tel.number, MAX_PB_NUMBER_LENGTH + 1);
  1632.     }
  1633.     else
  1634.     {
  1635.         mmi_phb_convert_to_digit((U8*) number_list, PhoneBook[store_index].tel.number, MAX_PB_NUMBER_LENGTH + 1);
  1636.     }
  1637.     if (mmi_phb_number_compare_before_extension(number_in, (S8*) number_list) &&
  1638.         mmi_phb_number_compare_extension(number_in, (S8*) number_list))
  1639.     {
  1640.         return TRUE;
  1641.     }
  1642. #ifdef __MMI_PHB_USIM_FIELD__
  1643.     /* Check number in the anr field */
  1644.     if (store_index >= MAX_PB_PHONE_ENTRIES)
  1645.     {
  1646.         if (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_ANRA)
  1647.         {
  1648.             if (phb_anr[store_index - MAX_PB_PHONE_ENTRIES][0].type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1649.             {
  1650.                 number_list[0] = '+';
  1651.                 mmi_phb_convert_to_digit(
  1652.                     (U8*) (number_list + 1),
  1653.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][0].number,
  1654.                     MAX_PB_NUMBER_LENGTH + 1);
  1655.             }
  1656.             else
  1657.             {
  1658.                 mmi_phb_convert_to_digit(
  1659.                     (U8*) number_list,
  1660.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][0].number,
  1661.                     MAX_PB_NUMBER_LENGTH + 1);
  1662.             }
  1663.             if (mmi_phb_number_compare_before_extension(number_in, (S8*) number_list) &&
  1664.                 mmi_phb_number_compare_extension(number_in, (S8*) number_list))
  1665.             {
  1666.                 return TRUE;
  1667.             }
  1668.         }
  1669.         if (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_ANRB)
  1670.         {
  1671.             if (phb_anr[store_index - MAX_PB_PHONE_ENTRIES][1].type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1672.             {
  1673.                 number_list[0] = '+';
  1674.                 mmi_phb_convert_to_digit(
  1675.                     (U8*) (number_list + 1),
  1676.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][1].number,
  1677.                     MAX_PB_NUMBER_LENGTH + 1);
  1678.             }
  1679.             else
  1680.             {
  1681.                 mmi_phb_convert_to_digit(
  1682.                     (U8*) number_list,
  1683.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][1].number,
  1684.                     MAX_PB_NUMBER_LENGTH + 1);
  1685.             }
  1686.             if (mmi_phb_number_compare_before_extension(number_in, (S8*) number_list) &&
  1687.                 mmi_phb_number_compare_extension(number_in, (S8*) number_list))
  1688.             {
  1689.                 return TRUE;
  1690.             }
  1691.         }
  1692.         if (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_ANRC)
  1693.         {
  1694.             if (phb_anr[store_index - MAX_PB_PHONE_ENTRIES][2].type == MMI_CSMCC_INTERNATIONAL_ADDR)
  1695.             {
  1696.                 number_list[0] = '+';
  1697.                 mmi_phb_convert_to_digit(
  1698.                     (U8*) (number_list + 1),
  1699.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][2].number,
  1700.                     MAX_PB_NUMBER_LENGTH + 1);
  1701.             }
  1702.             else
  1703.             {
  1704.                 mmi_phb_convert_to_digit(
  1705.                     (U8*) number_list,
  1706.                     phb_anr[store_index - MAX_PB_PHONE_ENTRIES][2].number,
  1707.                     MAX_PB_NUMBER_LENGTH + 1);
  1708.             }
  1709.             if (mmi_phb_number_compare_before_extension(number_in, (S8*) number_list) &&
  1710.                 mmi_phb_number_compare_extension(number_in, (S8*) number_list))
  1711.             {
  1712.                 return TRUE;
  1713.             }
  1714.         }
  1715.     }
  1716. #endif /* __MMI_PHB_USIM_FIELD__ */ 
  1717. #if !defined(__MMI_PHB_NO_OPTIONAL_FIELD__)
  1718.     /* Check number in the optional field */
  1719.     if ((store_index < MAX_PB_PHONE_ENTRIES) &&
  1720.         ((PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_HOME) ||
  1721.          (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_OFFICE) ||
  1722.          (PhoneBook[store_index].field & MMI_PHB_ENTRY_FIELD_FAX)))
  1723.     {
  1724.         S16 pError;
  1725.         ReadRecord(
  1726.             NVRAM_EF_PHB_FIELDS_LID,
  1727.             (U16) (store_index + 1),
  1728.             (void*)&PhoneBookOptionalFields,
  1729.             OPTIONAL_FIELDS_RECORD_SIZE,
  1730.             &pError);
  1731.         if (PhoneBook[store_index].field | MMI_PHB_ENTRY_FIELD_HOME)
  1732.         {
  1733.             if (mmi_phb_number_compare_before_extension(number_in, (S8*) PhoneBookOptionalFields.homeNumber) &&
  1734.                 mmi_phb_number_compare_extension(number_in, (S8*) PhoneBookOptionalFields.homeNumber))
  1735.             {
  1736.                 g_phb_cntx.searched_number_type = MMI_PHB_ENTRY_FIELD_HOME;
  1737.                 return TRUE;
  1738.             }
  1739.         }
  1740.         if (PhoneBook[store_index].field | MMI_PHB_ENTRY_FIELD_OFFICE)
  1741.         {
  1742.             if (mmi_phb_number_compare_before_extension(number_in, (S8*) PhoneBookOptionalFields.officeNumber) &&
  1743.                 mmi_phb_number_compare_extension(number_in, (S8*) PhoneBookOptionalFields.officeNumber))
  1744.             {
  1745.                 g_phb_cntx.searched_number_type = MMI_PHB_ENTRY_FIELD_OFFICE;
  1746.                 return TRUE;
  1747.             }
  1748.         }
  1749.         if (PhoneBook[store_index].field | MMI_PHB_ENTRY_FIELD_FAX)
  1750.         {
  1751.             if (mmi_phb_number_compare_before_extension(number_in, (S8*) PhoneBookOptionalFields.faxNumber) &&
  1752.                 mmi_phb_number_compare_extension(number_in, (S8*) PhoneBookOptionalFields.faxNumber))
  1753.             {
  1754.                 g_phb_cntx.searched_number_type = MMI_PHB_ENTRY_FIELD_FAX;
  1755.                 return TRUE;
  1756.             }
  1757.         }
  1758.     }
  1759. #endif /* !defined(__MMI_PHB_NO_OPTIONAL_FIELD__) */ 
  1760.     return FALSE;
  1761. }
  1762. /*****************************************************************************
  1763.  * FUNCTION
  1764.  *  mmi_phb_number_find_first_with_extension
  1765.  * DESCRIPTION
  1766.  *  
  1767.  * PARAMETERS
  1768.  *  mid             [IN]        
  1769.  *  number          [IN]        
  1770.  *  number_in       [?]         
  1771.  * RETURNS
  1772.  *  
  1773.  *****************************************************************************/
  1774. S16 mmi_phb_number_find_first_with_extension(S16 mid, U32 number, S8 *number_in)
  1775. {
  1776.     /*----------------------------------------------------------------*/
  1777.     /* Local Variables                                                */
  1778.     /*----------------------------------------------------------------*/
  1779.     S16 i, new_mid, min_index, counter;
  1780.     U8 number_list[MAX_PB_NUMBER_LENGTH + 1 + 1];
  1781.     U16 j;
  1782.     /*----------------------------------------------------------------*/
  1783.     /* Code Body                                                      */
  1784.     /*----------------------------------------------------------------*/
  1785.     new_mid = mid;
  1786.     min_index = MAX_PB_ENTRIES;
  1787.     counter = 0;
  1788.     /* Compare number before mid */
  1789.     i = mid;
  1790.     while ((i >= 0) && (LookUpTable[i].number == number))
  1791.     {
  1792.         if (mmi_phb_number_check_full_match_without_extension(i, (S8*) number_list, number_in))
  1793.         {
  1794.             for (j = 0; j < PhoneBookEntryCount; j++)
  1795.                 if (g_phb_name_index[j] == LookUpTable[i].store_index)
  1796.                 {
  1797.                     break;
  1798.                 }
  1799.             if (j < min_index)
  1800.             {
  1801.                 min_index = j;
  1802.                 new_mid = i;
  1803.             }
  1804.         }
  1805.         i--;
  1806.         counter++;
  1807.         if (counter >= MAX_PHB_NUMBER_COMP)
  1808.         {
  1809.             break;
  1810.         }
  1811.     }
  1812.     /* Compare number after mid */
  1813.     i = mid + 1;
  1814.     while ((i < g_phb_cntx.lookup_table_count) && (LookUpTable[i].number == number))
  1815.     {
  1816.         if (mmi_phb_number_check_full_match_without_extension(i, (S8*) number_list, number_in))
  1817.         {
  1818.             for (j = 0; j < PhoneBookEntryCount; j++)
  1819.                 if (g_phb_name_index[j] == LookUpTable[i].store_index)
  1820.                 {
  1821.                     break;
  1822.                 }
  1823.             if (j < min_index)
  1824.             {
  1825.                 min_index = j;
  1826.                 new_mid = i;
  1827.             }
  1828.         }
  1829.         i++;
  1830.         counter++;
  1831.         if (counter >= MAX_PHB_NUMBER_COMP)
  1832.         {
  1833.             break;
  1834.         }
  1835.     }
  1836.     if (min_index == MAX_PB_ENTRIES)
  1837.     {
  1838.         U16 ext1 = 0;
  1839.         mmi_phb_convert_to_digit(
  1840.             number_list,
  1841.             PhoneBook[LookUpTable[new_mid].store_index].tel.number,
  1842.             MAX_PB_NUMBER_LENGTH + 1);
  1843.         if ((counter <= 1) && !mmi_phb_number_has_extension((S8*) number_list) &&
  1844.             ((ext1 = mmi_phb_number_has_extension(number_in)) > 0) &&
  1845.             (number_in[ext1] != '#') && (number_in[ext1] != '*'))
  1846.         {
  1847.             return mid;
  1848.         }
  1849.         else
  1850.         {
  1851.             return -1;
  1852.         }
  1853.     }
  1854.     else
  1855.     {
  1856.         return new_mid;
  1857.     }
  1858. }
  1859. #endif /* defined(__MMI_PHB_ADV_NUM_MATCH_MOBILE__) */ 
  1860. /*****************************************************************************
  1861.  * FUNCTION
  1862.  *  mmi_phb_lookup_table_search
  1863.  * DESCRIPTION
  1864.  *  Search for the number in the lookup table
  1865.  *  and returns the index of the matched entry.
  1866.  *  
  1867.  *  Its a non-recursive binary search
  1868.  * PARAMETERS
  1869.  *  number              [IN]        
  1870.  *  low                 [IN]        
  1871.  *  high                [IN]        
  1872.  *  number_ASCII        [IN]         
  1873.  *  storage             [IN]
  1874.  * RETURNS
  1875.  *  void
  1876.  *****************************************************************************/
  1877. U16 mmi_phb_lookup_table_search(U32 number, S16 low, S16 high, S8 *number_ASCII, U8 storage)
  1878. {
  1879.     /*----------------------------------------------------------------*/
  1880.     /* Local Variables                                                */
  1881.     /*----------------------------------------------------------------*/
  1882.     S16 mid;
  1883.     /*----------------------------------------------------------------*/
  1884.     /* Code Body                                                      */
  1885.     /*----------------------------------------------------------------*/
  1886.     while (low <= high)
  1887.     {
  1888.         mid = (low + high) / 2;
  1889.         if (number == LookUpTable[mid].number)
  1890.         {
  1891.             /*
  1892.              * Advanced Compare - Compare number longer than 9 digit,
  1893.              * with extension, find out the prior one if numbers are the same, and etc.
  1894.              */
  1895.         #if defined(__MMI_PHB_ADV_NUM_MATCH_MOBILE__)
  1896.             if (!mmi_phb_number_has_extension(number_ASCII))
  1897.             {
  1898.                 mid = mmi_phb_number_find_first_without_extension(mid, number, number_ASCII);
  1899.             }
  1900.             else
  1901.             {
  1902.                 mid = mmi_phb_number_find_first_with_extension(mid, number, number_ASCII);
  1903.             }
  1904.             if (mid < 0)
  1905.             {
  1906.                 return 0xffff;  /* an invalid number */
  1907.             }
  1908.             else
  1909.         #endif /* defined(__MMI_PHB_ADV_NUM_MATCH_MOBILE__) */ 
  1910.             {
  1911.                 if (storage == MMI_STORAGE_BOTH || 
  1912.                     (storage == MMI_SIM && LookUpTable[mid].store_index >= MAX_PB_PHONE_ENTRIES) || 
  1913.                     (storage == MMI_NVRAM && LookUpTable[mid].store_index < MAX_PB_PHONE_ENTRIES))
  1914.                 {
  1915.                     return LookUpTable[mid].store_index;    /* return storage location in array, begin from 0 */
  1916.                 }
  1917.                 mid++;
  1918.                 while ((mid < (g_phb_cntx.lookup_table_count - 1)) && number == LookUpTable[mid].number)
  1919.                 {
  1920.                     if (storage == MMI_STORAGE_BOTH || 
  1921.                         (storage == MMI_SIM && LookUpTable[mid].store_index >= MAX_PB_PHONE_ENTRIES) || 
  1922.                         (storage == MMI_NVRAM && LookUpTable[mid].store_index < MAX_PB_PHONE_ENTRIES))
  1923.                     {
  1924.                         return LookUpTable[mid].store_index;    /* return storage location in array, begin from 0 */
  1925.                     }
  1926.                     mid++;
  1927.                 }
  1928.             }
  1929.         }
  1930.         else if (number < LookUpTable[mid].number)
  1931.         {
  1932.             high = mid - 1;
  1933.         }
  1934.         else
  1935.         {
  1936.             low = mid + 1;
  1937.         }
  1938.     }
  1939.     return 0xffff;
  1940. }
  1941. /*****************************************************************************
  1942.  * FUNCTION
  1943.  *  mmi_phb_util_read_compare_length
  1944.  * DESCRIPTION
  1945.  *  Read the compare length from NVRAM
  1946.  * PARAMETERS
  1947.  *  void
  1948.  * RETURNS
  1949.  *  void
  1950.  *****************************************************************************/
  1951. void mmi_phb_util_read_compare_length(void)
  1952. {
  1953.     /*----------------------------------------------------------------*/
  1954.     /* Local Variables                                                */
  1955.     /*----------------------------------------------------------------*/
  1956.     S16 pError;
  1957.     U8 comp_len;
  1958.     /*----------------------------------------------------------------*/
  1959.     /* Code Body                                                      */
  1960.     /*----------------------------------------------------------------*/
  1961.     /* Already read value */
  1962.     if (g_phb_compare_length != 0xff)
  1963.     {
  1964.         return;
  1965.     }
  1966.     ReadRecord(NVRAM_EF_PHB_COMPARE_DIGIT_LID, 1, (void*)&comp_len, 1, &pError);
  1967.     if (comp_len < 6)
  1968.     {
  1969.         g_phb_compare_length = 6;
  1970.     }
  1971.     else if (comp_len > 20)
  1972.     {
  1973.         g_phb_compare_length = 20;
  1974.     }
  1975.     else
  1976.     {
  1977.         g_phb_compare_length = comp_len;
  1978.     }
  1979. }
  1980. /*****************************************************************************
  1981.  * FUNCTION
  1982.  *  mmi_phb_util_convert_number_to_int
  1983.  * DESCRIPTION
  1984.  *  Converts the last n characters of a phone number to digits
  1985.  * PARAMETERS
  1986.  *  ascii_number        [IN]        Input ascii number
  1987.  * RETURNS
  1988.  *  interger of input number
  1989.  *****************************************************************************/
  1990. U32 mmi_phb_util_convert_number_to_int(U8 *ascii_number)
  1991. {
  1992.     /*----------------------------------------------------------------*/
  1993.     /* Local Variables                                                */
  1994.     /*----------------------------------------------------------------*/
  1995.     U16 num_len;
  1996.     U16 ext_len;
  1997.     U16 buff_len = MAX_PB_NUMBER_LENGTH + 1;
  1998.     U8 *number;
  1999.     U8 temp_number[MAX_PB_NUMBER_LENGTH + 1 + 1];
  2000.     U8 compare_length = 9;  /* Maximum convert number length is 9 digits. (4 bytes integer) */
  2001.     /*----------------------------------------------------------------*/
  2002.     /* Code Body                                                      */
  2003.     /*----------------------------------------------------------------*/
  2004.     PRINT_INFORMATION(("---[PhonebookSearch.c] mmi_phb_util_convert_number_to_int() => number: [%s] n", ascii_number));
  2005.     if (ascii_number != NULL)
  2006.     {
  2007.         strncpy((S8*) temp_number, (S8*) ascii_number, buff_len);
  2008.         memset((temp_number + buff_len), 0x00, 1);  /* Makre sure there will be terminator */
  2009.     }
  2010.     else
  2011.     {
  2012.         return INVALID_NUMBER;
  2013.     }
  2014.     number = (U8*) temp_number;
  2015.     /* Ignore  *31# and #31# case */
  2016.     while (((number[0] == '*') && (number[1] == '3') && (number[2] == '1') && (number[3] == '#')) ||
  2017.            ((number[0] == '#') && (number[1] == '3') && (number[2] == '1') && (number[3] == '#')))
  2018.     {
  2019.         number += 4;
  2020.     }
  2021.     /* Skip the first plus sign */
  2022.     if (number[0] == '+')
  2023.     {
  2024.         number++;
  2025.     }
  2026.     /* number empty */
  2027.     if (number[0] == '')
  2028.     {
  2029.         return INVALID_NUMBER;
  2030.     }
  2031.     /* Find the position of extension number and remove that part */
  2032.     ext_len = strcspn((PS8) number, "+pw*#");
  2033.     if (!ext_len)
  2034.     {
  2035.         return INVALID_NUMBER;
  2036.     }
  2037.     else
  2038.     {
  2039.         MMI_ASSERT(ext_len <= buff_len);
  2040.         number[ext_len] = '';
  2041.         /* Read compare length from NVRAM */
  2042.         mmi_phb_util_read_compare_length();
  2043.         num_len = strlen((PS8) number);
  2044.         /* May compare less number than 9 digits */
  2045.         if (g_phb_compare_length < 9)
  2046.         {
  2047.             compare_length = g_phb_compare_length;
  2048.         }
  2049.         /* Convert at most 9 digits integer */
  2050.         if (num_len > compare_length)
  2051.         {
  2052.             number += num_len - compare_length;
  2053.         }
  2054.         /* return a 32 bits integer by atol() */
  2055.         return atol((PS8) number);
  2056.     }
  2057. }
  2058. /*-----------------------------------------------END  General Compare String Functions -------------------------------------------------*/
  2059. #define MMI_PHB_SEARCH_EMAIL
  2060. #if defined(__MMI_PHB_EMAIL_SORT__)
  2061. /*****************************************************************************
  2062.  * FUNCTION
  2063.  *  mmi_phb_sort_email_insert_index
  2064.  * DESCRIPTION
  2065.  *  This function inserts email to mapping table by its index.
  2066.  * PARAMETERS
  2067.  *  store_index     [IN]        
  2068.  * RETURNS
  2069.  *  void
  2070.  *****************************************************************************/
  2071. void mmi_phb_sort_email_insert_index(U16 store_index)
  2072. {
  2073.     /*----------------------------------------------------------------*/
  2074.     /* Local Variables                                                */
  2075.     /*----------------------------------------------------------------*/
  2076.     U16 pos;
  2077.     U16 i;
  2078.     S16 pError;
  2079. #ifdef __MMI_PHB_USIM_FIELD__
  2080.     U16 g_phb_email_index[MAX_PB_ENTRIES];
  2081. #else 
  2082.     U16 g_phb_email_index[MAX_PB_PHONE_ENTRIES];
  2083. #endif 
  2084.     /*----------------------------------------------------------------*/
  2085.     /* Code Body                                                      */
  2086.     /*----------------------------------------------------------------*/
  2087. #ifdef __MMI_PHB_USIM_FIELD__
  2088.     ReadRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_ENTRIES * sizeof(U16), &pError);
  2089.     if (PhoneBookEntryCount == 1)
  2090.     {
  2091.         g_phb_email_index[(PhoneBookEntryCount - 1)] = store_index;
  2092.     }
  2093.     else
  2094.     {
  2095.         pos = mmi_phb_sort_email_find_insert_pos(0, (PhoneBookEntryCount - 2), store_index, g_phb_email_index);
  2096.         for (i = (PhoneBookEntryCount - 1); i > pos; i--)
  2097.         {
  2098.             g_phb_email_index[i] = g_phb_email_index[i - 1];
  2099.         }
  2100.         g_phb_email_index[pos] = store_index;
  2101.     }
  2102.     WriteRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_ENTRIES * sizeof(U16), &pError);
  2103. #else /* __MMI_PHB_USIM_FIELD__ */ 
  2104.     ReadRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_PHONE_ENTRIES * sizeof(U16), &pError);
  2105.     if (g_phb_cntx.phone_used == 1)
  2106.     {
  2107.         g_phb_email_index[(g_phb_cntx.phone_used - 1)] = store_index;
  2108.     }
  2109.     else
  2110.     {
  2111.         pos = mmi_phb_sort_email_find_insert_pos(0, (g_phb_cntx.phone_used - 2), store_index, g_phb_email_index);
  2112.         for (i = (g_phb_cntx.phone_used - 1); i > pos; i--)
  2113.         {
  2114.             g_phb_email_index[i] = g_phb_email_index[i - 1];
  2115.         }
  2116.         g_phb_email_index[pos] = store_index;
  2117.     }
  2118.     WriteRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_PHONE_ENTRIES * sizeof(U16), &pError);
  2119. #endif /* __MMI_PHB_USIM_FIELD__ */ 
  2120. }
  2121. /*****************************************************************************
  2122.  * FUNCTION
  2123.  *  mmi_phb_sort_email_find_insert_pos
  2124.  * DESCRIPTION
  2125.  *  This function find the insert position for a new adding email.
  2126.  * PARAMETERS
  2127.  *  low                 [IN]        
  2128.  *  high                [IN]        
  2129.  *  store_index         [IN]        
  2130.  *  mapping_table       [?]         
  2131.  * RETURNS
  2132.  *  void
  2133.  *****************************************************************************/
  2134. U16 mmi_phb_sort_email_find_insert_pos(S32 low, S32 high, U16 store_index, U16 *mapping_table)
  2135. {
  2136.     /*----------------------------------------------------------------*/
  2137.     /* Local Variables                                                */
  2138.     /*----------------------------------------------------------------*/
  2139.     S32 mid;
  2140.     S16 flag;
  2141.     U8 same_count;
  2142.     S32 distance;
  2143.     /*----------------------------------------------------------------*/
  2144.     /* Code Body                                                      */
  2145.     /*----------------------------------------------------------------*/
  2146.     while (low <= high)
  2147.     {
  2148.         mid = (low + high) / 2;
  2149.         mmi_phb_sort_email_compare_by_encoding(store_index, mapping_table[mid], &same_count, &distance);
  2150.         if (distance > 0)
  2151.         {
  2152.             low = mid + 1;
  2153.             flag = -1;
  2154.         }
  2155.         else    /* Either > 0 or < 0, not possible ==0 */
  2156.         {
  2157.             high = mid - 1;
  2158.             flag = 1;
  2159.         }
  2160.     }
  2161.     if (flag == -1)
  2162.     {
  2163.         return (U16) (mid + 1);
  2164.     }
  2165.     else
  2166.     {
  2167.         return (U16) mid;
  2168.     }
  2169. }
  2170. /*****************************************************************************
  2171.  * FUNCTION
  2172.  *  mmi_phb_sort_email_compare_by_encoding
  2173.  * DESCRIPTION
  2174.  *  This function compare email precedence by encoding.
  2175.  *  If no email presents, use name instead.
  2176.  * PARAMETERS
  2177.  *  first           [IN]        
  2178.  *  second          [IN]        
  2179.  *  same_count      [?]         
  2180.  *  distance        [?]         
  2181.  * RETURNS
  2182.  *  void
  2183.  *****************************************************************************/
  2184. void mmi_phb_sort_email_compare_by_encoding(U16 first, U16 second, U8 *same_count, S32 *distance)
  2185. {
  2186.     /*----------------------------------------------------------------*/
  2187.     /* Local Variables                                                */
  2188.     /*----------------------------------------------------------------*/
  2189.     S8 *string1, *string2;
  2190.     S8 email1[(MAX_PB_EMAIL_LENGTH + 1) * ENCODING_LENGTH];
  2191.     S8 email2[(MAX_PB_EMAIL_LENGTH + 1) * ENCODING_LENGTH];
  2192.     S16 pError;
  2193.     /*----------------------------------------------------------------*/
  2194.     /* Code Body                                                      */
  2195.     /*----------------------------------------------------------------*/
  2196.     /*
  2197.      * Prepare data for compare string 1
  2198.      */
  2199.     if (PhoneBook[first].field & MMI_PHB_ENTRY_FIELD_EMAIL)
  2200.     {
  2201.     #ifdef __MMI_PHB_USIM_FIELD__
  2202.         if (first >= MAX_PB_PHONE_ENTRIES)
  2203.         {
  2204.             AnsiiToUnicodeString((S8*) pbEmailAddress, (S8*) phb_email[first - MAX_PB_PHONE_ENTRIES].email_address);
  2205.         }
  2206.         else
  2207.     #endif /* __MMI_PHB_USIM_FIELD__ */ 
  2208.         {
  2209.             ReadRecord(
  2210.                 NVRAM_EF_PHB_FIELDS_LID,
  2211.                 (U16) (first + 1),
  2212.                 (void*)&PhoneBookOptionalFields,
  2213.                 OPTIONAL_FIELDS_RECORD_SIZE,
  2214.                 &pError);
  2215.             AnsiiToUnicodeString(email1, (S8*) PhoneBookOptionalFields.emailAddress);
  2216.         }
  2217.         string1 = email1;
  2218.     }
  2219.     else
  2220.     {
  2221.         string1 = (S8*) PhoneBook[first].alpha_id.name;
  2222.     }
  2223.     /*
  2224.      * Prepare data for compare string 2
  2225.      */
  2226.     if (PhoneBook[second].field & MMI_PHB_ENTRY_FIELD_EMAIL)
  2227.     {
  2228.     #ifdef __MMI_PHB_USIM_FIELD__
  2229.         if (second >= MAX_PB_PHONE_ENTRIES)
  2230.         {
  2231.             AnsiiToUnicodeString((S8*) pbEmailAddress, (S8*) phb_email[second - MAX_PB_PHONE_ENTRIES].email_address);
  2232.         }
  2233.         else
  2234.     #endif /* __MMI_PHB_USIM_FIELD__ */ 
  2235.         {
  2236.             ReadRecord(
  2237.                 NVRAM_EF_PHB_FIELDS_LID,
  2238.                 (U16) (second + 1),
  2239.                 (void*)&PhoneBookOptionalFields,
  2240.                 OPTIONAL_FIELDS_RECORD_SIZE,
  2241.                 &pError);
  2242.             AnsiiToUnicodeString(email2, (S8*) PhoneBookOptionalFields.emailAddress);
  2243.         }
  2244.         string2 = email2;
  2245.     }
  2246.     else
  2247.     {
  2248.         string2 = (S8*) PhoneBook[second].alpha_id.name;
  2249.     }
  2250.     /*
  2251.      * compare strings
  2252.      */
  2253.     mmi_phb_compare_ucs2_strings(string1, string2, same_count, distance);
  2254.     /*
  2255.      * If two strings are the same, put smaller store index in front.
  2256.      */
  2257.     if (*distance == 0)
  2258.     {
  2259.         if (first < second)
  2260.         {
  2261.             *distance = -1;
  2262.         }
  2263.         else if (first > second)
  2264.         {
  2265.             *distance = 1;
  2266.         }
  2267.     }
  2268. }
  2269. /*****************************************************************************
  2270.  * FUNCTION
  2271.  *  mmi_phb_sort_email_delete_index
  2272.  * DESCRIPTION
  2273.  *  This function
  2274.  * PARAMETERS
  2275.  *  store_index     [IN]        
  2276.  * RETURNS
  2277.  *  void
  2278.  *****************************************************************************/
  2279. void mmi_phb_sort_email_delete_index(U16 store_index)
  2280. {
  2281.     /*----------------------------------------------------------------*/
  2282.     /* Local Variables                                                */
  2283.     /*----------------------------------------------------------------*/
  2284.     U16 pos, i;
  2285.     S16 pError;
  2286. #ifdef __MMI_PHB_USIM_FIELD__
  2287.     U16 g_phb_email_index[MAX_PB_ENTRIES];
  2288. #else 
  2289.     U16 g_phb_email_index[MAX_PB_PHONE_ENTRIES];
  2290. #endif 
  2291.     /*----------------------------------------------------------------*/
  2292.     /* Code Body                                                      */
  2293.     /*----------------------------------------------------------------*/
  2294. #ifdef __MMI_PHB_USIM_FIELD__
  2295.     ReadRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_ENTRIES * sizeof(U16), &pError);
  2296.     for (pos = 0; pos < (PhoneBookEntryCount + 1); pos++)
  2297.         if (g_phb_email_index[pos] == store_index)
  2298.         {
  2299.             break;
  2300.         }
  2301.     for (i = pos; i < (PhoneBookEntryCount + 1); i++)
  2302.     {
  2303.         g_phb_email_index[i] = g_phb_email_index[i + 1];
  2304.     }
  2305.     WriteRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_ENTRIES * sizeof(U16), &pError);
  2306. #else /* __MMI_PHB_USIM_FIELD__ */ 
  2307.     ReadRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_PHONE_ENTRIES * sizeof(U16), &pError);
  2308.     for (pos = 0; pos < (g_phb_cntx.phone_used + 1); pos++)
  2309.         if (g_phb_email_index[pos] == store_index)
  2310.         {
  2311.             break;
  2312.         }
  2313.     for (i = pos; i < (g_phb_cntx.phone_used + 1); i++)
  2314.     {
  2315.         g_phb_email_index[i] = g_phb_email_index[i + 1];
  2316.     }
  2317.     WriteRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_PHONE_ENTRIES * sizeof(U16), &pError);
  2318. #endif /* __MMI_PHB_USIM_FIELD__ */ 
  2319. }
  2320. /*****************************************************************************
  2321.  * FUNCTION
  2322.  *  mmi_phb_sort_email_delete_all_index
  2323.  * DESCRIPTION
  2324.  *  This function
  2325.  * PARAMETERS
  2326.  *  void
  2327.  * RETURNS
  2328.  *  void
  2329.  *****************************************************************************/
  2330. void mmi_phb_sort_email_delete_all_index(void)
  2331. {
  2332.     /*----------------------------------------------------------------*/
  2333.     /* Local Variables                                                */
  2334.     /*----------------------------------------------------------------*/
  2335.     S16 pError;
  2336. #ifdef __MMI_PHB_USIM_FIELD__
  2337.     U16 g_phb_email_index[MAX_PB_ENTRIES];
  2338. #else 
  2339.     U16 g_phb_email_index[MAX_PB_PHONE_ENTRIES];
  2340. #endif 
  2341.     /*----------------------------------------------------------------*/
  2342.     /* Code Body                                                      */
  2343.     /*----------------------------------------------------------------*/
  2344. #ifdef __MMI_PHB_USIM_FIELD__
  2345.     memset(g_phb_email_index, 0xff, MAX_PB_ENTRIES * sizeof(U16));
  2346.     WriteRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_ENTRIES * sizeof(U16), &pError);
  2347. #else /* __MMI_PHB_USIM_FIELD__ */ 
  2348.     memset(g_phb_email_index, 0xff, MAX_PB_PHONE_ENTRIES * sizeof(U16));
  2349.     WriteRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_PHONE_ENTRIES * sizeof(U16), &pError);
  2350. #endif /* __MMI_PHB_USIM_FIELD__ */ 
  2351. }
  2352. /*****************************************************************************
  2353.  * FUNCTION
  2354.  *  mmi_phb_search_email_binary_search
  2355.  * DESCRIPTION
  2356.  *  This function
  2357.  * PARAMETERS
  2358.  *  low                 [IN]        
  2359.  *  high                [IN]        
  2360.  *  ucs2_pattern        [?]         
  2361.  * RETURNS
  2362.  *  void
  2363.  *****************************************************************************/
  2364. U16 mmi_phb_search_email_binary_search(S32 low, S32 high, S8 *ucs2_pattern)
  2365. {
  2366.     /*----------------------------------------------------------------*/
  2367.     /* Local Variables                                                */
  2368.     /*----------------------------------------------------------------*/
  2369.     S16 pError;
  2370.     U16 g_phb_email_index[MAX_PB_PHONE_ENTRIES];
  2371.     S32 mid;
  2372.     S16 flag;
  2373.     U8 same_count;
  2374.     S32 distance;
  2375.     U16 index;
  2376.     S8 *string;
  2377.     /*----------------------------------------------------------------*/
  2378.     /* Code Body                                                      */
  2379.     /*----------------------------------------------------------------*/
  2380.     /* Get email mapping table from NVRAM */
  2381.     ReadRecord(NVRAM_EF_PHB_EMAIL_SORT_LID, 1, (void*)g_phb_email_index, MAX_PB_PHONE_ENTRIES * sizeof(U16), &pError);
  2382.     /* Use binary search to find nearest name. */
  2383.     while (low <= high)
  2384.     {
  2385.         mid = (low + high) / 2;
  2386.         index = g_phb_email_index[mid];
  2387.         /* Use email to compare pattern, if email empty, use name instead */
  2388.         ReadRecord(
  2389.             NVRAM_EF_PHB_FIELDS_LID,
  2390.             (U16) (index + 1),
  2391.             (void*)&PhoneBookOptionalFields,
  2392.             OPTIONAL_FIELDS_RECORD_SIZE,
  2393.             &pError);
  2394.         if (PhoneBookOptionalFields.emailAddress[0] != 0x00)
  2395.         {
  2396.             AnsiiToUnicodeString(pbEmailAddress, (PS8) PhoneBookOptionalFields.emailAddress);
  2397.             string = (S8*) pbEmailAddress;
  2398.         }
  2399.         else
  2400.         {
  2401.             string = (S8*) PhoneBook[index].alpha_id.name;
  2402.         }
  2403.         mmi_phb_compare_ucs2_strings(ucs2_pattern, string, &same_count, &distance);
  2404.         if (distance > 0)
  2405.         {
  2406.             low = mid + 1;
  2407.             flag = -1;
  2408.         }
  2409.         /*
  2410.          * Distance == 0 or < 0 here
  2411.          * If there are duplicate entry, this will help to move up until first entry.
  2412.          */
  2413.         else
  2414.         {
  2415.             high = mid - 1;
  2416.             flag = 1;
  2417.         }
  2418.     }
  2419.     if (flag == -1)
  2420.     {
  2421.         return (U16) (mid + 1);
  2422.     }
  2423.     else
  2424.     {
  2425.         return (U16) mid;
  2426.     }
  2427. }
  2428. #endif /* defined(__MMI_PHB_EMAIL_SORT__) */ 
  2429. #endif /* _PHONEBOOKSEARCH_C */