/* * Report reference errors */ static void reportError(Ejs *ejs, EjsVar *vp) { if (ejsIsNull(vp)) { ejsThrowReferenceError(ejs, "Object reference is null"); } else if (ejsIsUndefined(vp)) { ejsThrowReferenceError(ejs, "Reference is undefined"); } else { ejsThrowReferenceError(ejs, "Undefined setProperty helper"); } }
/* Function to iterate and return the next element value. NOTE: this is not a method of Array. Rather, it is a callback function for Iterator */ static EjsObj *nextValue(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv) { EjsFile *fp; fp = (EjsFile*) ip->target; if (!ejsIs(ejs, fp, File)) { ejsThrowReferenceError(ejs, "Wrong type"); return 0; } if (ip->index < fp->info.size) { #if !ME_CC_MMU || 1 if (mprSeekFile(fp->file, SEEK_CUR, 0) != ip->index) { if (mprSeekFile(fp->file, SEEK_SET, ip->index) != ip->index) { ejsThrowIOError(ejs, "Cannot seek to %d", ip->index); return 0; } } ip->index++; return (EjsObj*) ejsCreateNumber(ejs, mprGetFileChar(fp->file)); #else return (EjsObj*) ejsCreateNumber(ejs, fp->mapped[ip->index++]); #endif } #if ME_CC_MMU && FUTURE unmapFile(fp); fp->mapped = 0; #endif ejsThrowStopIteration(ejs); return 0; }
/* Update the value of the property at slotNum with the given value @param ejs VM handle. @param lhs Left hand side object. @param slotNum Slot number of the property to update. The VM maps the property names to slots. @param value Value to write to the property. */ static int setProperty(Ejs *ejs, Shape *sp, int slotNum, EjsObj *value) { mprAssert(sp); switch (slotNum) { case ES_nclass_Shape_x: sp->x = ejsGetInt(ejs, value); break; case ES_nclass_Shape_y: sp->y = ejsGetInt(ejs, value); break; case ES_nclass_Shape_height: sp->height = ejsGetInt(ejs, value); break; case ES_nclass_Shape_width: sp->width = ejsGetInt(ejs, value); break; default: ejsThrowReferenceError(ejs, "Bad slot reference"); return EJS_ERR; } return slotNum; }
/* Function to iterate and return the next element value. NOTE: this is not a method of Array. Rather, it is a callback function for Iterator */ static EjsObj *nextArrayValue(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv) { EjsArray *ap; EjsObj *vp, **data; ap = (EjsArray*) ip->target; if (!ejsIs(ejs, ap, Array)) { ejsThrowReferenceError(ejs, "Wrong type"); return 0; } data = ap->data; if (ap->length < ip->length) { ip->length = ap->length; } for (; ip->index < ip->length; ip->index++) { vp = data[ip->index]; assert(vp); if (ejsIs(ejs, vp, Void)) { continue; } ip->index++; return vp; } ejsThrowStopIteration(ejs); return 0; }
/* Set a property and return the slot number. Incoming slot may be -1 to allocate a new slot. */ int ejsSetProperty(Ejs *ejs, EjsVar *vp, int slotNum, EjsVar *value) { if (vp == 0) { ejsThrowReferenceError(ejs, "Object is null"); return EJS_ERR; } mprAssert(vp->type->helpers->setProperty); return (vp->type->helpers->setProperty)(ejs, vp, slotNum, value); }
/* function secure(keyFile: Path, certFile: Path!, protocols: Array? = null, ciphers: Array? = null): Void */ static EjsObj *hs_secure(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv) { #if ME_COM_SSL EjsArray *protocols; cchar *token; int mask, protoMask, i; if (sp->ssl == 0 && ((sp->ssl = mprCreateSsl(1)) == 0)) { return 0; } if (!ejsIs(ejs, argv[0], Null)) { mprSetSslKeyFile(sp->ssl, ejsToMulti(ejs, argv[0])); } if (!ejsIs(ejs, argv[1], Null)) { mprSetSslCertFile(sp->ssl, ejsToMulti(ejs, argv[1])); } if (argc >= 3 && ejsIs(ejs, argv[2], Array)) { protocols = (EjsArray*) argv[2]; protoMask = 0; for (i = 0; i < protocols->length; i++) { token = ejsToMulti(ejs, ejsGetProperty(ejs, protocols, i)); mask = -1; if (*token == '-') { token++; mask = 0; } else if (*token == '+') { token++; } if (scaselesscmp(token, "SSLv2") == 0) { protoMask &= ~(MPR_PROTO_SSLV2 & ~mask); protoMask |= (MPR_PROTO_SSLV2 & mask); } else if (scaselesscmp(token, "SSLv3") == 0) { protoMask &= ~(MPR_PROTO_SSLV3 & ~mask); protoMask |= (MPR_PROTO_SSLV3 & mask); } else if (scaselesscmp(token, "TLSv1") == 0) { protoMask &= ~(MPR_PROTO_TLSV1 & ~mask); protoMask |= (MPR_PROTO_TLSV1 & mask); } else if (scaselesscmp(token, "ALL") == 0) { protoMask &= ~(MPR_PROTO_ALL & ~mask); protoMask |= (MPR_PROTO_ALL & mask); } } mprSetSslProtocols(sp->ssl, protoMask); } if (argc >= 4 && ejsIs(ejs, argv[3], Array)) { mprSetSslCiphers(sp->ssl, ejsToMulti(ejs, argv[3])); } #else ejsThrowReferenceError(ejs, "SSL support was not included in the build"); #endif return 0; }
/* * Set a variable in the web server. This is used to implement virtual properties */ int ejsSetWebVar(Ejs *ejs, int collection, int field, EjsVar *value) { EjsWeb *web; mprAssert(ejs); web = ejsGetHandle(ejs); if (web->control->setVar == 0) { ejsThrowReferenceError(ejs, "Object is read-only"); return EJS_ERR; } mprAssert(web->control->setVar); return web->control->setVar(web->handle, collection, field, value); }
/* * Set a property and return the slot number. Incoming slot may be -1 to allocate a new slot. */ int ejsSetProperty(Ejs *ejs, EjsVar *vp, int slotNum, EjsVar *value) { if (vp == 0) { ejsThrowReferenceError(ejs, "Object is null"); return EJS_ERR; } if (vp->type->helpers->setProperty) { ejsSetReference(ejs, vp, value); return (vp->type->helpers->setProperty)(ejs, vp, slotNum, value); } ejsThrowInternalError(ejs, "Helper not defined for type \"%s\"", vp->type->qname.name); return EJS_ERR; }
/* Function to iterate and return the next element index. NOTE: this is not a method of Array. Rather, it is a callback function for Iterator */ static EjsNumber *nextKey(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv) { EjsFile *fp; fp = (EjsFile*) ip->target; if (!ejsIs(ejs, fp, File)) { ejsThrowReferenceError(ejs, "Wrong type"); return 0; } if (ip->index < fp->info.size) { return ejsCreateNumber(ejs, ip->index++); } ejsThrowStopIteration(ejs); return 0; }
/* Function to iterate and return the next element name. NOTE: this is not a method of Xml. Rather, it is a callback function for Iterator */ static EjsObj *nextXmlKey(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv) { EjsXML *xml; xml = (EjsXML*) ip->target; if (!ejsIsXML(ejs, xml)) { ejsThrowReferenceError(ejs, "Wrong type"); return 0; } if (ip->index < mprGetListLength(xml->elements)) { return (EjsObj*) ejsCreateNumber(ejs, ip->index++); } ejsThrowStopIteration(ejs); return 0; }
/* Get a property name @param ejs VM handle. @param sp is set to the object instance. @param slotNum Slot number of the property to retrieve. The VM maps the property names to slots. @return The qualified property name. */ static EjsName getPropertyName(Ejs *ejs, Shape *sp, int slotNum) { /* To be thread-safe, we must have a different qname structure for each property name. */ switch (slotNum) { case ES_nclass_Shape_x: { static EjsName qname; qname.name = ejsCreateStringFromAsc(ejs, "y"); qname.space = 0; return qname; } case ES_nclass_Shape_y: { static EjsName qname; qname.space = 0; return qname; } case ES_nclass_Shape_height: { static EjsName qname; qname.name = ejsCreateStringFromAsc(ejs, "height"); qname.space = 0; return qname; } case ES_nclass_Shape_width: { static EjsName qname; qname.name = ejsCreateStringFromAsc(ejs, "width"); qname.space = 0; return qname; } default: { static EjsName qname; qname.name = 0; qname.space = 0; ejsThrowReferenceError(ejs, "Bad slot reference"); return qname; } } }
/** Delete a property in an object variable. The stack is unchanged. @return Returns a status code. */ int ejsDeletePropertyByName(Ejs *ejs, EjsVar *vp, EjsName *qname) { EjsLookup lookup; int slotNum; mprAssert(qname); mprAssert(qname->name); mprAssert(qname->space); if (vp->type->helpers->deletePropertyByName) { return (vp->type->helpers->deletePropertyByName)(ejs, vp, qname); } else { slotNum = ejsLookupVar(ejs, vp, qname, &lookup); if (slotNum < 0) { ejsThrowReferenceError(ejs, "Property \"%s\" does not exist", qname->name); return 0; } return ejsDeleteProperty(ejs, vp, slotNum); } }
/* Function to iterate and return the next element value. NOTE: this is not a method of Xml. Rather, it is a callback function for Iterator */ static EjsObj *nextXmlValue(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv) { EjsXML *xml, *vp; xml = (EjsXML*) ip->target; if (!ejsIsXML(ejs, xml)) { ejsThrowReferenceError(ejs, "Wrong type"); return 0; } for (; ip->index < mprGetListLength(xml->elements); ip->index++) { vp = (EjsXML*) mprGetItem(xml->elements, ip->index); if (vp == 0) { continue; } ip->index++; return (EjsObj*) vp; } ejsThrowStopIteration(ejs); return 0; }
/* Get a property from the object @param ejs VM handle. @param sp is set to the object instance. @param slotNum Slot number of the property to retrieve. The VM maps the property names to slots. @return the property value */ static EjsObj *getProperty(Ejs *ejs, Shape *sp, int slotNum) { mprAssert(sp); switch (slotNum) { case ES_nclass_Shape_x: return (EjsObj*) ejsCreateNumber(ejs, sp->x); case ES_nclass_Shape_y: return (EjsObj*) ejsCreateNumber(ejs, sp->x); case ES_nclass_Shape_height: return (EjsObj*) ejsCreateNumber(ejs, sp->height); case ES_nclass_Shape_width: return (EjsObj*) ejsCreateNumber(ejs, sp->width); default: ejsThrowReferenceError(ejs, "Bad slot reference"); } return 0; }
/* Lookup a property by name. This is optionally implemented by native types and could be further optimized by hashing these properties. Note: the compiler binds most references to typed properties, so this routine should not be called often. @param ejs VM handle. @param sp is set to the object instance. @param name Property name to look for. */ static int lookupProperty(Ejs *ejs, Shape *sp, EjsName *qname) { MprChar *name; name = qname->name->value; if (mcmp(name, "x") == 0) { return ES_nclass_Shape_x; } else if (mcmp(name, "y") == 0) { return ES_nclass_Shape_y; } else if (mcmp(name, "height") == 0) { return ES_nclass_Shape_height; } else if (mcmp(name, "width") == 0) { return ES_nclass_Shape_width; } else { ejsThrowReferenceError(ejs, "Can't find property %@", qname->name); return EJS_ERR; } }
/* * Function to iterate and return the next element name. * NOTE: this is not a method of Array. Rather, it is a callback function for Iterator */ static EjsVar *nextArrayKey(Ejs *ejs, EjsIterator *ip, int argc, EjsVar **argv) { EjsArray *ap; EjsVar *vp, **data; ap = (EjsArray*) ip->target; if (!ejsIsArray(ap)) { ejsThrowReferenceError(ejs, "Wrong type"); return 0; } data = ap->data; for (; ip->index < ap->length; ip->index++) { vp = data[ip->index]; if (vp == 0) { continue; } return (EjsVar*) ejsCreateNumber(ejs, ip->index++); } ejsThrowStopIteration(ejs); return 0; }
static EjsObj *getNullProperty(Ejs *ejs, EjsNull *unused, int slotNum) { ejsThrowReferenceError(ejs, "Object reference is null"); return 0; }
/* Update a property's name (hash name) @param ejs VM handle. @param sp is set to the object instance. @param sloNum Property slot number to set. @param name Property name to set. */ static EjsObj *setPropertyName(Ejs *ejs, Shape *sp, int slotNum, EjsName *name) { ejsThrowReferenceError(ejs, "Can't define property names for this type"); return 0; }
int defineProperty(Ejs *ejs, EjsObj *vp, int slotNum, EjsName *name, EjsType *propType, int attributes, EjsObj *value) { ejsThrowReferenceError(ejs, "Can't define properties in this sample"); return EJS_ERR; }