⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atbpb.c

📁 GSM手机设计软件代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	
	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 + -