📄 atbpb.c
字号:
phonebook_info->records_used = data->records_used;
phonebook_info->records_max = data->records_max;
phonebook_info->records_free = data->records_max - data->records_used;
phonebook_info->search_results = data->search_results;
return PB_OK;
}
/*******************************************************************************
$Function: ATB_pb_ReadRec
$Description: Reads a record from the logical position index. The record information
will be returned in the data structure pointed to by record. The
T_PB_RECORD structure must be allocated by the user.
This function calls the ATB_mem_ReadRec function, with an additional
check to make sure no other commands are currently executing.
$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
$Arguments: phonebook_id The phonebook identifier
index_type The index list from which the record is to be read
log_index Logical index in the index list of the record to read
record Structure in which to store record data
*******************************************************************************/
PB_RET ATB_pb_ReadRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index, T_PB_RECORD *record)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
PB_RET result;
tracefunction("ATB_pb_ReadRec");
/* Ensure that phonebook exists */
if (!data)
{
trace("**ERROR** Phonebook does not exist");
return PB_BOOKDOESNOTEXIST;
}
/* Make sure phonebook is not busy */
if (ATB_pb_Status(phonebook_id)==PB_BUSY)
{
trace("* ERROR * - Phonebook is busy");
result = PB_BUSY;
}
else
{
/* Read the record from cache or from file */
result = ATB_mem_ReadRec(phonebook_id, index_type, log_index, record);
}
/* Send success/failure info to the GI */
if (result==PB_OK)
GI_pb_OK(phonebook_id, PB_READREC, NULL);
else if (result!=PB_EXCT)
GI_pb_Error(phonebook_id, PB_READREC, result);
/* Close any open file */
FS_pb_Finished(phonebook_id);
return result;
}
/*******************************************************************************
$Function: ATB_pb_WriteRec
$Description: Writes a record to the logical position index. If the index is
PB_NEW_RECORD, a new record is added, otherwise the previous
record at that position is overwritten. The name and number index lists
will be updated with the new entry in the appropriate place in each.
GI_pb_OK will be called to confirm that the write completed successfully,
otherwise GI_pb_Error will be called with an error code.
Since the order of the records may change due to sorting, GI_pb_OK
will receive a pointer to an integer new_log_index, which will store the
new position of the record in the chosen index list. This is allocated
by and will be destroyed by the phonebook, so must be copied by the
GI before function return.
$Returns: PB_OK Action completed OK.
PB_EXCT Action currently executing, callback awaited.
GI_pb_OK will be called if successful,
GI_pb_Error otherwise.
GI_pb_OK will receive a pointer to the following:
SHORT new_log_index - The new position of the
record in the chosen index list
PB_BUSY Failed, phonebook is busy.
PB_FILEWRITEFAIL File write encountered an error
PB_RECDOESNOTEXIST (Overwriting only) Tried to access a record that
does not exist
$Arguments: phonebook_id The phonebook identifier
index_type The index list of the record to write
log_index Logical index in the index list of the record to write
record Pointer to record data to write to phonebook
(allocated by caller)
*******************************************************************************/
PB_RET ATB_pb_WriteRec(SHORT phonebook_id, T_PB_TYPE index_type, SHORT log_index, T_PB_RECORD *record)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
SHORT phys_index;
tracefunction("ATB_pb_WriteRec");
/* Ensure that phonebook exists */
if (!data)
{
trace("**ERROR** Phonebook does not exist");
return PB_BOOKDOESNOTEXIST;
}
/* Make sure phonebook is not busy */
if (ATB_pb_Status(phonebook_id)==PB_BUSY)
{
trace("* ERROR * - Phonebook is busy");
GI_pb_Error(phonebook_id, PB_WRITEREC, PB_BUSY);
return PB_BUSY;
}
/* Are we adding a new record, or overwriting an old one? */
if (log_index==PB_NEW_RECORD)
{
/* Is phonebook full? */
if (data->records_used==data->records_max)
{
GI_pb_Error(phonebook_id, PB_WRITEREC, PB_BOOKFULL);
return PB_BOOKFULL;
}
/* Find an empty physical record */
for (phys_index=0; phys_index<data->records_max; phys_index++)
{
if (data->in_memory[phys_index]==PB_EMPTY_RECORD)
break;
}
}
else
{
/* Check that record exists */
if (log_index<0
|| (log_index>=data->records_used && (index_type==INDEX_NAME || index_type==INDEX_NUMBER))
|| (index_type==INDEX_SEARCH && log_index>data->search_results)
|| (index_type==INDEX_PHYSICAL && log_index>data->records_max))
{
GI_pb_Error(phonebook_id, PB_WRITEREC, PB_RECDOESNOTEXIST);
return PB_RECDOESNOTEXIST;
}
phys_index = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index);
}
/* Set up command */
data->command_id = PB_WRITEREC;
data->status = PB_STATUS_INIT;
data->param.WriteRec.log_index = log_index;
data->param.WriteRec.index_type = index_type;
data->param.WriteRec.phys_index = phys_index;
data->param.WriteRec.record = record;
return ATB_status_WriteRec(phonebook_id);
}
/* Status function for WriteRec */
PB_RET ATB_status_WriteRec(SHORT phonebook_id)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
T_PB_WRITEREC *WriteRec = &data->param.WriteRec;
SHORT blocking;
PB_RET result;
SHORT name_log_index;
SHORT number_log_index;
SHORT *log_index_return;
blocking = TRUE;
while (blocking)
{
switch(data->status)
{
case PB_STATUS_INIT:
result = FS_pb_WriteRec(phonebook_id, WriteRec->phys_index, WriteRec->record);
/* Select next state */
data->status = PB_STATUS_COMPLETE;
/* Allow exit from function */
if (result!=PB_OK)
blocking = FALSE;
break;
case PB_STATUS_COMPLETE:
if (WriteRec->log_index!=PB_NEW_RECORD)
{
name_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NAME, WriteRec->phys_index);
ATB_index_RemoveRec(phonebook_id, INDEX_NAME, name_log_index);
number_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NUMBER, WriteRec->phys_index);
ATB_index_RemoveRec(phonebook_id, INDEX_NUMBER, number_log_index);
data->records_used--;
}
/* Indicate that record is new, then add to the cache */
data->in_memory[WriteRec->phys_index] = 0;
ATB_mem_UpdateCache(phonebook_id, WriteRec->phys_index, WriteRec->record);
/* Add the record to the index lists */
ATB_index_AddRec(phonebook_id, INDEX_NAME, WriteRec->phys_index, WriteRec->record, &name_log_index);
ATB_index_AddRec(phonebook_id, INDEX_NUMBER, WriteRec->phys_index, WriteRec->record, &number_log_index);
data->records_used++;
blocking = FALSE;
/* Close any open file */
FS_pb_Finished(phonebook_id);
FS_pb_WriteTables(phonebook_id, data->records_used, data->name_table, data->number_table);
/* Notify the GI of success */
log_index_return = NULL;
if (WriteRec->index_type==INDEX_NAME)
log_index_return = &name_log_index;
if (WriteRec->index_type==INDEX_NUMBER)
log_index_return = &number_log_index;
GI_pb_OK(phonebook_id, data->command_id, log_index_return);
result = PB_OK;
data->status = PB_STATUS_NONE;
break;
}
}
/* Report any errors to the GI */
if (result!=PB_OK && result!=PB_EXCT)
{
GI_pb_Error(phonebook_id, PB_WRITEREC, result);
}
return result;
}
/*******************************************************************************
$Function: ATB_pb_DeleteRec
$Description: Deletes a record at a logical position index.
GI_pb_OK will be called to confirm that the delete completed successfully,
otherwise GI_pb_Error will be called with an error code.
$Returns: PB_OK Action completed OK.
PB_EXCT Action currently executing, callback awaited.
GI_pb_OK will be called if successful,
GI_pb_Error otherwise.
PB_BUSY Failed, phonebook is busy.
PB_FILEWRITEFAIL File write encountered an error
PB_RECDOESNOTEXIST Tried to access a record that does not exist
$Arguments: phonebook_id The phonebook identifier
index_type The index list of the record to delete
log_index Logical index in the index list of the record to delete
*******************************************************************************/
PB_RET ATB_pb_DeleteRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
tracefunction("ATB_pb_DeleteRec");
/* Ensure that phonebook exists */
if (!data)
{
trace("**ERROR** Phonebook does not exist");
return PB_BOOKDOESNOTEXIST;
}
/* Make sure phonebook is not busy */
if (ATB_pb_Status(phonebook_id)==PB_BUSY)
{
trace("* ERROR * - Phonebook is busy");
GI_pb_Error(phonebook_id, PB_DELETEREC, PB_BUSY);
return PB_BUSY;
}
/* Check that record exists */
if (log_index<0
|| (log_index>=data->records_used && (index_type==INDEX_NAME || index_type==INDEX_NUMBER))
|| (index_type==INDEX_SEARCH && log_index>data->search_results)
|| (index_type==INDEX_PHYSICAL && log_index>data->records_max))
{
GI_pb_Error(phonebook_id, PB_DELETEREC, PB_RECDOESNOTEXIST);
return PB_RECDOESNOTEXIST;
}
/* Set up the command */
data->command_id = PB_DELETEREC;
data->status = PB_STATUS_INIT;
data->param.DeleteRec.log_index = log_index;
data->param.DeleteRec.index_type = index_type;
data->param.DeleteRec.phys_index = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index);
return ATB_status_DeleteRec(phonebook_id);
}
/* Status function for DeleteRec */
PB_RET ATB_status_DeleteRec(SHORT phonebook_id)
{
T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id);
T_PB_DELETEREC *DeleteRec = &data->param.DeleteRec;
SHORT blocking;
PB_RET result;
SHORT name_log_index;
SHORT number_log_index;
blocking = TRUE;
while (blocking)
{
switch(data->status)
{
case PB_STATUS_INIT:
result = FS_pb_DeleteRec(phonebook_id, DeleteRec->phys_index);
/* Select next state */
data->status = PB_STATUS_COMPLETE;
/* Allow exit from function */
if (result!=PB_OK)
blocking = FALSE;
break;
case PB_STATUS_COMPLETE:
name_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NAME, DeleteRec->phys_index);
ATB_index_RemoveRec(phonebook_id, INDEX_NAME, name_log_index);
number_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NUMBER, DeleteRec->phys_index);
ATB_index_RemoveRec(phonebook_id, INDEX_NUMBER, number_log_index);
data->records_used--;
data->in_memory[DeleteRec->phys_index] = -1;
/* Close any open file */
FS_pb_Finished(phonebook_id);
FS_pb_WriteTables(phonebook_id, data->records_used, data->name_table, data->number_table);
blocking = FALSE;
/* Notify the GI of success */
GI_pb_OK(phonebook_id, data->command_id, NULL);
result = PB_OK;
data->status = PB_STATUS_NONE;
break;
}
}
/* Report any errors to the GI */
if (result!=PB_OK && result!=PB_EXCT)
{
GI_pb_Error(phonebook_id, PB_DELETEREC, result);
}
return result;
}
/*******************************************************************************
$Function: ATB_pb_Find
$Description: Find the nearest match to the supplied record. Only the index_type
specified will be considered: if the index_type is INDEX_NAME, then the
name only will be matched; if INDEX_NUMBER, then just the number.
The new_log_index parameter should be a pointer to a user allocated
integer. This will return the logical index of the closest match in the
index list specified. This index either corresponds to a perfect match,
or to the record that would appear just after the provided record in the
list. For example, if the list consisted of record 0, Alice and record 1,
Carol, then a search for Bob would return 1. A search for a record
that would occur before the first record always returns 0. A search for
a record that would occur after the last record returns the index of the
last record +1.
The "match" parameter should be a pointer to a user allocated variable
of type T_PB_MATCH. This returns information about how closely the
found entry matches the record. In the example above, a search for
Bob would return 1 and MATCH_NONE; a search for Ca would return 1
and MATCH_START, and a search for Carol would return 1 and
MATCH_EXACT. Rarely, match may be MATCH_FRAGMENT: this can be
considered equivalent to MATCH_NONE in this context.
$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_pb_Find (SHORT phonebook_id, T_PB_INDEX index_type, T_PB_RECORD *record, SHORT *new_log_index, T_PB_MATCH *match)
{
PB_RET result;
tracefunction("ATB_pb_Find");
result = ATB_index_Find(phonebook_id, index_type, record, new_log_index, match);
/* Close any open file */
FS_pb_Finished(phonebook_id);
/* Send success/failure info to the GI */
if (result==PB_OK)
GI_pb_OK(phonebook_id, PB_FIND, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -