var.c

来自「samba最新软件」· C语言 代码 · 共 2,216 行 · 第 1/4 页

C
2,216
字号
			cp = prop->name;			if (cp[0] == property[0] && strcmp(cp, property) == 0) {				break;			}			last = prop;		}	}	if (prop == (MprVar*) 0) {		mprAssert(prop);		return MPR_ERR_NOT_FOUND;	} 	if (prop->readonly) {		mprAssert(! prop->readonly);		return MPR_ERR_READ_ONLY;	}	if (obj->trigger) {		if ((obj->trigger)(MPR_VAR_DELETE_PROPERTY, obj->properties, prop, 0, 0)				== MPR_TRIGGER_ABORT) {			return MPR_ERR_ABORTED;		}	}	if (last) {		last->forw = prop->forw;	} else {		obj->properties->buckets[bucketIndex] = prop->forw;	}	obj->properties->numItems--;	if (! mprVarIsFunction(prop->type)) {		obj->properties->numDataItems--;	}	mprDestroyVar(prop);	return 0;}/******************************************************************************//* *	Find a property in an object and return a pointer to it. If a value arg *	is supplied, then copy the data into the var.  */MprVar *mprGetProperty(MprVar *obj, const char *property, MprVar *value){	MprVar	*prop, triggerValue;	int		rc;	if (obj == 0 || obj->type != MPR_TYPE_OBJECT || property == 0 || 			*property == '\0') {		if (value) {			value->type = MPR_TYPE_UNDEFINED;		}		return 0;	}	for (prop = getObjChain(obj->properties, property); prop; 			prop = prop->forw) {		if (prop->name &&			prop->name[0] == property[0] && strcmp(prop->name, property) == 0) {			break;		}	}	if (prop == 0) {		if (value) {			value->type = MPR_TYPE_UNDEFINED;		}		return 0;	}	if (value) {		if (prop->trigger) {			triggerValue = *prop;			triggerValue.allocatedVar = 0;			triggerValue.allocatedData = 0;			/*			 *	Pass the trigger the current read value and may receive			 *	a new value.			 */ 			rc = (prop->trigger)(MPR_VAR_READ, prop->parentProperties, prop, 				&triggerValue, 0);			if (rc == MPR_TRIGGER_ABORT) {				if (value) {					value->type = MPR_TYPE_UNDEFINED;				}				return 0;			} else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {				copyVarCore(prop, &triggerValue, MPR_SHALLOW_COPY);				mprDestroyVar(&triggerValue);			}		}		/*		 *	Clone. No copy.		 */		*value = *prop;	}	return prop;}/******************************************************************************//* *	Read a properties value. This returns the property's value. It does not *	copy object/string data but returns a pointer directly into the variable. *	The caller does not and should not call mprDestroy on the returned value. *	If value is null, just read the property and run triggers. */int mprReadProperty(MprVar *prop, MprVar *value){	MprVar	triggerValue;	int		rc;	mprAssert(prop);	if (prop->trigger) {		triggerValue = *prop;		triggerValue.allocatedVar = 0;		triggerValue.allocatedData = 0;		rc = (prop->trigger)(MPR_VAR_READ, prop->parentProperties, prop, 			&triggerValue, 0);		if (rc == MPR_TRIGGER_ABORT) {			return MPR_ERR_ABORTED;		} else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {			copyVarCore(prop, &triggerValue, MPR_SHALLOW_COPY);			mprDestroyVar(&triggerValue);			return 0;		}	}	if (value) {		*value = *prop;		/*		 *	Just so that if the user calls mprDestroyVar on value, it will do no		 *	harm.		 */		value->allocatedVar = 0;		value->allocatedData = 0;	}	return 0;}/******************************************************************************//* *	Read a properties value. This returns a copy of the property variable.  *	However, if the property is an object or string, it returns a copy of the *	reference to the underlying data. If copyDepth is set to MPR_DEEP_COPY, *	then the underlying objects and strings data will be copied as well. If  *	copyDepth is set to MPR_SHALLOW_COPY, then only strings will be copied. If *	it is set to MPR_NO_COPY, then no data will be copied. In all cases, the  *	user must call mprDestroyVar to free resources. This routine will run any  *	registered triggers which may modify the value the user receives (without  *	updating the properties real value). * *	WARNING: the args are reversed to most other APIs. This conforms to the *	strcpy(dest, src) standard instead. */int mprCopyProperty(MprVar *dest, MprVar *prop, int copyDepth){	MprVar	triggerValue;	int		rc;	mprAssert(prop);	mprAssert(dest);	if (prop->trigger) {		triggerValue = *prop;		triggerValue.allocatedVar = 0;		triggerValue.allocatedData = 0;		rc = (prop->trigger)(MPR_VAR_READ, prop->parentProperties, prop, 			&triggerValue, copyDepth);		if (rc == MPR_TRIGGER_ABORT) {			return MPR_ERR_ABORTED;		} else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {			copyVarCore(dest, &triggerValue, MPR_SHALLOW_COPY);			mprDestroyVar(&triggerValue);			return 0;		}	}	mprCopyVar(dest, prop, copyDepth);	return 0;}/******************************************************************************//* *	Write a new value into an existing property in an object. */int mprWriteProperty(MprVar *vp, MprVar *value){	MprVar	triggerValue;	int		rc;	mprAssert(vp);	mprAssert(value);	if (vp->readonly) {		return MPR_ERR_READ_ONLY;	}	if (vp->trigger) {		triggerValue = *value;		rc = (vp->trigger)(MPR_VAR_WRITE, vp->parentProperties, vp, 			&triggerValue, 0);		if (rc == MPR_TRIGGER_ABORT) {			return MPR_ERR_ABORTED;		} else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {			copyVarCore(vp, &triggerValue, MPR_SHALLOW_COPY);			mprDestroyVar(&triggerValue);			return 0;		}		/* Fall through */	}	copyVarCore(vp, value, MPR_SHALLOW_COPY);	return 0;}/******************************************************************************//* *	Write a new value into an existing property in an object. */int mprWritePropertyValue(MprVar *vp, MprVar value){	mprAssert(vp);	return mprWriteProperty(vp, &value);}/******************************************************************************//* *	Get the count of properties. */int mprGetPropertyCount(MprVar *vp, int includeFlags){	mprAssert(vp);	if (vp->type != MPR_TYPE_OBJECT) {		return 0;	}	if (includeFlags == MPR_ENUM_DATA) {		return vp->properties->numDataItems;	} else {		return vp->properties->numItems;	}}/******************************************************************************//* *	Get the first property in an object. Used for walking all properties in an *	object. */MprVar *mprGetFirstProperty(MprVar *obj, int includeFlags){	MprVar		*prop;	int			i;	mprAssert(obj);	mprAssert(obj->type == MPR_TYPE_OBJECT);	if (obj->type != MPR_TYPE_OBJECT) {		mprAssert(obj->type == MPR_TYPE_OBJECT);		return 0;	}	for (i = 0; i < (int) obj->properties->hashSize; i++) {		for (prop = obj->properties->buckets[i]; prop; prop = prop->forw) {			if (prop) {				if (mprVarIsFunction(prop->type)) {					if (!(includeFlags & MPR_ENUM_FUNCTIONS)) {						continue;					}				} else {					if (!(includeFlags & MPR_ENUM_DATA)) {						continue;					}				}				return prop;			}			break;		}	}	return 0;}/******************************************************************************//* *	Get the next property in sequence. */MprVar *mprGetNextProperty(MprVar *obj, MprVar *last, int includeFlags){	MprProperties	*properties;	int				i;	mprAssert(obj);	mprAssert(obj->type == MPR_TYPE_OBJECT);	if (obj->type != MPR_TYPE_OBJECT) {		mprAssert(obj->type == MPR_TYPE_OBJECT);		return 0;	}	properties = obj->properties;	if (last->forw) {		return last->forw;	}	for (i = last->bucketIndex + 1; i < (int) properties->hashSize; i++) {		for (last = properties->buckets[i]; last; last = last->forw) {			if (mprVarIsFunction(last->type)) {				if (!(includeFlags & MPR_ENUM_FUNCTIONS)) {					continue;				}			} else {				if (!(includeFlags & MPR_ENUM_DATA)) {					continue;				}			}			return last;		}	}	return 0;}/******************************************************************************//************************** Internal Support Routines *************************//******************************************************************************//* *	Create an hash table to hold and index properties. Properties are just  *	variables which may contain primitive data types, functions or other *	objects. The hash table is the essence of an object. HashSize specifies  *	the size of the hash table to use and should be a prime number. */static MprProperties *createProperties(const char *name, int hashSize){	MprProperties	*pp;	if (hashSize < 7) {		hashSize = 7;	}	if ((pp = (MprProperties*) mprMalloc(sizeof(MprProperties))) == NULL) {		mprAssert(0);		return 0;	}	mprAssert(pp);	memset(pp, 0, sizeof(MprProperties));	pp->numItems = 0;	pp->numDataItems = 0;	pp->hashSize = hashSize;	pp->buckets = (MprVar**) mprMalloc(pp->hashSize * sizeof(MprVar*));	mprAssert(pp->buckets);	memset(pp->buckets, 0, pp->hashSize * sizeof(MprVar*));	pp->refCount = 1;#if VAR_DEBUG	if (objectCount == -1) {		objectCount = 0;		objectList.next = objectList.prev = &objectList;	}	mprStrcpy(pp->name, sizeof(pp->name), name);	pp->next = &objectList;	pp->prev = objectList.prev;	objectList.prev->next = pp;	objectList.prev = pp;	objectCount++;#endif	return pp;}/******************************************************************************//* *	Release an object's properties hash table. If this is the last person  *	using it, free it. Return TRUE if the object is released. */static bool releaseProperties(MprProperties *obj, int force){	MprProperties	*pp;	MprVar			*prop, *forw;	int				i;	mprAssert(obj);	mprAssert(obj->refCount > 0);#if VAR_DEBUG	/*	 *	Debug sanity check	 */	mprAssert(obj->refCount < 20);#endif	if (--obj->refCount > 0 && !force) {		return 0;	}#if VAR_DEBUG	mprAssert(obj->prev);	mprAssert(obj->next);	mprAssert(obj->next->prev);	mprAssert(obj->prev->next);	obj->next->prev = obj->prev;	obj->prev->next = obj->next;	objectCount--;#endif	for (i = 0; i < (int) obj->hashSize; i++) {		for (prop = obj->buckets[i]; prop; prop = forw) {			forw = prop->forw;			if (prop->type == MPR_TYPE_OBJECT) {				if (prop->properties == obj) {					/* Self reference */					continue;				}				pp = prop->properties;				if (pp->visited) {					continue;				}				pp->visited = 1;				if (! freeVar(prop, pp->deleteProtect ? 0 : force)) {					pp->visited = 0;				}			} else {				freeVar(prop, force);			}		}	}	mprFree((void*) obj->buckets);	mprFree((void*) obj);	return 1;}/******************************************************************************//* *	Adjust the reference count */static int adjustRefCount(MprProperties *pp, int adj){	mprAssert(pp);	/*	 *	Debug sanity check	 */	mprAssert(pp->refCount < 20);	return pp->refCount += adj;}/******************************************************************************/#if VAR_DEBUG/* *	Print objects held */void mprPrintObjects(char *msg){	MprProperties	*pp, *np;	MprVar			*prop, *forw;	char			*buf;	int				i;	mprLog(7, "%s: Object Store. %d objects.\n", msg, objectCount);	pp = objectList.next;	while (pp != &objectList) {		mprLog(7, "%s: 0x%x, refCount %d, properties %d\n", 			pp->name, pp, pp->refCount, pp->numItems);		for (i = 0; i < (int) pp->hashSize; i++) {			for (prop = pp->buckets[i]; prop; prop = forw) {				forw = prop->forw;				if (prop->properties == pp) {					/* Self reference */					continue;				}				mprVarToString(&buf, MPR_MAX_STRING, 0, prop);				if (prop->type == MPR_TYPE_OBJECT) {					np = objectList.next;					while (np != &objectList) {						if (prop->properties == np) {							break;						}						np = np->next;					}					if (prop->properties == np) {						mprLog(7, "    %s: OBJECT 0x%x, <%s>\n", 							prop->name, prop->properties, prop->fullName);					} else {						mprLog(7, "    %s: OBJECT NOT FOUND, %s <%s>\n", 							prop->name, buf, prop->fullName);					}				} else {					mprLog(7, "    %s: <%s> = %s\n", prop->name, 						prop->fullName, buf);				}				mprFree(buf);			}		}		pp = pp->next;	}}/******************************************************************************/void mprPrintObjRefCount(MprVar *vp){	mprLog(7, "OBJECT 0x%x, refCount %d\n", vp->properties,		vp->properties->refCount);}#endif/******************************************************************************//* *	Get the bucket chain containing a property. */static MprVar *getObjChain(MprProperties *obj, const char *property){	mprAssert(obj);	return obj->buckets[hash(obj, property)];}/******************************************************************************//* *	Fast hash. The history of this algorithm is part of lost computer science  *	folk lore. */static int hash(MprProperties *pp, const char *property){	uint	sum;	mprAssert(pp);	mprAssert(property);

⌨️ 快捷键说明

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