📄 atbpb.c
字号:
*******************************************************************************/
void ATB_pb_CopyRec(SHORT phonebook_id, T_PB_RECORD *dest_record, T_PB_RECORD *src_record)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
dest_record->alpha.length = src_record->alpha.length;
dest_record->alpha.dcs = src_record->alpha.dcs;
memcpy((UBYTE *)dest_record->alpha.data, (UBYTE *)src_record->alpha.data, data->alpha_max*sizeof(USHORT));
memcpy(dest_record->number, src_record->number, data->number_max/2);
if (data->ext_max>0)
{
memcpy(dest_record->ext_data, src_record->ext_data, data->ext_max);
}
dest_record->ton_npi = src_record->ton_npi;
return;
}
/*******************************************************************************
$Function: ATB_pb_OK
$Description: This function is called if the requested FS command executed successfully.
$Returns: None.
$Arguments: phonebook_id The phonebook identifier
*******************************************************************************/
PB_RET ATB_pb_OK(SHORT phonebook_id)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
PB_RET result;
switch(data->command_id)
{
case PB_INITIALISE:
result = ATB_status_Initialise(phonebook_id);
break;
case PB_WRITEREC:
result = ATB_status_WriteRec(phonebook_id);
break;
case PB_DELETEREC:
result = ATB_status_DeleteRec(phonebook_id);
break;
}
return result;
}
/*******************************************************************************
$Function: ATB_pb_Error
$Description: This function is called if an error was returned while executing the
requested command.
$Returns: None.
$Arguments: phonebook_id The phonebook identifier
error_id Identifies the error that occurred.
*******************************************************************************/
void ATB_pb_Error(SHORT phonebook_id, SHORT error_id)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
/* Forward the error report to the GI */
GI_pb_Error(phonebook_id, data->command_id, error_id);
data->status = PB_STATUS_NONE;
return;
}
/*******************************************************************************
$Function: ATB_index_GetTable
$Description: Returns a pointer to the index table specified by the index_type
$Returns: None.
$Arguments: phonebook_id The phonebook identifier
index_type The index table required.
*******************************************************************************/
SHORT * ATB_index_GetTable(SHORT phonebook_id, T_PB_INDEX index_type)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
SHORT *table = NULL;
switch(index_type)
{
case INDEX_NAME:
table = data->name_table;
break;
case INDEX_NUMBER:
table = data->number_table;
break;
case INDEX_SEARCH:
table = data->search_table;
break;
default:
table = GI_pb_GetTable(index_type);
break;
}
return table;
}
/*******************************************************************************
$Function: ATB_index_Find
$Description: Find the nearest match to the supplied record. See ATB_pb_Find for
more information.
$Returns: PB_OK Action completed OK.
PB_BUSY Failed, phonebook is busy.
PB_FILEREADFAIL File read encountered an error
PB_RECDOESNOTEXIST Tried to access a record that does not exist
(should never happen)
$Arguments: phonebook_id The phonebook identifier
index_type The index_type of the provided record that is to be
searched for, and the index list that the resulting
new_log_index pertains to
record The record whose index_type is to be matched
new_log_index Returns with the logical index of the closest matching
record
match Specifies how good the resulting match was
(MATCH_NONE, MATCH_START, MATCH_FRAGMENT
or MATCH_EXACT).
*******************************************************************************/
PB_RET ATB_index_Find (SHORT phonebook_id, T_PB_INDEX index_type, T_PB_RECORD *record, SHORT *new_log_index, T_PB_MATCH *match)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
PB_RET result = PB_OK;
SHORT *table;
SHORT lower;
SHORT upper;
SHORT middle;
T_PB_RECORD *comp_record;
T_PB_COMPARE compare;
UBYTE searching;
/* Ensure that phonebook exists */
if (!data)
{
trace("**ERROR** Phonebook does not exist");
return PB_BOOKDOESNOTEXIST;
}
/* Allocate record for comparison */
comp_record = ATB_pb_AllocRec(phonebook_id);
/* Make sure we're searching a valid index type */
if (index_type==INDEX_PHYSICAL || index_type==INDEX_SEARCH)
{
GI_pb_Error(phonebook_id, PB_FIND, PB_INDEXINVALID);
return PB_INDEXINVALID;
}
table = ATB_index_GetTable(phonebook_id, index_type);
/* The initial upper and lower bounds are the bounds of the array */
lower = 0;
upper = data->records_used-1;
searching = TRUE;
/* If the list is empty, insert at 0 */
if (data->records_used==0)
{
middle = 0;
searching = FALSE;
}
while (searching)
{
/* Compare our record with the middle element of the partition */
middle = (lower+upper)/2;
result = ATB_mem_ReadRec(phonebook_id, index_type, middle, comp_record);
if (result!=PB_OK)
break;
compare = ATB_index_Compare(record, comp_record, index_type);
switch(compare)
{
case COMPARE_IDENTICAL:
/* We've found a match; stop searching */
searching = FALSE;
break;
case COMPARE_FIRSTBEFORE:
if (middle==lower)
{
/* The partition is a single element, so stop here. */
searching = FALSE;
}
else
{
/* Our record comes before the middle element;
* redefine the partiton */
upper = middle - 1;
}
break;
case COMPARE_FIRSTAFTER:
if (middle==upper)
{
/* The partition is a single element, so stop here. The record
* we need is the record after this one. */
middle++;
searching = FALSE;
}
else
{
/* Our record comes after the middle element;
* redefine the partiton */
lower = middle+1;
}
break;
}
}
/* Store our results */
if (new_log_index)
*new_log_index = middle;
if (match)
{
ATB_mem_ReadRec(phonebook_id, index_type, middle, comp_record);
*match = ATB_index_Match(record, comp_record, index_type);
}
/* Free allocated record */
ATB_pb_FreeRec(phonebook_id, comp_record);
/* Send success/failure info to the GI */
if (result==PB_OK)
GI_pb_OK(phonebook_id, PB_FIND, NULL);
else if (result!=PB_EXCT)
GI_pb_Error(phonebook_id, PB_FIND, result);
return result;
}
/*******************************************************************************
$Function: ATB_index_GetPhysIndex
$Description: Returns the physical index corresponding to the given logical index, in
the index table specified by the index_type.
$Returns: None.
$Arguments: phonebook_id The phonebook identifier.
index_type The index table required.
log_index The logical index.
*******************************************************************************/
SHORT ATB_index_GetPhysIndex(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
SHORT phys_index;
SHORT *table;
switch(index_type)
{
case INDEX_PHYSICAL:
phys_index = log_index;
break;
case INDEX_NAME:
case INDEX_NUMBER:
case INDEX_SEARCH:
table = ATB_index_GetTable(phonebook_id, index_type);
phys_index = table[log_index];
break;
}
return phys_index;
}
/*******************************************************************************
$Function: ATB_index_GetLogIndex
$Description: Provided with the physical index, finds the logical index of the record
in the index table specified.
$Returns: None.
$Arguments: phonebook_id The phonebook identifier
index_type The index table required.
phys_index The logical index of the record to find
*******************************************************************************/
SHORT ATB_index_GetLogIndex(SHORT phonebook_id, T_PB_INDEX index_type, SHORT phys_index)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
SHORT *table = ATB_index_GetTable(phonebook_id, index_type);
SHORT log_index;
if (index_type==INDEX_PHYSICAL)
{
log_index = phys_index;
}
else
{
for (log_index=0; log_index<data->records_used; log_index++)
{
if (table[log_index]==phys_index)
break;
}
}
return log_index;
}
/*******************************************************************************
$Function: ATB_index_AddRec
$Description: Adds a record to an index list, sorting automatically as required.
$Returns: None.
$Arguments: phonebook_id The phonebook identifier
index_type The index table required.
phys_index The physical index of the record to add.
record The record to add.
new_log_index New logical index of record.
*******************************************************************************/
void ATB_index_AddRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT phys_index, T_PB_RECORD *record, SHORT *new_log_index)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
SHORT *table = ATB_index_GetTable(phonebook_id, index_type);
SHORT log_index;
SHORT found_log_index;
ATB_index_Find(phonebook_id, index_type, record, &found_log_index, NULL);
/* Shift end of index table down */
for (log_index=data->records_used; log_index>found_log_index; log_index--)
{
table[log_index] = table[log_index-1];
}
table[found_log_index] = phys_index;
if (new_log_index)
*new_log_index = found_log_index;
return;
}
/*******************************************************************************
$Function: ATB_index_RemoveRec
$Description: Removes a record reference from an index list, sorting the index list
appropriately.
$Returns: None.
$Arguments: phonebook_id The phonebook identifier
index_type The index table required.
log_index The logical index of the record to remove
*******************************************************************************/
void ATB_index_RemoveRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
SHORT *table = ATB_index_GetTable(phonebook_id, index_type);
SHORT table_index;
for (table_index = log_index+1; table_index<data->records_used; table_index++)
{
table[table_index-1] = table[table_index];
}
return;
}
/*******************************************************************************
$Function: ATB_index_Match
$Description: This function attempts a match between two records based on the
index_type specified in index_type. It returns a value indicating
whether there is no match (MATCH_NONE), a partial match
(MAX_START), or an exact match (MATCH_EXACT).
The function GI_pb_Match is called first, to check whether there is
any user-specific matching required. If not, then ATB_alpha_Match
is called for an alpha tag, or ATB_num_Match for a phone number.
For any other index_type, MATCH_NONE is returned as default.
$Returns: MATCH_EXACT, MATCH_START or MATCH_NONE
$Arguments: record1 The first record to be compared
record2 The second record to be compared
index_type Indicator of the index_type which is to be matched
*******************************************************************************/
T_PB_MATCH ATB_index_Match(T_PB_RECORD *record1, T_PB_RECORD *record2, T_PB_INDEX index_type)
{
T_PB_MATCH match;
match = GI_pb_Match(record1, record2, index_type);
if (match==MATCH_DEFAULT)
{
switch(index_type)
{
case INDEX_NAME:
match = ATB_alpha_Match(&record1->alpha, &record2->alpha);
break;
case INDEX_NUMBER:
match = ATB_num_Match(record1->number, record2->number);
break;
}
}
return match;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -