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

📄 obj_dict.c.svn-base

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 SVN-BASE
字号:
#include "fitz-base.h"#include "fitz-stream.h"/* keep either names or strings in the dict. don't mix & match. */static int keyvalcmp(const void *ap, const void *bp){	const fz_keyval *a = ap;	const fz_keyval *b = bp;	if (fz_isname(a->k))		return strcmp(fz_toname(a->k), fz_toname(b->k));	if (fz_isstring(a->k))		return strcmp(fz_tostrbuf(a->k), fz_tostrbuf(b->k));	return -1;}static inline int keystrcmp(fz_obj *key, char *s){	if (fz_isname(key))		return strcmp(fz_toname(key), s);	if (fz_isstring(key))		return strcmp(fz_tostrbuf(key), s);	return -1;}fz_error *fz_newdict(fz_obj **op, int initialcap){	fz_obj *obj;	int i;	obj = *op = fz_malloc(sizeof (fz_obj));	if (!obj)	    return fz_throw("outofmem: dict struct");	obj->refs = 1;	obj->kind = FZ_DICT;	obj->u.d.sorted = 1;	obj->u.d.len = 0;	obj->u.d.cap = initialcap > 0 ? initialcap : 10;	obj->u.d.items = fz_malloc(sizeof(fz_keyval) * obj->u.d.cap);	if (!obj->u.d.items)	{	    fz_free(obj);	    return fz_throw("outofmem: dict item buffer");	}	for (i = 0; i < obj->u.d.cap; i++)	{		obj->u.d.items[i].k = nil;		obj->u.d.items[i].v = nil;	}	return fz_okay;}fz_error *fz_copydict(fz_obj **op, fz_obj *obj){	fz_error *error;	fz_obj *new;	int i;	if (!fz_isdict(obj))		return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));	error = fz_newdict(&new, obj->u.d.cap);	if (error)	    return fz_rethrow(error, "cannot create new dict");	for (i = 0; i < fz_dictlen(obj); i++)	{		error = fz_dictput(new, fz_dictgetkey(obj, i), fz_dictgetval(obj, i));		if (error)		{			fz_dropobj(new);			return fz_rethrow(error, "cannot copy dict entry");		}	}	*op = new;	return fz_okay;}fz_error *fz_deepcopydict(fz_obj **op, fz_obj *obj){	fz_error *error;	fz_obj *new;	fz_obj *val;	int i;	if (!fz_isdict(obj))		return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));	error = fz_newdict(&new, obj->u.d.cap);	if (error)	    return fz_rethrow(error, "cannot create new dict");	for (i = 0; i < fz_dictlen(obj); i++)	{		val = fz_dictgetval(obj, i);		if (fz_isarray(val))		{			error = fz_deepcopyarray(&val, val);			if (error)			{				fz_dropobj(new);				return fz_rethrow(error, "cannot deep copy item");			}			error = fz_dictput(new, fz_dictgetkey(obj, i), val);			if (error)			{				fz_dropobj(val);				fz_dropobj(new);				return fz_rethrow(error, "cannot add copied dict entry");			}			fz_dropobj(val);		}		else if (fz_isdict(val))		{			error = fz_deepcopydict(&val, val);			if (error)			{				fz_dropobj(new);				return fz_rethrow(error, "cannot deep copy item");			}			error = fz_dictput(new, fz_dictgetkey(obj, i), val);			if (error)			{				fz_dropobj(val);				fz_dropobj(new);				return fz_rethrow(error, "cannot add copied dict entry");			}			fz_dropobj(val);		}		else		{			error = fz_dictput(new, fz_dictgetkey(obj, i), val);			if (error)			{				fz_dropobj(new);				return fz_rethrow(error, "cannot copy dict entry");			}		}	}	*op = new;	return fz_okay;}static fz_error *growdict(fz_obj *obj){	fz_keyval *newitems;	int newcap;	int i;	newcap = obj->u.d.cap * 2;	newitems = fz_realloc(obj->u.d.items, sizeof(fz_keyval) * newcap);	if (!newitems)	    return fz_throw("outofmem: resize item buffer");	obj->u.d.items = newitems;	for (i = obj->u.d.cap; i < newcap; i++)	{		obj->u.d.items[i].k = nil;		obj->u.d.items[i].v = nil;	}	obj->u.d.cap = newcap;	return fz_okay;}intfz_dictlen(fz_obj *obj){	if (!fz_isdict(obj))		return 0;	return obj->u.d.len;}fz_obj *fz_dictgetkey(fz_obj *obj, int i){	if (!fz_isdict(obj))		return nil;	if (i < 0 || i >= obj->u.d.len)		return nil;	return obj->u.d.items[i].k;}fz_obj *fz_dictgetval(fz_obj *obj, int i){	if (!fz_isdict(obj))		return nil;	if (i < 0 || i >= obj->u.d.len)		return nil;	return obj->u.d.items[i].v;}static inline int dictfinds(fz_obj *obj, char *key){	if (obj->u.d.sorted)	{		int l = 0;		int r = obj->u.d.len - 1;		while (l <= r)		{			int m = (l + r) >> 1;			int c = -keystrcmp(obj->u.d.items[m].k, key);			if (c < 0)				r = m - 1;			else if (c > 0)				l = m + 1;			else				return m;		}	}	else	{		int i;		for (i = 0; i < obj->u.d.len; i++)			if (keystrcmp(obj->u.d.items[i].k, key) == 0)				return i;	}	return -1;}fz_obj *fz_dictgets(fz_obj *obj, char *key){	int i;	if (!fz_isdict(obj))		return nil;	i = dictfinds(obj, key);	if (i >= 0)		return obj->u.d.items[i].v;	return nil;}fz_obj *fz_dictget(fz_obj *obj, fz_obj *key){	if (fz_isname(key))		return fz_dictgets(obj, fz_toname(key));	if (fz_isstring(key))		return fz_dictgets(obj, fz_tostrbuf(key));	return nil;}fz_obj *fz_dictgetsa(fz_obj *obj, char *key, char *abbrev){	fz_obj *v;	v = fz_dictgets(obj, key);	if (v)		return v;	return fz_dictgets(obj, abbrev);}fz_error *fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val){	fz_error *error;	char *s;	int i;	if (!fz_isdict(obj))		return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));	if (fz_isname(key))		s = fz_toname(key);	else if (fz_isstring(key))		s = fz_tostrbuf(key);	else		return fz_throw("assert: key is not string or name (%s)", fz_objkindstr(obj));	i = dictfinds(obj, s);	if (i >= 0)	{		fz_dropobj(obj->u.d.items[i].v);		obj->u.d.items[i].v = fz_keepobj(val);		return fz_okay;	}	if (obj->u.d.len + 1 > obj->u.d.cap)	{		error = growdict(obj);		if (error)			return fz_rethrow(error, "cannot grow dict item buffer");	}	/* borked! */	if (obj->u.d.len)		if (keystrcmp(obj->u.d.items[obj->u.d.len - 1].k, s) > 0)			obj->u.d.sorted = 0;	obj->u.d.items[obj->u.d.len].k = fz_keepobj(key);	obj->u.d.items[obj->u.d.len].v = fz_keepobj(val);	obj->u.d.len ++;	return fz_okay;}fz_error *fz_dictputs(fz_obj *obj, char *key, fz_obj *val){	fz_error *error;	fz_obj *keyobj;	error = fz_newname(&keyobj, key);	if (error)		return fz_rethrow(error, "cannot create dict key");	error = fz_dictput(obj, keyobj, val);	fz_dropobj(keyobj);	if (error)		return fz_rethrow(error, "cannot insert dict entry");	return fz_okay;}fz_error *fz_dictdels(fz_obj *obj, char *key){	int i;	if (!fz_isdict(obj))		return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));	i = dictfinds(obj, key);	if (i >= 0)	{		fz_dropobj(obj->u.d.items[i].k);		fz_dropobj(obj->u.d.items[i].v);		obj->u.d.sorted = 0;		obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];		obj->u.d.len --;	}	return fz_okay;}fz_error *fz_dictdel(fz_obj *obj, fz_obj *key){	if (fz_isname(key))		return fz_dictdels(obj, fz_toname(key));	else if (fz_isstring(key))		return fz_dictdels(obj, fz_tostrbuf(key));	else		return fz_throw("assert: key is not string or name (%s)", fz_objkindstr(obj));}voidfz_dropdict(fz_obj *obj){	int i;	if (!fz_isdict(obj))		return;	for (i = 0; i < obj->u.d.len; i++) {		if (obj->u.d.items[i].k)			fz_dropobj(obj->u.d.items[i].k);		if (obj->u.d.items[i].v)			fz_dropobj(obj->u.d.items[i].v);	}	fz_free(obj->u.d.items);	fz_free(obj);}voidfz_sortdict(fz_obj *obj){	if (!fz_isdict(obj))		return;	if (!obj->u.d.sorted)	{		qsort(obj->u.d.items, obj->u.d.len, sizeof(fz_keyval), keyvalcmp);		obj->u.d.sorted = 1;	}}

⌨️ 快捷键说明

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