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

📄 record.c

📁 linux下的电话本的最底层
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	librecord2 - Record Object manipulation and storage library 2 * *	Authors: YE Nan <nan.ye@orange-ftgroup.com>  *	 *	This software and associated documentation files (the "Software")  *	are copyright (C) 2005 LiPS Linux Phone Standards Forum [FranceTelecom]  *	All Rights Reserved.  * *	A copyright license is hereby granted for redistribution and use of  *	the Software in source and binary forms, with or without modification,  *	provided that the following conditions are met:  *	- Redistributions of source code must retain the above copyright notice,  *	this copyright license and the following disclaimer.  *  - Redistributions in binary form must reproduce the above copyright  * 	notice, this copyright license and the following disclaimer in the  *	documentation and/or other materials provided with the distribution.  *	- Neither the name of LiPS  nor the names of its Members may be used  *	to endorse or promote products derived from the Software without  *	specific prior written permission.  * *	A patent license for any Necessary Claims owned by Members of LiPS Forum  *	to make, have made, use, import, offer to sell, lease and sell or otherwise  *	distribute any implementation compliant with the any specification adopted  *	by the LiPS Forumcan be obtained from the respective Members on reasonable  *	and non-discriminatory terms and conditions and under reciprocity, as  *	regulated in more detail in the Internal Policy of the LiPS Forum.  * *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER, ITS MEMBERS AND CONTRIBUTORS  *	"AS IS", AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  *	THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE  *	AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER,  *	ITS MEMBERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  *	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  *	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  *	POSSIBILITY OF SUCH DAMAGE.  */#include <stdio.h>#include <glib.h>#include <field.h>#include <template.h>#include <record.h>#include <iterator.h>#include <utils.h>#include "internal.h"/* * FID/FTID maps */typedef struct {	GArray		*fids;	guint32		 max_fid;	gboolean	 def_changed;} FidsMap;static FidsMap *fids_map_new (void){	FidsMap *map = NULL;		map = g_new0(FidsMap, 1);		map->fids = g_array_new(TRUE,													TRUE,													sizeof(guint32));	map->max_fid = 0;	map->def_changed = FALSE;		return map;}static voidfids_map_free (FidsMap	*map){	utils_g_array_free_generic(map->fids);	g_free(map);		return;}static voidfids_map_set_fid (FidsMap	*map,									gint		 i,									guint32	 val){	guint32 * dest = &g_array_index(map->fids, guint32, i);		*dest = val;		return;}#define	fids_map_size(map)							(map->fids->len)#define	fids_map_get_fid(map, i)				(g_array_index(map->fids, guint32, i))#define	fids_map_get_default_fid(map)		(fids_map_get_fid(map, 0))#define	fids_map_set_max_fid(map, fid)	(map->max_fid = fid)#define	fids_map_get_max_fid(map)				(map->max_fid)#define	fids_map_get_min_fid(map)				FID_GENERATE(FID_GET_FTID(fids_map_get_fid(map, 0)), 0)#define	fids_map_append_fid(map, fid)		(g_array_append_val(map->fids, fid))#define	fids_map_prepend_fid(map, fid)	(g_array_prepend_val(map->fids, fid))/** * @brief		Create a #Record object of specific template. * * @param		template	the #FieldTemplate objec used to generate  * 										#Record object *  * @return	newly-created #Record object  * 					or NULL if failed. */Record *							record_new (const FieldTemplate	*template){	Record * rec = NULL;	g_return_val_if_fail(template, NULL);	rec = g_new0(Record, 1);	rec->fields = g_hash_table_new_full(g_int_hash,																			g_int_equal,																			g_free,																			(GDestroyNotify)field_free);	rec->fids_map = g_hash_table_new_full(g_int_hash,																				g_int_equal,																				g_free,																				(GDestroyNotify)fids_map_free);	rec->template = template;	rec->extended	= FALSE;		return rec;}/** * @brief		Frees the memory allocated for the  * 					#Record object. * * @param		record		the #Record object */voidrecord_free (Record	*record){	g_return_if_fail(record);		g_hash_table_destroy(record->fields);	g_hash_table_destroy(record->fids_map);	g_free(record);	return;}static FidsMap *record_gen_base_fields (Record	*record,												guint32	 ftid){	const FieldDescriptor * fdesc = NULL;	FidsMap *map = NULL;	Iterator * iter = NULL;	gint i;	/* 	g_return_val_if_fail(record, FIELD_ID_INVALID);	g_return_val_if_fail(ftid != FIELD_TEMPLATE_ID_INVALID,											 FIELD_ID_INVALID);*/		/*	 * we need field descriptor(layouts) to generate	 * default fids of specific ftid.	 */	fdesc = field_template_get(record->template,														 ftid);	if (fdesc == NULL)	{		g_print("%s(): INVALID template id: %d\n",						__FUNCTION__,						ftid);									return NULL;	}		map = fids_map_new();		/*	 * a newly-generated fid for each layout	 * in field descriptor	 */	iter = field_descriptor_get_layouts(fdesc);	for (i = 0, iterator_to_first(iter);			 !iterator_at_last(iter);			 i++, iterator_next(iter))	{		/*		 * basic fid generation strategy:		 * 	FID = FTID * 100 + index;		 */		guint32 fid_gen = FID_GENERATE(ftid, i);		fids_map_append_fid(map, fid_gen);		fids_map_set_max_fid(map, fid_gen);//		g_array_append_val(map->fids, fid_gen);//		map->max_fid = fid_gen; 	}		iterator_free(iter, TRUE);	if (TRUE)	{		guint32 * key = NULL;				key = g_new0(guint32, 1);		*key = ftid;				/*		 * insert newly-generated fids map to		 * global hash table of maps. 		 */		g_hash_table_replace(record->fids_map,												 key,												 map);	}	return map;}/** * @brief		Add a new field in #Record object for * 					specific field template *  * @param		record	the #Record object * @param		ftid		the identifier of field template *  * @return	identifier of newly-added field in #Record * 					object. */guint32								record_add_field (Record	*record,									guint32	 ftid){	FieldDescriptor * fdesc = NULL;	FidsMap *map = NULL;	guint32 fid = FIELD_ID_INVALID;		g_return_val_if_fail(record, FIELD_ID_INVALID);	g_return_val_if_fail(ftid != FIELD_TEMPLATE_ID_INVALID,											 FIELD_ID_INVALID);		fdesc = field_template_get(record->template,														 ftid);	if (fdesc == NULL)	{		g_print("%s(): NULL Descriptor (%d).\n",						__FUNCTION__,						ftid);		return FIELD_ID_INVALID;	}	else if(!(fdesc->attribute & FIELD_ATTR_MULTIPLE))	{		g_print("%s(): CANNOT add field for template (%d). MULTI unset.\n",						__FUNCTION__,						ftid);		return FIELD_ID_INVALID;	}	/*	 * retrieve existing fids map of specific	 * ftid. if no existing map, generate one with	 * default layout.  	 */	map = (FidsMap *)g_hash_table_lookup(record->fids_map,																			 &ftid);	if (map == NULL)	{		map = record_gen_base_fields(record, ftid);	}		/*	 * extend fid generation strategy:	 * 	FID = MAX_GEN_FID + 1;	 */	fid = fids_map_get_max_fid(map) + 1;		fids_map_append_fid(map, fid);	fids_map_set_max_fid(map, fid);//	g_array_append_val(map->fids, fid);//	map->max_fid = fid;		return fid;}/** * @brief		Remove a existing field in #Record object for * 					specific field template *  * @param		record	the #Record object * @param		fid			the identifier of field to be removed */gboolean									record_remove_field (Record		*record,										 guint32	 fid){	FidsMap *map = NULL;	guint32 ftid = FIELD_TEMPLATE_ID_INVALID;		g_return_if_fail(record);	g_return_if_fail(fid != FIELD_TEMPLATE_ID_INVALID);		ftid = FID_GET_FTID(fid);		map = (FidsMap *)g_hash_table_lookup(record->fids_map,																			 &ftid);	if (map)	{		gint i;				for (i = 0; i < fids_map_size(map); i++)		{			guint32 tmp = g_array_index(map->fids,																	guint32,																	i);/*		g_print("%s: tmp/fid = %d/%d\n",							__FUNCTION__,							tmp,							fid);*/			if (tmp == fid)			{				break;			}		}/*	g_print("%s(): i = %d, size = %d\n",						__FUNCTION__,						i,						fids_map_size(map));*/		if (i == 0)		{			g_print("%s(): CANNOT remove default field (%d)\n",							__FUNCTION__,							fid);			return FALSE;		}				if (i < fids_map_size(map))		{			g_array_remove_index(map->fids, i);					g_hash_table_remove(record->fields,													&fid);		}		else		{			g_print("%s(): invalid field (%d)\n",							__FUNCTION__,							fid);			return FALSE;		}	}	else	{		return FALSE;	}		return TRUE;}/** * @brief		Set value of default field of specific field template  * 					in #Record object. *  * @param		record	the #Record object * @param		ftid		the identifier of specific field template * @param		value		the value to be set * @param		size		size of value or FIELD_SIZE_AUTO to force the function * 									calculates the size automatically with field template * 									definition * * @return	TRUE if set successfully */gboolean							record_set_field_default (Record				*record,													guint32				 ftid,													gconstpointer	 value,													FieldSize			 size){	Field * field = NULL;	FidsMap * map = NULL;	guint32 fid = FIELD_ID_INVALID;		g_return_val_if_fail(record, FALSE);	g_return_val_if_fail(ftid != FIELD_TEMPLATE_ID_INVALID,											 FALSE);	map = (FidsMap *)g_hash_table_lookup(record->fids_map,																			 &ftid);	if (map == NULL)	{		map = record_gen_base_fields(record, ftid);	}		fid = fids_map_get_default_fid(map);	field = g_hash_table_lookup(record->fields,															&fid);	if (field == NULL)	{		FieldDescriptor *fdesc = NULL;		guint32 * key = NULL;		fdesc = field_template_get(record->template,															 ftid);		key = g_new0(guint32, 1);		*key = fid;				field = field_new(fdesc);				g_hash_table_replace(record->fields,												 key,												 (gpointer)field);	}		field_set_value(field,									value,									size);		return TRUE;};/** * @brief		Set value of field in #Record object. *  * @param		record	the #Record object * @param		fid			the identifier of the field * @param		value		the value to be set * @param		size		size of value or FIELD_SIZE_AUTO to force the function * 									calculates the size automatically with field template * 									definition * * @return	TRUE if set successfully */gboolean							record_set_field (Record				*record,									guint32				 fid,									gconstpointer	 value,									FieldSize			 size){	Field * field = NULL;		g_return_val_if_fail(record, FALSE);		field = g_hash_table_lookup(record->fields,															&fid);	if (field == NULL)	{		FidsMap * map = NULL;		guint32 * key = NULL;		guint32 ftid = FIELD_TEMPLATE_ID_INVALID;		FieldDescriptor * fdesc = NULL;				ftid = FID_GET_FTID(fid);		g_return_val_if_fail(ftid != FIELD_TEMPLATE_ID_INVALID,												 FALSE);			fdesc = field_template_get(record->template,															 ftid);															 		map = (FidsMap *)g_hash_table_lookup(record->fids_map,																				 &ftid);		if (map == NULL)		{			map = record_gen_base_fields(record, ftid);		}				if (fid < fids_map_get_min_fid(map) ||				fid > fids_map_get_max_fid(map))		{			return FALSE;		}				key = g_new0(guint32, 1);		*key = fid;				field = field_new(fdesc);				g_hash_table_replace(record->fields,												 key,												 (gpointer)field);		if (record->extended == FALSE)		{			record->extended = (fid != fids_map_get_default_fid(map));		}	}		field_set_value(field,									value,									size);		return TRUE;}/** * @brief		Set label of default field of specific field template  * 					in #Record object. *  * @param		record	the #Record object * @param		ftid		the identifier of specific field template * @param		label		the label to be set * * @return	TRUE if set successfully */gboolean							record_set_label_default (Record			*record,													guint32			 ftid,													const gchar	*label){	Field * field = NULL;	FidsMap * map = NULL;	guint32 fid = FIELD_ID_INVALID;		g_return_val_if_fail(record, FALSE);	g_return_val_if_fail(ftid != FIELD_TEMPLATE_ID_INVALID,											 FALSE);	map = (FidsMap *)g_hash_table_lookup(record->fids_map,																			 &ftid);	if (map == NULL)	{		map = record_gen_base_fields(record, ftid);	}		fid = fids_map_get_default_fid(map);	field = g_hash_table_lookup(record->fields,															&fid);	if (field == NULL)	{		FidsMap * map = NULL;		guint32 * key = NULL;		guint32 ftid = FIELD_TEMPLATE_ID_INVALID;		FieldDescriptor * fdesc = NULL;				ftid = FID_GET_FTID(fid);		g_return_val_if_fail(ftid != FIELD_TEMPLATE_ID_INVALID,												 FALSE);			fdesc = field_template_get(record->template,															 ftid);															 		map = (FidsMap *)g_hash_table_lookup(record->fids_map,																				 &ftid);

⌨️ 快捷键说明

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