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

📄 pgprngpub.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Okay, allocated - fill it in */
	iter->set.pool = pool;
	iter->set.next = pool->sets;
	iter->set.type = RINGSET_ITERATOR;
	pool->sets = &iter->set;
	iter->set.mask = set->mask;
	iter->level = 0;	/* Rewind to beginning */
	return iter;
}

void
ringIterDestroy(RingIterator *iter)
{
	RingPool *pool;
	RingSet **setp;

	if (iter) {
		pool = iter->set.pool;

		pgpAssert(iter->set.type == RINGSET_ITERATOR);
		iter->set.type = RINGSET_FREE;

		/* Remove it from the list of allocated sets */
		setp = &pool->sets;
		while (*setp != &iter->set) {
			pgpAssert(*setp);
			setp = &(*setp)->next;
		}
		*setp = iter->set.next;

		/* Add to the list of free iterators. */
		iter->set.next = (RingSet *)pool->freeiter;
		pool->freeiter = iter;
	}
}

static RingSet *
ringSetAlloc(RingPool *pool)
{
	RingSet *set;

	/* Allocate the structure */
	set = pool->freesets;
	if (set) {
		pool->freesets = set->next;
	} else {
		set = (RingSet *)memPoolNew(&pool->structs,
						   RingSet);
		if (!set) {
			ringAllocErr(pool);
			return NULL;
		}
	}

	/* Okay, allocated - fill it in */
	set->pool = pool;
	set->next = pool->sets;
	pool->sets = set;
	pgpVirtMaskInit (pool, &set->mask);
	/* set->type uninitialized */

	return set;
}

RingSet *
ringSetCreate(RingPool *pool)
{
	PGPVirtMask mask;
	RingSet *set;
	unsigned bit;
	PGPError err;

	if (!pool)
		return NULL;

	/* Allocate a new bit */
	err = ringBitAlloc(pool, &bit);
	if (IsPGPError(err)) {
		ringSimpleErr(pool, err);
		return NULL;
	}

	pgpVirtMaskInit (pool, &mask);
	pgpVirtMaskSetBit (pool, &mask, bit);

	/* Allocate the structure */
	set = ringSetAlloc(pool);
	if (set) {
		pgpVirtMaskCopy (pool, &mask, &set->mask);
		set->type = RINGSET_MUTABLE;
		pgpVirtMaskOR (pool, &mask, &pool->allocmask);
	}
	pgpVirtMaskCleanup (pool, &mask);
	return set;
}

/* Create a "universal" set which represents all keys in the pool */
RingSet *
ringSetCreateUniversal(RingPool *pool)
{
	RingSet *set;

	if (!pool)
		return NULL;

	/* Allocate the structure */
	set = ringSetAlloc(pool);
	if (set) {
		pgpVirtMaskCopy (pool, &pool->allocmask, &set->mask);
		set->type = RINGSET_IMMUTABLE;
	}
	return set;
}

void
ringSetDestroy(RingSet *set)
{
	RingPool *pool;
	RingSet **setp;

	if (set) {
		pool = set->pool;
		pgpAssert(set->type < RINGSET_FREE);
		set->type = RINGSET_FREE;

		/* Remove it from the list of allocated sets */
		setp = &pool->sets;
		while (*setp != set) {
			pgpAssert(*setp);
			setp = &(*setp)->next;
		}
		*setp = set->next;

		pgpVirtMaskCleanup (pool, &set->mask);

		/* Add to the list of free sets. */
		set->next = pool->freesets;
		pool->freesets = set;
	}
}

/*
 * Freeze a RingSet so that you can start doing set operations
 * on it, copying it, etc.
 */
	PGPError
ringSetFreeze(RingSet *set)
{
	if (set) {
		if (set->type == RINGSET_MUTABLE)
			set->type = RINGSET_IMMUTABLE;
		pgpAssert(set->type == RINGSET_IMMUTABLE);
	}
	return kPGPError_NoErr;
}

RingSet *
ringSetCopy(RingSet const *s)
{
	RingSet *set;

	if (!s)
		return NULL;

	pgpAssert(!RINGSETISMUTABLE(s));
	set = ringSetAlloc(s->pool);
	if (set) {
		pgpVirtMaskCopy (s->pool, &s->mask, &set->mask);
		set->type = RINGSET_IMMUTABLE;
	}
	return set;
}

/* This accepts NULL as an alias for "no such set" */
RingSet *
ringSetUnion(RingSet const *s1, RingSet const *s2)
{
	RingSet *set;

	if (!s1)
		return ringSetCopy(s2);

	set = ringSetCopy(s1);
	if (set && s2) {
		pgpAssert(s1->pool == s2->pool);
		pgpAssert(!RINGSETISMUTABLE(s2));
		pgpVirtMaskOR (s1->pool, &s2->mask, &set->mask);
	}
	return set;
}


/** The following operations only apply to mutable RingSets **/

/*
 * Add an object to a mutable RingSet.  That includes the all of the
 * object's parents in order to main the proper RingSet invariants.
 */
	int
ringSetAddObject(RingSet *set, union RingObject *obj)
{
	pgpAssert(RINGSETISMUTABLE(set));

	if (IsntNull(obj) && !pgpIsRingSetMember(set, obj)) {
		pgpVirtMaskOR (set->pool, &set->mask, &obj->g.mask);
		/* Ensure all parents are added, too. */
		while (!OBJISTOP(obj)) {
			obj = obj->g.up;
			if (pgpIsRingSetMember(set, obj))
				break;
			pgpVirtMaskOR (set->pool, &set->mask, &obj->g.mask);
		}
	}
	return 0;
}

/*
 * Add an object and its children to a mutable RingSet.  Also will do
 * the object's parents.  src RingSet controls which children are added.
 */
	int
ringSetAddObjectChildren(RingSet *dest, RingSet const *src,
	union RingObject *obj)
{
	RingSet const *srcx;
	RingIterator *iter;
	int level, initlevel;
	int nobjs;
	int err;

	/* Need to iterate over src, make a copy if necessary */
	srcx = src;
	if (RINGSETISMUTABLE(src)) {
		RingSet *src1 = ringSetCreate (ringSetPool (src));
		if (!src1)
			return ringSetError(src)->error;
		ringSetAddSet (src1, src);
		ringSetFreeze (src1);
		src = (RingSet const *)src1;
	}
			
	/* First add the object */
	if ((err= (PGPError)ringSetAddObject(dest, obj)) < 0)
		return err;

	iter = ringIterCreate(src);
	if (!iter)
		return ringSetError(src)->error;

	nobjs = 1;
	initlevel=ringIterSeekTo(iter, obj);
	if (initlevel < 0)
		return initlevel;
	level = initlevel + 1;
	while (level > initlevel) {
		union RingObject *child;
		err = (PGPError)ringIterNextObject(iter, level);
		if (err < 0) {
			ringIterDestroy(iter);
			return err;
		}
		if (err > 0) {
			child = ringIterCurrentObject(iter, level);
			if (!child)
				return ringSetError(src)->error;
			if ((err=ringSetAddObject(dest, child)) < 0)
				return err;
			++nobjs;
			++level;
		} else {
			--level;
		}
	}
	ringIterDestroy(iter);
	/* Destroy set copy if we made one */
	if (src != srcx)
		ringSetDestroy ((RingSet *)src);
	return nobjs;
}

/*
 * Remove an object from a mutable RingSet.  That includes the all of the
 * object's children in order to main the proper RingSet invariants.
 * (Done recursively.)
 */
int
ringSetRemObject(RingSet *set, union RingObject *obj)
{
	pgpAssert(RINGSETISMUTABLE(set));

	/*
	 * Remove this object and all its children.
	 * As an optimization, omit scanning children if the
	 * object is not already in the set.
	 */
	if (IsntNull(obj) && pgpIsRingSetMember (set, obj)) {
		if (!OBJISBOT(obj)) {
			union RingObject *obj2 = obj;
			for (obj2 = obj2->g.down; obj2; obj2 = obj2->g.next)
				ringSetRemObject(set, obj2);
		}
		pgpVirtMaskANDNOT (set->pool, &set->mask, &obj->g.mask);
		ringGarbageCollectObject(set->pool, obj);
	}
	return 0;
}

/* Helper function for ringSetAddSet */
static void
ringSetAddList(union RingObject *obj, RingSet *dest, RingSet const *src)
{
	while (obj) {
		if (pgpIsRingSetMember(src, obj)) {
			pgpVirtMaskOR (dest->pool, &dest->mask, &obj->g.mask);
			if (!OBJISBOT(obj))
				ringSetAddList(obj->g.down, dest, src);
		}
		obj = obj->g.next;
	}
}

int
ringSetAddSet(RingSet *set, RingSet const *set2)
{
	pgpAssert(RINGSETISMUTABLE(set));
	if (set2) {
		pgpAssert(set->pool == set2->pool);

		ringSetAddList(set->pool->keys, set, set2);
	}
	return 0;
}

/*
 * Subtracting sets is simplified by the proper-set requirement.
 * If I remove a key (because it's in set2), I have to remove all
 * children of the key, so I just use ringClearMask to do
 * the job.  If I don't (because it's not in set2), then it's
 * guaranteed that none of its children are in set2 either,
 * so there's no need to examine any children.
 */
int
ringSetSubtractSet(RingSet *set, RingSet const *set2)
{
	union RingObject *obj;
	PGPVirtMask tmask;

	pgpAssert(RINGSETISMUTABLE(set));

	pgpVirtMaskInit (set->pool, &tmask);

	if (IsntNull(set2) && !pgpVirtMaskIsEmpty(&set2->mask)) {
		pgpAssert(set->pool == set2->pool);
		for (obj = set->pool->keys; obj; obj = obj->g.next) {
			if (pgpIsRingSetMember (set, obj)
				&& pgpIsRingSetMember (set2, obj)) {
				pgpVirtMaskANDNOT (set->pool, &set->mask, &obj->g.mask);
				if (!OBJISBOT(obj)) {
					ringClearMask(set->pool, &obj->g.down, NULL,
								  &set->mask, &tmask);
				}
			}
		}
	}
	pgpVirtMaskCleanup (set->pool, &tmask);
	return 0;
}

static int
ringSetIntersectList(union RingObject *obj, RingSet const *s1,
	RingSet const *s2, RingSet const *dest)
{
	int flag = 0;

	while (obj) {
		if (pgpIsRingSetMember(s1,obj) &&
			pgpIsRingSetMember(s2,obj)) {
			flag = 1;
			pgpVirtMaskOR (s1->pool, &dest->mask, &obj->g.mask);
			if (!OBJISBOT(obj))
				ringSetIntersectList(obj->g.down, s1, s2, dest);
		}
		obj = obj->g.next;
	}
	return flag;
}

RingSet *
ringSetIntersection(RingSet const *s1, RingSet const *s2)
{
	RingSet *set;
	PGPVirtMask mask;

	if (!s1 || !s2)
		return (RingSet *)NULL;

	pgpVirtMaskInit (s1->pool, &mask);

	pgpAssert(s1->pool == s2->pool);
	pgpAssert(!RINGSETISMUTABLE(s1));
	pgpAssert(!RINGSETISMUTABLE(s2));

	/* Do a few trivial cases without allocating bits. */
	pgpVirtMaskCopy (s1->pool, &s1->mask, &mask);
	pgpVirtMaskANDNOT (s1->pool, &s2->mask, &mask);
	if (!pgpVirtMaskIsEmpty(&mask)) {	/* s1 is a subset of s2 - copy s1 */
		pgpVirtMaskCleanup (s1->pool, &mask);
		return ringSetCopy(s1);
	}

	pgpVirtMaskCopy (s1->pool, &s2->mask, &mask);
	pgpVirtMaskANDNOT (s1->pool, &s1->mask, &mask);
	if (!pgpVirtMaskIsEmpty(&mask)) {	/* s2 is a subset of s1 - copy s2 */
		pgpVirtMaskCleanup (s1->pool, &mask);
		return ringSetCopy(s2);
	}

	set = ringSetCreate(s1->pool);
	if (set) {
		if (!ringSetIntersectList(s1->pool->keys, s1, s2, set))
		{
			/* Empty set - free bit */
			pgpVirtMaskANDNOT (s1->pool, &set->mask, &s1->pool->allocmask);
			pgpVirtMaskCleanup (s1->pool, &set->mask);
		}
		set->type = RINGSET_IMMUTABLE;
	}
	pgpVirtMaskCleanup (s1->pool, &mask);
	return set;
}

static void
ringSetDiffList(union RingObject *obj, RingSet const *s1, RingSet const *s2,
				RingSet const *dest)
{
	while (obj) {
		if (pgpIsRingSetMember(s1, obj) &&
			!pgpIsRingSetMember(s2, obj)) {
			pgpVirtMaskOR (s1->pool, &dest->mask, &obj->g.mask);
			if (!OBJISBOT(obj))
				ringSetDiffList(obj->g.down, s1, s2, dest);
		}
		obj = obj->g.next;
	}
}

/* Return s1-s2. */
RingSet *
ringSetDifference(RingSet const *s1, RingSet const *s2)
{
	RingSet *set;
	PGPVirtMask mask;

	if (IsNull(s1))
		return NULL;
	if (IsNull(s2) || pgpVirtMaskIsEmpty(&s2->mask))
		return ringSetCopy(s1);

	pgpAssert(s1->pool == s2->pool);
	pgpAssert(!RINGSETISMUTABLE(s1));
	pgpAssert(!RINGSETISMUTABLE(s2));

	pgpVirtMaskInit (s1->pool, &mask);
	pgpVirtMaskCopy (s1->pool, &s1->mask, &mask);
	pgpVirtMaskANDNOT (s1->pool, &s2->mask, &mask);
	if (pgpVirtMaskIsEmpty(&mask)) {
		/* s1->mask is a subset of s2->mask, so result is empty */
		set = ringSetAlloc(s1->pool);
		if (set) {
			pgpVirtMaskCleanup (s1->pool, &set->mask);
			set->type = RINGSET_IMMUTABLE;
		}
	} else {
		set = ringSetCreate(s1->pool);
		if (set) {
			ringSetDiffList(s1->pool->keys, s1, s2, set);
			set->type = RINGSET_IMMUTABLE;
		}
	}
	pgpVirtMaskCleanup (s1->pool, &mask);
	return set;
}

int
ringFileIsDirty(RingFile const *file)
{
	return file ? file->flags & RINGFILEF_DIRTY : 0;
}

int
ringFileIsTrustChanged(RingFile const *file)
{
	return file ? file->flags & RINGFILEF_TRUSTCHANGED : 0;
}

RingPool *
ringPoolCreate(PGPEnv const *env)
{
	RingPool *pool;
	PGPContextRef	context	= pgpenvGetContext( env );

	pool = (RingPool *)pgpContextMemAlloc( context,
		sizeof(*pool), kPGPMemoryMgrFlags_Clear );
	if (pool)
		ringPoolInit( context, pool, env);
	return pool;
}

void
ringPoolDestroy(RingPool *pool)
{
	if (pool) {
		PGPContextRef cdkContext = pool->context;
		ringPoolFini(pool);
		pgpContextMemFree( cdkContext, pool);
	}
}

PGPContextRef
ringPoolContext(RingPool *pool)
{
	pgpAssert( pool );
	return pool->context;
}

union RingObject *
ringKeyById8(
	RingSet const *		set,
	PGPByte				pkalg,
	PGPByte const *		keyID)
{
	RingKey *key;

	if ((pkalg|1) == 3)	/* viacrypt */
		pkalg = 1;
	for (key = set->pool->hashtable[keyID[0]]; key; key = key->util) {
		if ((((key->pkalg|1) == 3) ? 1 : key->pkalg) == pkalg &&
		    memcmp(keyID, key->keyID, 8) == 0) {
			if (!pgpIsRingSetMember(set, (union RingObject *)key))
				break;
			ringObjectHold((union RingObject *)key);
			return (union RingObject *)key;
		}
	}
	/* Failed */
	return NULL;
}

#if 0
union RingObject *
ringKeyById4(

⌨️ 快捷键说明

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