📄 ejsvar.c
字号:
} } dest->method.body = mprStrdup(dest->method.args, src->method.body); if (dest->method.body == 0) { mprFree(dest->method.args); dest->method.args = 0; return 0; } dest->callsSuper = src->callsSuper; break; case EJS_TYPE_STRING: dest->length = src->length; if (src->string) { /* Shallow, deep or recursive deep */ dest->length = dupString(MPR_LOC_PASS(ep, loc), &dest->ustring, src->ustring, src->length); if (dest->length < 0) { return 0; } dest->allocatedData = 1; } else { dest->string = src->string; dest->allocatedData = 0; } break; } dest->type = src->type; dest->flags = src->flags; dest->isArray = src->isArray; return dest;}/******************************************************************************//* * Copy all properies in an object. Must preserve property order */EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest, const EjsVar *src, EjsCopyDepth copyDepth){ EjsProperty *srcProp, *destProp, *last, *next; int propertyIndex; srcProp = ejsGetFirstProperty(src, EJS_ENUM_ALL); while (srcProp) { next = ejsGetNextProperty(srcProp, EJS_ENUM_ALL); if (srcProp->visited) { srcProp = next; continue; } /* * This finds the last variable in the hash chain * FUTURE OPT. This is slow. If used double link, we could locate the * tail more easily. */ destProp = hashLookup(dest->objectState, srcProp->name, &propertyIndex, &last); mprAssert(destProp == 0); destProp = allocProperty(ep, dest, srcProp->name, propertyIndex, last); if (destProp == 0) { mprAssert(destProp); return 0; } /* * Recursively copy the object. If DEEP_COPY, then we * will do a shallow copy of the object contents. If * RECURSIVE_DEEP, then we do a deep copy at all levels. */ srcProp->visited = 1; if (copyVar(EJS_LOC_ARGS(ep), ejsGetVarPtr(destProp), ejsGetVarPtr(srcProp), (copyDepth == EJS_DEEP_COPY) ? EJS_SHALLOW_COPY : copyDepth) == 0) { return 0; } srcProp->visited = 0; srcProp = next; } return dest;}/******************************************************************************//********************************** Properties ********************************//******************************************************************************//* * Create a property in an object and return a pointer to it. If the property * already exists then just return a pointer to it (no error). * To test for existance of a property, use GetProperty */static EjsProperty *hashLookup(EjsObj *obj, const char *property, int *propertyIndex, EjsProperty **hashTail){ EjsProperty *prop, *last; int index; mprAssert(obj); mprAssert(property); if (obj == 0 || property == 0 || *property == '\0') { mprAssert(0); return 0; } /* * Find the property in the hash chain if it exists */ index = hash(property); prop = obj->propertyHash[index]; for (last = 0; prop != 0; last = prop, prop = prop->hashNext) { if (prop->name[0] == property[0] && strcmp(prop->name, property) == 0) { break; } } if (propertyIndex) { *propertyIndex = index; } if (hashTail) { *hashTail = last; } return prop;}/******************************************************************************//* * Create a property in an object and return a pointer to it. If the property * already exists then just return a pointer to it (no error). If the property * does not exist, create an undefined variable. To test for existance of a * property, use GetProperty. */EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *op, const char *property){ EjsProperty *prop, *last; int propertyIndex; if (op == 0 || op->type != EJS_TYPE_OBJECT || property == 0 || *property == '\0') { mprAssert(0); return 0; } /* * Find the property in the hash chain if it exists */ prop = hashLookup(op->objectState, property, &propertyIndex, &last); if (prop == 0) { /* * Create a new property */ prop = allocProperty(ep, op, property, propertyIndex, last); if (prop == 0) { mprAssert(prop == 0); return 0; } } return prop;}/******************************************************************************//* * Create a property in an object and return a pointer to it. If the property * already exists then just return a pointer to it (no error). * To test for existance of a property, use GetProperty */EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *op, const char *property){ EjsProperty *prop, *last; int propertyIndex; if (op == 0 || op->type != EJS_TYPE_OBJECT || property == 0 || *property == '\0') { mprAssert(0); return 0; } /* * Find end of chain */ propertyIndex = hash(property); prop = op->objectState->propertyHash[propertyIndex]; for (last = 0; prop != 0; last = prop, prop = prop->hashNext) { ; } return allocProperty(ep, op, property, propertyIndex, last);}/******************************************************************************//* * Find a property in an object and return a pointer to it. * This does NOT traverse base classes. */EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *op, const char *property){ mprAssert(op); mprAssert(op->type == EJS_TYPE_OBJECT); mprAssert(property && *property); /* * This is an internal API. It has very little checking. */ return hashLookup(op->objectState, property, 0, 0);}/******************************************************************************//* * NOTE: There is no ejsSetSimpleProperty as all the ejsSetProperty routines * operate only on the instance and don't follow base classes. ie. there is * no simple version required. However, there is a ejsSetBaseProperty routine * that will follow base classes and is used to set static properties in base * classes *//******************************************************************************//******************************* Property Access ******************************//******************************************************************************//* * The property get routines follow base classes and utilize the propery * method access routines. The property set routines do not follow base * classes. The property ejsSetBase... routines do follow base classes. *//* * Find a property in an object and return a pointer to it. * This follows base classes. */EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *op, const char *property){ EjsVar *vp, *newOp; int maxBaseClasses = 50; do { if (op->type != EJS_TYPE_OBJECT) { mprAssert(op->type == EJS_TYPE_OBJECT); return 0; } mprAssert(op->objectState); vp = ejsGetPropertyMethod(ep, op, property); if (vp != 0) { /* * Found */ break; } newOp = op->objectState->baseClass; if (newOp == 0) { if (op->objectState != ep->objectClass->objectState) { newOp = ep->objectClass; } } op = newOp; /* * A little bit of sanity checking */ if (--maxBaseClasses <= 0) { mprAssert(maxBaseClasses > 0); break; } } while (op); return ejsGetPropertyPtr(vp);}/******************************************************************************//* * Get the property's variable. Optionally create if it does not exist. */EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *vp, const char *property){ return ejsGetVarPtr(ejsGetProperty(ep, vp, property));}/******************************************************************************//* * Get the property's value as a binary string. */const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj, const char *property, int *length){ EjsVar *vp; vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); if (vp == 0 || ejsVarIsUndefined(vp)) { return 0; } if (vp->type == EJS_TYPE_STRING) { if (length) { *length = vp->length; } return vp->ustring; } return 0;}/******************************************************************************//* * Get the property's value as a string. */const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj, const char *property){ EjsVar *vp; vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); if (vp == 0 || ejsVarIsUndefined(vp)) { return 0; } if (vp->type == EJS_TYPE_STRING) { return vp->string; } return 0;}/******************************************************************************//* * Get the property's value as a number. */BLD_FEATURE_NUM_TYPE ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj, const char *property){ EjsVar *vp; vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); if (vp == 0 || ejsVarIsUndefined(vp)) { return 0; } return ejsVarToNumber(vp);}/******************************************************************************//* * Get the property's value as a integer. */int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj, const char *property){ EjsVar *vp; vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); if (vp == 0 || ejsVarIsUndefined(vp)) { return 0; } return ejsVarToInteger(vp);}/******************************************************************************//* * Get the property's value as a boolean. */bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj, const char *property){ EjsVar *vp; vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); if (vp == 0 || ejsVarIsUndefined(vp)) { return 0; } return ejsVarToBoolean(vp);}/******************************************************************************//* * Get the property's value as a pointer. */void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj, const char *property){ EjsVar *vp; vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); if (vp == 0 || ejsVarIsUndefined(vp)) { return 0; } if (vp->type == EJS_TYPE_PTR) { return vp->ptr.userPtr; } return 0;}/******************************************************************************//* * Create a property in the object. This will override any base class * properties. * * MOB -- need to spell out the difference between ejsSetProperty and * ejsCreateProperty. */EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *property){ EjsVar *vp; vp = ejsCreatePropertyMethod(ep, obj, property); return ejsGetPropertyPtr(vp);}/******************************************************************************//* * Set a property's variable value. Create the property if it does not exist. * This routine DOES follow base classes. */EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *op, const char *property, const EjsVar *value){ EjsVar *vp, *newOp; int maxBaseClasses = 50; do { if (op->type != EJS_TYPE_OBJECT) { mprAssert(op->type == EJS_TYPE_OBJECT); return 0; } mprAssert(op->objectState); vp = ejsGetPropertyMethod(ep, op, property); if (vp != 0) { /* * Found */ vp = ejsSetPropertyMethod(ep, op, property, value); break; } newOp = op->objectState->baseClass; if (newOp == 0) { if (op->objectState != ep->objectClass->objectState) { newOp = ep->objectClass; } } op = newOp; /* * A little bit of sanity checking */ if (--maxBaseClasses <= 0) { mprAssert(maxBaseClasses > 0); break; } } while (op); return ejsGetPropertyPtr(vp);}/******************************************************************************//* * Set a property's variable value. Create the property if it does not exist. * This does NOT follow base classes. Okay when updating instance properties, * but not for class (static) properties. This does a shallow copy which * will copy references. */EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *property, const EjsVar *value){ EjsVar *vp; vp = ejsSetPropertyMethod(ep, obj, property, value); return ejsGetPropertyPtr(vp);}/******************************************************************************//* * Set a property's variable value by assigning the given value. The caller * must NOT free value as it is assigned directly into the property's value. */EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj, const char *property, EjsVar *value){ EjsVar *vp; vp = ejsSetPropertyMethod(ep, obj, property, value); ejsFree(ep, value, EJS_SLAB_VAR); return ejsGetPropertyPtr(vp);}/******************************************************************************/EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *vp, const char *prop, EjsCMethod fn, void *userData, int flags){ EjsVar v; ejsInitVar(&v, EJS_TYPE_CMETHOD); v.cMethod.fn = fn; v.cMethod.userData = userData; v.flags = flags; return ejsSetProperty(ep, vp, prop, &v);}/******************************************************************************/EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *vp, const char *prop, int value){ EjsVar v; ejsInitVar(&v, EJS_TYPE_BOOL); v.boolean = value; return ejsSetProperty(ep, vp, prop, &v);}/******************************************************************************/#if BLD_FEATURE_FLOATING_POINTEjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *vp, const char *prop, double value){ EjsVar v; ejsInitVar(&v, EJS_TYPE_FLOAT); v.floating = value; return ejsSetProperty(ep, vp, prop, &v);}#endif/******************************************************************************/EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *vp, const char *prop, int value){ EjsVar v; ejsInitVar(&v, EJS_TYPE_INT); v.integer = value; return ejsSetProperty(ep, vp, prop, &v);}/******************************************************************************/#if BLD_FEATURE_INT64EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *vp, const char *prop, int64 value){ EjsVar v; ejsInitVar(&v, EJS_TYPE_INT64); v.integer64 = value; return ejsSetProperty(ep, vp, prop, &v);}#endif/******************************************************************************/EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *vp, const char *prop){ EjsVar v; ejsInitVar(&v, EJS_TYPE_NULL); return ejsSetProperty(ep, vp, prop, &v);}/******************************************************************************/EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *vp, const char *prop, const char *body, MprArray *args, int flags){ return ejsSetPropertyAndFree(ep, vp, prop, ejsCreateMethodVar(ep, body, args, flags));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -