/* static function run(timeout: Number = -1, oneEvent: Boolean = false): Boolean */ static EjsObj *app_run(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { MprTicks mark, remaining; int64 dispatcherMark; int rc, oneEvent, timeout; timeout = (argc > 0) ? ejsGetInt(ejs, argv[0]) : MAXINT; oneEvent = (argc > 1) ? ejsGetInt(ejs, argv[1]) : 0; if (ejs->hosted) { return ESV(true); } if (timeout < 0) { timeout = MAXINT; } mark = mprGetTicks(); remaining = timeout; dispatcherMark = mprGetEventMark(ejs->dispatcher); do { rc = mprWaitForEvent(ejs->dispatcher, remaining, dispatcherMark); remaining = mprGetRemainingTicks(mark, timeout); dispatcherMark = mprGetEventMark(ejs->dispatcher); } while (!ejs->exception && !oneEvent && !ejs->exiting && remaining > 0 && !mprIsStopping()); return (rc == 0) ? ESV(true) : ESV(false); }
/* 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; }
/* Set a byte in the file at the offset designated by slotNum. */ static int setFileProperty(Ejs *ejs, EjsFile *fp, int slotNum, EjsObj *value) { MprOff offset; int c; if (!(fp->mode & EJS_FILE_OPEN)) { ejsThrowIOError(ejs, "File is not open"); return 0; } if (!(fp->mode & EJS_FILE_WRITE)) { ejsThrowIOError(ejs, "File is not opened for writing"); return 0; } c = ejsIs(ejs, value, Number) ? ejsGetInt(ejs, value) : ejsGetInt(ejs, ejsToNumber(ejs, value)); offset = mprSeekFile(fp->file, SEEK_CUR, 0); if (slotNum < 0) { // could have an mprGetPosition(file) API slotNum = (int) offset; } #if ME_CC_MMU && FUTURE fp->mapped[slotNum] = c; #else if (offset != slotNum && mprSeekFile(fp->file, SEEK_SET, slotNum) != slotNum) { ejsThrowIOError(ejs, "Cannot seek to file offset"); return 0; } if (mprPutFileChar(fp->file, c) < 0) { ejsThrowIOError(ejs, "Cannot write file"); return 0; } #endif return slotNum; }
EjsString *ejsSerializeWithOptions(Ejs *ejs, EjsAny *vp, EjsObj *options) { Json json; EjsObj *arg; EjsString *result; int i; memset(&json, 0, sizeof(Json)); json.depth = 99; json.quotes = 1; json.indent = sclone(" "); if (options) { json.options = options; if ((arg = ejsGetPropertyByName(ejs, options, EN("baseClasses"))) != 0) { json.baseClasses = (arg == ESV(true)); } if ((arg = ejsGetPropertyByName(ejs, options, EN("depth"))) != 0) { json.depth = ejsGetInt(ejs, arg); } if ((arg = ejsGetPropertyByName(ejs, options, EN("indent"))) != 0) { if (ejsIs(ejs, arg, String)) { json.indent = (char*) ejsToMulti(ejs, arg); // TODO - get another solution to hold } else if (ejsIs(ejs, arg, Number)) { i = ejsGetInt(ejs, arg); if (0 <= i && i < MPR_MAX_STRING) { json.indent = mprAlloc(i + 1); // TODO - get another solution to hold memset(json.indent, ' ', i); json.indent[i] = '\0'; } } } if ((arg = ejsGetPropertyByName(ejs, options, EN("commas"))) != 0) { json.commas = (arg == ESV(true)); } if ((arg = ejsGetPropertyByName(ejs, options, EN("hidden"))) != 0) { json.hidden = (arg == ESV(true)); } if ((arg = ejsGetPropertyByName(ejs, options, EN("namespaces"))) != 0) { json.namespaces = (arg == ESV(true)); } if ((arg = ejsGetPropertyByName(ejs, options, EN("quotes"))) != 0) { json.quotes = (arg != ESV(false)); } if ((arg = ejsGetPropertyByName(ejs, options, EN("pretty"))) != 0) { json.pretty = (arg == ESV(true)); } json.replacer = ejsGetPropertyByName(ejs, options, EN("replacer")); if (!ejsIsFunction(ejs, json.replacer)) { json.replacer = NULL; } } mprRelease(json.indent); mprHold(json.indent); result = serialize(ejs, vp, &json); // TODO - get another solution to hold return result; }
/* * static function serviceEvents(count: Number = -1, timeout: Number = -1): void */ static EjsVar *serviceEvents(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv) { int count, timeout; count = (argc > 1) ? ejsGetInt(argv[0]) : MAXINT; timeout = (argc > 1) ? ejsGetInt(argv[1]) : MAXINT; ejsServiceEvents(ejs, count, timeout, MPR_SERVICE_EVENTS | MPR_SERVICE_ONE_THING); return 0; }
/* The constructor's job is to initialize a bare object instance function Constructor(height: num, width: num */ static EjsObj *constructor(Ejs *ejs, Shape *sp, int argc, EjsObj **argv) { mprAssert(sp); mprAssert(argc == 2); mprLog(1, "Shape()\n"); sp->x = 0; sp->y = 0; sp->height = ejsGetInt(ejs, argv[0]); sp->width = ejsGetInt(ejs, argv[0]); return (EjsObj*) sp; }
/* Wait for a request to complete. Timeout is in msec. Timeout < 0 means use default inactivity and request timeouts. Timeout of zero means no timeout. function wait(state: Number, timeout: Number = -1): Boolean */ static EjsUri *ws_wait(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv) { MprTicks timeout; int state; state = argc >= 1 ? ejsGetInt(ejs, argv[0]) : WS_STATE_CLOSED; timeout = argc >= 2 ? ejsGetInt(ejs, argv[1]) : -1; if (timeout == 0) { timeout = MPR_MAX_TIMEOUT; } if (!waitForReadyState(ws, state, timeout, 0)) { return ESV(false); } return ESV(true); }
/* Read data bytes from a file. If offset is < 0, then append to the write position. function read(buffer: ByteArray, offset: Number = 0, count: Number = -1): Number */ static EjsNumber *readFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv) { EjsByteArray *buffer; MprPath info; ssize offset, count, totalRead; assert(1 <= argc && argc <= 3); buffer = (EjsByteArray*) argv[0]; offset = (argc >= 2) ? ejsGetInt(ejs, argv[1]): 0; count = (argc >= 3) ? ejsGetInt(ejs, argv[2]): -1; if (fp->file == 0) { ejsThrowStateError(ejs, "File not open"); return 0; } if (!(fp->mode & EJS_FILE_READ)) { ejsThrowStateError(ejs, "File not opened for reading"); return 0; } if (offset >= buffer->size) { ejsThrowOutOfBoundsError(ejs, "Bad read offset value"); return 0; } if (offset < 0) { offset = buffer->writePosition; } else if (offset == 0) { ejsSetByteArrayPositions(ejs, buffer, 0, 0); } if (count < 0) { // TODO OPT could this be cached in fp->info if (mprGetPathInfo(fp->path, &info) == 0) { count = (int) info.size; count -= (int) mprGetFilePosition(fp->file); } else { count = ME_MAX_BUFFER; } assert(count >= 0); } totalRead = readData(ejs, fp, buffer, offset, count); if (totalRead < 0) { return 0; } else if (totalRead == 0) { return ESV(zero); } ejsSetByteArrayPositions(ejs, buffer, -1, offset + totalRead); return ejsCreateNumber(ejs, (MprNumber) totalRead); }
/* static function capture(uplevels: Number): Array */ static EjsArray *error_capture(Ejs *ejs, EjsError *error, int argc, EjsObj **argv) { int uplevels; uplevels = (argc > 0) ? ejsGetInt(ejs, argv[0]) : 0; return ejsCaptureStack(ejs, uplevels); }
/* Exit the application static function exit(status: Number, how: String = "default"): void MOB - status is not implemented */ static EjsObj *app_exit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { cchar *how; int status, mode; if (ejs->dontExit) { ejsThrowStateError(ejs, "App.exit has been disabled"); return 0; } status = argc >= 1 ? ejsGetInt(ejs, argv[0]) : 0; how = ejsToMulti(ejs, argc >= 2 ? ejsToString(ejs, argv[1]): ESV(empty)); if (scmp(how, "default") == 0) { mode = MPR_EXIT_DEFAULT; } else if (scmp(how, "immediate") == 0) { mode = MPR_EXIT_IMMEDIATE; } else if (scmp(how, "graceful") == 0) { mode = MPR_EXIT_GRACEFUL; } else { mode = MPR_EXIT_NORMAL; } mprTerminate(mode, status); ejsAttention(ejs); return 0; }
static EjsVar *myEjs(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) { int i; /* Write this data back to the client */ ejsWrite(ejs, "<h1>Hello World</h1><p>Args: "); mprAssert(argv); for (i = 0; i < argc; ) { if (ejsIsNumber(argv[i])) { ejsWrite(ejs, "%d", ejsGetInt(argv[i])); } else { ejsWrite(ejs, ejsGetString(argv[i])); } if (++i < argc) { ejsWrite(ejs, " "); } } ejsWrite(ejs, "</p>"); /* * Functions can return a result */ return (EjsVar*) ejsCreateString(ejs, "sunny day"); return 0; }
/* function waitForMessage(timeout: Number = -1): Boolean */ static EjsBoolean *workerWaitForMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv) { MprTicks mark, remaining; int timeout; timeout = (argc > 0) ? ejsGetInt(ejs, argv[0]): MAXINT; if (timeout < 0) { timeout = MAXINT; } mark = mprGetTicks(); remaining = timeout; worker->gotMessage = 0; do { mprWaitForEvent(ejs->dispatcher, (int) remaining); remaining = mprGetRemainingTicks(mark, timeout); } while (!worker->gotMessage && remaining > 0 && !ejs->exception); if (worker->gotMessage) { worker->gotMessage = 0; return ESV(true); } else { return ESV(true); } }
/* function read(buffer: ByteArray, offset: Number = 0, count: Number = -1): Number Returns a count of bytes read. Non-blocking if a callback is defined. Otherwise, blocks. Offset: -1 then read to the buffer write position, >= 0 then read to that offset count: -1 then read as much as the buffer will hold. If buffer is growable, read all content. If not growable, read the buffer size. If count >= 0, then read that number of bytes. */ static EjsNumber *http_read(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { EjsByteArray *buffer; HttpConn *conn; MprOff contentLength; ssize offset, count; conn = hp->conn; buffer = (EjsByteArray*) argv[0]; offset = (argc >= 2) ? ejsGetInt(ejs, argv[1]) : 0; count = (argc >= 3) ? ejsGetInt(ejs, argv[2]): -1; if (!waitForResponseHeaders(hp)) { return 0; } contentLength = httpGetContentLength(conn); if (conn->state >= HTTP_STATE_PARSED && contentLength == hp->readCount) { /* End of input */ return ESV(null); } if (offset < 0) { offset = buffer->writePosition; } else if (offset < buffer->size) { ejsSetByteArrayPositions(ejs, buffer, offset, offset); } else { ejsThrowOutOfBoundsError(ejs, "Bad read offset value"); return 0; } if (count < 0 && !buffer->resizable) { count = buffer->size - offset; } if ((count = readHttpData(ejs, hp, count)) < 0) { assert(ejs->exception); return 0; } else if (count == 0 && conn->state > HTTP_STATE_CONTENT) { return ESV(null); } hp->readCount += count; if (ejsCopyToByteArray(ejs, buffer, offset, (char*) mprGetBufStart(hp->responseContent), count) != count) { ejsThrowMemoryError(ejs); } ejsSetByteArrayPositions(ejs, buffer, -1, buffer->writePosition + count); mprAdjustBufStart(hp->responseContent, count); mprResetBufIfEmpty(hp->responseContent); return ejsCreateNumber(ejs, (MprNumber) count); }
/* Seek to a new location in the file and set the File marker to a new read/write position. function set position(value: Number): void */ static EjsObj *setFilePosition(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv) { MprOff pos; assert(argc == 1 && ejsIs(ejs, argv[0], Number)); pos = ejsGetInt(ejs, argv[0]); if (fp->file == 0) { ejsThrowStateError(ejs, "File not opened"); return 0; } pos = ejsGetInt(ejs, argv[0]); if (mprSeekFile(fp->file, SEEK_SET, pos) != pos) { ejsThrowIOError(ejs, "Cannot seek to %Ld", pos); } return 0; }
/** * Pause the application * * static function sleep(delay: Number = -1): void */ static EjsVar *sleepProc(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv) { int timeout; timeout = (argc > 0) ? ejsGetInt(argv[0]): MAXINT; ejsServiceEvents(ejs, -1, timeout, MPR_SERVICE_EVENTS | MPR_SERVICE_ONE_THING); return 0; }
static int getNumOption(Ejs *ejs, EjsObj *options, cchar *field) { EjsObj *obj; if ((obj = ejsGetPropertyByName(ejs, options, EN(field))) != 0) { return ejsGetInt(ejs, obj); } return -1; }
/* function truncate(size: Number): Void */ PUBLIC EjsObj *truncateFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv) { int size; size = ejsGetInt(ejs, argv[0]); if (mprTruncateFile(fp->path, size) < 0) { ejsThrowIOError(ejs, "Cant truncate %s", fp->path); } return 0; }
/* * function load(script: Path, timeout: Number = 0): Void */ static EjsVar *workerLoad(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv) { int timeout; mprAssert(argc == 0 || ejsIsPath(argv[0])); worker->scriptFile = mprStrdup(worker, ((EjsPath*) argv[0])->path); timeout = argc == 2 ? ejsGetInt(argv[1]): 0; return startWorker(ejs, worker, timeout); }
/* function flush(dir: Number = Stream.WRITE): Void */ static EjsObj *http_flush(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { int dir; dir = (argc == 1) ? ejsGetInt(ejs, argv[0]) : EJS_STREAM_WRITE; if (dir & EJS_STREAM_WRITE) { httpFlush(hp->conn); } return 0; }
/* * static function join(workers: Object = null, timeout: Number = -1): Boolean */ static EjsVar *workerJoin(Ejs *ejs, EjsWorker *unused, int argc, EjsVar **argv) { EjsVar *workers; int timeout; workers = (argc > 0) ? argv[0] : NULL; timeout = (argc == 2) ? ejsGetInt(argv[1]) : MAXINT; return (join(ejs, workers, timeout) == 0) ? (EjsVar*) ejs->trueValue: (EjsVar*) ejs->falseValue; }
/* * native static function set maximum(limit: Number): Void */ static EjsVar *setMaxMemory(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) { int maxMemory; mprAssert(argc == 1 && ejsIsNumber(argv[0])); maxMemory = ejsGetInt(argv[0]); mprSetAllocLimits(ejs, -1, maxMemory); return 0; }
/* * function eval(script: String, timeout: Boolean = -1): String */ static EjsVar *workerEval(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv) { int timeout; mprAssert(ejsIsString(argv[0])); worker->scriptLiteral = mprStrdup(worker, ejsGetString(argv[0])); timeout = argc == 2 ? ejsGetInt(argv[1]): MAXINT; return startWorker(ejs, worker, timeout); }
/* function load(script: Path, timeout: Number = 0): Void */ static EjsObj *workerLoad(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv) { int timeout; assert(argc == 0 || ejsIs(ejs, argv[0], Path)); worker->scriptFile = sclone(((EjsPath*) argv[0])->value); timeout = argc == 2 ? ejsGetInt(ejs, argv[1]): 0; return startWorker(ejs, worker, timeout); }
/* static function join(workers: Object = null, timeout: Number = -1): Boolean */ static EjsObj *workerJoin(Ejs *ejs, EjsWorker *unused, int argc, EjsObj **argv) { EjsObj *workers; int timeout; workers = (argc > 0) ? argv[0] : NULL; timeout = (argc == 2) ? ejsGetInt(ejs, argv[1]) : MAXINT; return (join(ejs, workers, timeout) == 0) ? ESV(true): ESV(false); }
/* function eval(script: String, timeout: Boolean = -1): Obj */ static EjsObj *workerEval(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv) { int timeout; assert(ejsIs(ejs, argv[0], String)); worker->scriptLiteral = (EjsString*) argv[0]; timeout = argc == 2 ? ejsGetInt(ejs, argv[1]): MAXINT; return startWorker(ejs, worker, timeout); }
/** * Sort the array using the supplied compare function * intrinsic native function sort(compare: Function = null, order: Number = 1): Array */ static EjsVar *sortArray(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv) { int direction; if (ap->length <= 1) { return (EjsVar*) ap; } direction = (argc >= 2) ? ejsGetInt(argv[1]) : 1; quickSort(ejs, ap, direction, 0, ap->length - 1); return (EjsVar*) ap; }
/* Exit the application static function exit(status: Number, how: String = "immediate"): void TODO - status is not implemented */ static EjsObj *app_exit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { MprTicks timeout; cchar *how; int status, mode; if (ejs->dontExit) { ejsThrowStateError(ejs, "App.exit has been disabled"); return 0; } status = argc >= 1 ? ejsGetInt(ejs, argv[0]) : 0; timeout = argc >= 2 ? ejsGetInt(ejs, argv[1]) : 0; how = ejsToMulti(ejs, argc >= 2 ? ejsToString(ejs, argv[1]): ESV(empty)); if (scmp(how, "normal") == 0) { mode = 0; } else if (scmp(how, "abort") == 0) { mode = MPR_EXIT_ABORT; } else if (scmp(how, "safe") == 0) { mode = MPR_EXIT_SAFE; } else if (scmp(how, "restart") == 0) { mode = MPR_EXIT_RESTART; #if DEPRECATED || 1 } else if (scmp(how, "immediate") == 0) { mode = 0; } else if (scmp(how, "graceful") == 0) { mode = 0; if (argc <= 2) { timeout = 30 * 3000; } } else if (scmp(how, "default") == 0) { mode = 0; #endif } else { mode = 0; } mprShutdown(mode, status, timeout); ejsAttention(ejs); return 0; }
/* function redirect(location: String, level: Number = null): Void */ static EjsFile *lf_redirect(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { cchar *logSpec; int level; logSpec = ejsToMulti(ejs, argv[0]); level = (argc >= 2) ? ejsGetInt(ejs, argv[1]) : -1; mprStartLogging(logSpec, 0); if (level >= 0) { mprSetLogLevel(level); } return 0; }
/* * native static function set redline(limit: Number): Void */ static EjsVar *setRedline(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) { int redline; mprAssert(argc == 1 && ejsIsNumber(argv[0])); redline = ejsGetInt(argv[0]); if (redline <= 0) { redline = INT_MAX; } mprSetAllocLimits(ejs, redline, -1); return 0; }
/* Wait for a request to complete. Timeout is in msec. Timeout < 0 means use default inactivity and request timeouts. Timeout of zero means no timeout. function wait(timeout: Number = -1): Boolean */ static EjsBoolean *http_wait(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { MprTicks timeout; timeout = (argc >= 1) ? ejsGetInt(ejs, argv[0]) : -1; if (timeout == 0) { timeout = MPR_MAX_TIMEOUT; } if (!waitForState(hp, HTTP_STATE_FINALIZED, timeout, 0)) { return ESV(false); } return ESV(true); }