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 + -
显示快捷键?