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

📄 carddb.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
					for( k = 0; k < count; k++ )
						SysLfree( record_head[k].data );
					SysLfree( record_head );
					FreeRecordList( local_search_list );
					return NULL;
				}
				head_info = (DBRECORDHEAD *)record;
				next_record_data->index = next_record_index->index;
				next_record_data->data = record;
				next_record_data->datalen = head_info->size;
				next_record_data++;
				count++;
			}else{
				flag = 0;
			}
			next_record_index = next_record_index->next;
		}

		if( count == 0 )
		{
			SysLfree( record_head );
			FreeRecordList( local_search_list );
			return lacb->head;
		}

		if( ( record_data_head = (RECORDDATA *)SysLmalloc( sizeof(RECORDDATA) * count ) ) == NULL ) 
		{
			for( k = 0; k < count; k++ )
				SysLfree( record_head[k].data );
			SysLfree( record_head );
			FreeRecordList( local_search_list );
			return NULL;
		}
		memcpy( record_data_head, record_head, ( sizeof(RECORDDATA) * count ) );
		lacb->head->num = count;
		lacb->head->head = record_data_head;
		SysLfree( record_head );
		FreeRecordList( local_search_list );
		CardDBSortList( lacb, lacb->head, CARD_NAME_FIELD, 0 );
		return ( lacb->head );
	}

	//验证字段值的有效性
	if( data == NULL )
		return NULL;

	switch( field )	//获取关键字的一二级索引
	{
		case CARD_NAME_FIELD:	// 姓名字段
			GetNameFieldIandIIIndex( data, field_I_index, field_II_index, &PY_num);	//将关键字转化为索引
			I_index_list += ( *field_I_index - 'a' );
			if( I_index_list->num == 0 )
			{
				goto endrv;
			}else{
				II_index_list = I_index_list->sub;
				II_index_list += ( *field_II_index );//确定二级索引表
			}
			break;
		case CARD_MOBILE_FIELD: // 手机号码字段
		case CARD_PHONE_FIELD:  // 固定电话号码字段
			GetPhoneFieldIandIIIndex( data, field_I_index, field_II_index, field );
			I_index_list += ( *field_I_index );//确定一级索引表
			if( I_index_list->num == 0 )
			{
				goto endrv;
			}else{
				II_index_list = I_index_list->sub;
				II_index_list += ( *field_II_index );//确定二级索引表
			}
			break;
		case CARD_RELATION_FIELD:	// 关系字段
			*field_I_index = (WORD)(*data & 0x0f);
			I_index_list += ( *field_I_index );//确定一级索引表
			break;
		default:
			break;
	}
			
	switch( field )	//得到查找的链表
	{
		case CARD_NAME_FIELD:	// 姓名字段
		case CARD_MOBILE_FIELD: // 手机号码字段
		case CARD_PHONE_FIELD:  // 固定电话号码字段
			if( II_index_list->num == 0 )	
				goto	endrv;

			if( ( record_head = (RECORDDATA *)SysLmalloc( sizeof(RECORDDATA) * II_index_list->num ) ) == NULL ) 
				return NULL;

			next_record_data = record_head;
			next_record_index = II_index_list->next;

			for( count = 0, i = 0; i < II_index_list->num; i++ )
			{
				//获取记录表上已有记录的同一字段值
				tmp_id = next_record_index->index;
				read_rv = GlobalReadRecord( lacb->gacb->PLInfo, tmp_id, &record );
				if( read_rv != DB_OK )
					goto endrv;
				head_info = (DBRECORDHEAD *)record;
				record_size = head_info->size;

				record_data = (BYTE *)(&head_info->data);

#ifdef SIM_ON_PC
				field_head = (WORD *)record_data;
				if( field_head[field] != 0 )			// 字段有字段值
#else
				Bytes2Word( &field_head, record_data+field*sizeof(WORD) );
				if( field_head != 0 )	// 字段有字段值
#endif
				{
#ifdef SIM_ON_PC
					WORD	next_field_value = field_head[field];
#else
					WORD	next_field_value = field_head, temp;
#endif
					FIELDINDEXLIST	*field_index_list = lacb->gacb->FList;
					field_index_list = field_index_list + field;
					while( next_field_value != 0 )
					{
						// 根据字段类型取出字段值
						switch( field_index_list->type )
						{
							case MULTI_VALUE_FIELD:		// 多值字段,带字段值索引
								field_value = record_data + next_field_value + 2;	// 跳过字段值索引(2字节)
#ifdef SIM_ON_PC
								next_field_value = *(WORD *)( record_data + next_field_value );
#else
								temp = next_field_value;
								Bytes2Word( &next_field_value, data + temp );
#endif
								break;
							case SINGLE_VALUE_FIELD:	// 单值字段,不带字段值索引
								field_value = record_data + next_field_value;
								next_field_value = 0;
								break;
						}
						rv = strcmp( field_value, data );	//比较同一字段

						if( ( ( rv == 0 ) && ( mode == PRECISE_FULL_MATCH ) )
							|| ( ( rv >= 0 ) && ( mode == PRECISE_PART_MATCH ) ) )	//完全匹配
						{
							if( mode == PRECISE_PART_MATCH )
							{
								cmp_data_size = (WORD)strlen(data);
								if( ( tmp_field_value = (BYTE *)SysLmalloc( cmp_data_size + 1 ) ) == NULL )
									return NULL;
								memcpy( tmp_field_value, field_value, cmp_data_size );
								*( tmp_field_value + cmp_data_size ) = '\0';
								rv = strcmp( tmp_field_value, data );
								SysLfree( tmp_field_value );
							}
							
							if( rv == 0 )
							{
								next_record_data->index = tmp_id;
								next_record_data->datalen = record_size;
								next_record_data->data = record;	
								count++;
								next_record_data++;
							}else{
								SysLfree( record );
							}
						}else{
							SysLfree( record );
						}
					}
				}
				next_record_index = next_record_index->next;
			}

			lacb->head->num = count;
			if( count == 0 )
			{
				SysLfree( record_head );
				goto	endrv;
			}

			if( ( record_data_head = (RECORDDATA *)SysLmalloc( sizeof(RECORDDATA) * count ) ) == NULL ) 
				return NULL;
			memcpy( record_data_head, record_head, ( sizeof(RECORDDATA) * count ) );
			lacb->head->num = count;
			lacb->head->head = record_data_head;
			SysLfree( record_head );
			break;
		case CARD_RELATION_FIELD:	// 关系字段
			lacb->head->num = I_index_list->num;
			if( I_index_list->num == 0 )
				goto	endrv;
			lacb->head->head = ObtainSearchList( lacb->gacb->PLInfo, I_index_list->next, lacb->head->num );
			break;
	}
	CardDBSortList( lacb, lacb->head, CARD_NAME_FIELD, 0 );

endrv:
	return ( lacb->head );
}
/**********************************************************************/
//在指定数据库中查找与指定字段索引匹配(完全匹配/部分匹配)的记录(模糊查找)
LOCALSEARCHLIST* CardDBSortRecord( DBLACB *lacb, BYTE field, BYTE *data, BYTE reserved )
{
	return NULL;
}

/**********************************************************************/
//对指定列表进行排序
LOCALSEARCHLIST* CardDBSortList( DBLACB *lacb, LOCALSEARCHLIST *searchlist, BYTE field, BYTE reserved )
{
	WORD				i, count;
	CHAR				rv;			//字段值比较结果
	DBRECORDHEAD		*head_info, *tmp_head_info;
	BYTE				*record_data, *field_value, *tmp_data, *tmp_field_value;
#ifdef SIM_ON_PC
	WORD				*field_head, *tmp_field_head;
#else
	WORD				field_head, tmp_field_head;
#endif
	RECORDDATA			*next_record_data;

	//验证字段的有效性
	if( field != CARD_NAME_FIELD )
		return NULL;
	
	if(  searchlist->num != 0 )
	{
		count = searchlist->num;
		if( ( next_record_data = (RECORDDATA *)SysLmalloc(sizeof(RECORDDATA)) ) == NULL )
			return NULL;
		while( count != 1 )	//冒泡算法
		{
			for( i = 0; i < (WORD)( count - 1 ) ; i++ )
			{
				head_info = (DBRECORDHEAD *)( searchlist->head[i].data );
				record_data = (BYTE *)(&head_info->data);
#ifdef SIM_ON_PC
				field_head = (WORD *)record_data;
				if( field_head[field] != 0 )
					field_value = record_data + field_head[field];
#else
				Bytes2Word( &field_head, record_data+field*sizeof(WORD) );
				if( field_head != 0 )	// 字段有字段值
					field_value = record_data + field_head;
#endif

				tmp_head_info = (DBRECORDHEAD *)( searchlist->head[i+1].data );
				tmp_data = (BYTE *)(&tmp_head_info->data);
#ifdef SIM_ON_PC
				tmp_field_head = (WORD *)tmp_data;
				if( tmp_field_head[field] != 0 )
					tmp_field_value = tmp_data + tmp_field_head[field];
#else
				Bytes2Word( &tmp_field_head, tmp_data+field*sizeof(WORD) );
				if( tmp_field_head != 0 )	// 字段有字段值
					tmp_field_value = tmp_data + tmp_field_head;
#endif

				switch( field )
				{
					case CARD_NAME_FIELD:
						rv = CompareChar( field_value, tmp_field_value );
						break;
				}
				if( rv > 0 )	//名字按拼音和长度排列(大的放后面),交换;时间按新的放在后面
				{
					//暂存前一个数据
					next_record_data->index = searchlist->head[i].index;
					next_record_data->data = searchlist->head[i].data;
					next_record_data->datalen = searchlist->head[i].datalen;

					//重新写入前一个数据
					searchlist->head[i].index = searchlist->head[i+1].index;
					searchlist->head[i].data = searchlist->head[i+1].data;
					searchlist->head[i].datalen = searchlist->head[i+1].datalen;

					//重新写入后一个数据
					searchlist->head[i+1].index = next_record_data->index;
					searchlist->head[i+1].data = next_record_data->data;
					searchlist->head[i+1].datalen = next_record_data->datalen;
				}
			}
			count--;
		}
		SysLfree( next_record_data );
	}
	return searchlist;
}

/*************** Local Functions ********************/
//初始化一级索引表
void InitIndexList( void )
{
	BYTE i;

	// 姓名一级索引表   //	for( i = 0; i < 26; i++ )
	for( i = 0; i < 27; i++ )
	{
		CARDNameField_I[i].next = NULL;
		CARDNameField_I[i].prev = NULL;
		CARDNameField_I[i].sub = NULL;
		CARDNameField_I[i].index = (WORD)(97+i);	// 'a' to 'z'
		CARDNameField_I[i].num = 0;
	}

	// 手机一级索引表
	for( i = 0; i < 100; i++ )
	{
		CARDMobileField_I[i].next = NULL;
		CARDMobileField_I[i].prev = NULL;
		CARDMobileField_I[i].sub = NULL;
		CARDMobileField_I[i].index = i;		// 0 to 99
		CARDMobileField_I[i].num = 0;
	}

	// 固话一级索引表
	for( i = 0; i < 100; i++ )
	{
		CARDPhoneField_I[i].next = NULL;
		CARDPhoneField_I[i].prev = NULL;
		CARDPhoneField_I[i].sub = NULL;
		CARDPhoneField_I[i].index = i;		// 0 to 99
		CARDPhoneField_I[i].num = 0;
	}

	// 关系索引表
	for( i = 0; i < 5; i++ )
	{
		CARDRelationField[i].next = NULL;
		CARDRelationField[i].prev = NULL;
		CARDRelationField[i].sub = NULL;
		CARDRelationField[i].index = i;		// 0 to 3
		CARDRelationField[i].num = 0;
	}
}

/**********************************************************************/
// 将字段值加入到字段索引表	
DWORD Add2FieldIndexTbl( DBGACB *gacb, BYTE field, BYTE *value, DWORD id )
{
	FIELDINDEXLIST		*list;
	BYTE				*temp;	//指向字段的暂存指针
	BYTE				i;
	FIELDINDEX			*I_index_list, *II_index_list;	//一、二级索引表
	WORD				field_I_index[PY_MAX_NUM], field_II_index[PY_MAX_NUM];//字段一二级索引值
	RECORDINDEX			*new_record_head;	//新纪录的地址
	BYTE				PY_num = 0;			//存放汉字的多音字的个数

	if( value == NULL )
		return DB_ERROR;

	temp = value;
	list = gacb->FList;
	I_index_list = list[field].head;//链接一级索引表

	switch( field )
	{
		case CARD_NAME_FIELD:	// 姓名字段
			GetNameFieldIandIIIndex( temp, field_I_index, field_II_index, &PY_num);	//将字段值转化为索引
			for( i = 0; i <= PY_num; i++ )			//把单音字/多音字逐个添加到字段索引表中
			{
//				I_index_list += ( *field_I_index - 'a' );
				I_index_list += ( field_I_index[i] - 'a' );
				II_index_list = CreateIIIndexList( I_index_list, field );// 新建姓名二级索引表
//				II_index_list += ( *field_II_index );//确定二级索引表
				II_index_list += ( field_II_index[i] );//确定二级索引表
				
				new_record_head = Add2RecordIndexTbl( II_index_list, id );
				Add2RecordIndex( gacb->RFList, id, new_record_head );// 将字段索引加入到记录字段表

				I_index_list = list[field].head;
//				field_I_index++;
//				field_II_index++;
			}
//			field_I_index -= (PY_num+1);
//			field_II_index -= (PY_num+1);
			break;
		case CARD_MOBILE_FIELD: // 手机号码字段
		case CARD_PHONE_FIELD: // 固定电话号码字段
			GetPhoneFieldIandIIIndex( temp, field_I_index, field_II_index, field );	//将字段值转化为索引
			I_index_list += ( *field_I_index );//确定一级索引表
			II_index_list = CreateIIIndexList( I_index_list, field );// 新建二级索引表
			II_index_list += ( *field_II_index );//确定二级索引表

			new_record_head = Add2RecordIndexTbl( II_index_list, id );
			Add2RecordIndex( gacb->RFList, id, new_record_head );// 将字段索引加入到记录字段表
			break;
		case CARD_RELATION_FIELD: // 关系字段

			*field_I_index = (WORD)( *value & 0x0f );
			I_index_list += ( *field_I_index );//确定一级索引表

			new_record_head = Add2RecordIndexTbl( I_index_list, id );
			Add2RecordIndex( gacb->RFList, id, new_record_head );// 将字段索引加入到记录字段表
			break;
		default:
			break;
	}

	return DB_OK;
}

/**********************************************************************/
//创建新的二级索引表
FIELDINDEX *CreateIIIndexList( FIELDINDEX *I_index_list, BYTE field )
{
	BYTE		k;
	FIELDINDEX	*II_index_list;

	II_index_list = I_index_list->sub;		//链接二级索引表
	if( II_index_list == NULL )	 //二级索引表为空,则动态申请二级索引表
	{
								
		switch( field )
		{		
			case CARD_NAME_FIELD:	// 姓名字段
				I_index_list->num = 54;				//更新一级索引表的索引数
				break;
			case CARD_MOBILE_FIELD: // 手机号码字段
			case CARD_PHONE_FIELD:  // 固话号码字段
				I_index_list->num = 100;			//更新一级索引表的索引数
				break;
		}

		if( ( II_index_list = (FIELDINDEX *)SysLmalloc( sizeof(FIELDINDEX) * ( I_index_list->num ) ) ) == NULL )
			return NULL;
		I_index_list->sub = II_index_list;	//链接二级索引表
		
		// 新建二级索引表
		for( k = 0; k < I_index_list->num; k++ )
		{
			II_index_list[k].next = NULL;		
			II_index_list[k].prev = NULL;
			II_index_list[k].sub = NULL;
			II_index_list[k].index = k;	
			II_index_list[k].num = 0;
		}
	}
	return ( II_index_list );
}

/**********************************************************************/
//获取手机号码字段值的一二级索引
void GetPhoneFieldIandIIIndex( BYTE *field_value, WORD *field_I_index, WORD *field_II_index, BYTE field )
{
	BYTE	*temp;
	BYTE	i = 0;

	temp = field_value;
	while( *temp != '\0' )	//记录字段长度
	{
		temp++;
		i++;
	}

	temp = field_value;
	switch( field )
	{
		case CARD_MOBILE_FIELD:
			temp += 1;					
			*field_I_index = (WORD)( ( ( *temp & 0x0f ) * 10 ) + ( *(temp+1) & 0x0f ) );				//第2位和3位作为一级索引
			temp = field_value;
			*field_II_index = (WORD)( ( ( *(temp + i - 2 ) & 0x0f ) *10 ) + ( *(temp + i - 1 ) & 0x0f ) );	//倒数第1位和2位作为二级索引
			break;
		case CARD_PHONE_FIELD:
			temp += ( i - 4 );					
			*field_I_index = (WORD)( ( ( *temp & 0x0f ) *10 ) + ( *(temp+1) & 0x0f ) );		//倒数第4位和第3位作为一级索引
			temp += 2;
			*field_II_index = (WORD)( ( ( *temp & 0x0f ) *10 ) + ( *(temp+1) & 0x0f ) );		//倒数第1位和第2位作为二级索引
			break;
	}
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -