Example #1
0
PUBLIC EjsArray *ejsCloneArray(Ejs *ejs, EjsArray *ap, bool deep)
{
    EjsArray    *newArray;
    EjsObj      **dest, **src;
    int         i;

    if ((newArray = ejsClonePot(ejs, ap, deep)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    if (ap->length > 0) {
        if (growArray(ejs, newArray, ap->length) < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
        src = ap->data;
        dest = newArray->data;
        if (deep) {
            for (i = 0; i < ap->length; i++) {
                dest[i] = ejsClone(ejs, src[i], deep);
            }
        } else {
            memcpy(dest, src, ap->length * sizeof(EjsObj*));
        }
    }
    return newArray;
}
Example #2
0
/*
 *  Convert the array to a single string each member of the array has toString called on it and the resulting strings 
 *  are concatenated.
 *
 *  override function toString(): String
 */
static EjsVar *arrayToString(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsString       *result;
    EjsVar          *vp;
    int             i, rc;

    result = ejsCreateString(ejs, "");
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    for (i = 0; i < ap->length; i++) {
        vp = ap->data[i];
        rc = 0;
        if (i > 0) {
            rc = ejsStrcat(ejs, result, (EjsVar*) ejsCreateString(ejs, ","));
        }
        if (vp != 0 && vp != ejs->undefinedValue && vp != ejs->nullValue) {
            rc = ejsStrcat(ejs, result, vp);
        }
        if (rc < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
    }
    return (EjsVar*) result;
}
Example #3
0
static EjsArray *cloneArray(Ejs *ejs, EjsArray *ap, bool deep)
{
    EjsArray    *newArray;
    EjsVar      **dest, **src;
    int         i;

    newArray = (EjsArray*) ejsCopyObject(ejs, (EjsObject*) ap, deep);
    if (newArray == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    if (ap->length > 0) {
        if (growArray(ejs, newArray, ap->length) < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
        src = ap->data;
        dest = newArray->data;

        if (deep) {
            for (i = 0; i < ap->length; i++) {
                dest[i] = ejsCloneVar(ejs, src[i], 1);
            }

        } else {
            memcpy(dest, src, ap->length * sizeof(EjsVar*));
        }
    }
    return newArray;
}
Example #4
0
/*
    Convert the array to a single string each member of the array has toString called on it and the resulting strings 
    are concatenated.

    override function toString(): String
 */
static EjsString *arrayToString(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsString       *result, *comma;
    EjsObj              *vp;
    int             i, rc;

    result = ESV(empty);
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    comma = ejsCreateStringFromAsc(ejs, ",");
    for (i = 0; i < ap->length; i++) {
        vp = ap->data[i];
        rc = 0;
        if (i > 0) {
            result = ejsJoinString(ejs, result, comma);
        }
        if (ejsIsDefined(ejs, vp)) {
            result = ejsJoinString(ejs, result, ejsToString(ejs, vp));
        }
        if (rc < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
    }
    return result;
}
Example #5
0
static EjsVar *arrayConstructor(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsArray    *args;
    EjsVar      *arg0, **src, **dest;
    int         size, i;

    mprAssert(argc == 1 && ejsIsArray(argv[0]));

    args = (EjsArray*) argv[0];
    
    if (args->length == 0) {
        return 0;
    }

    size = 0;
    arg0 = getArrayProperty(ejs, args, 0);

    if (args->length == 1 && ejsIsNumber(arg0)) {
        /*
         *  x = new Array(size);
         */
        size = ejsGetInt(arg0);
        if (size > 0 && growArray(ejs, ap, size) < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }

    } else {

        /*
         *  x = new Array(element0, element1, ..., elementN):
         */
        size = args->length;
        if (size > 0 && growArray(ejs, ap, size) < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }

        src = args->data;
        dest = ap->data;
        for (i = 0; i < size; i++) {
            dest[i] = src[i];
        }
    }
    ap->length = size;

    return (EjsVar*) ap;
}
Example #6
0
/**
 *  Iterate over all elements in the object and find all elements for which the matching function is true.
 *  The match is called with the following signature:
 *
 *      function match(arrayElement: Object, elementIndex: Number, arr: Array): Boolean
 *
 *  @param match Matching function
 *  @return Returns a new array containing all matching elements.
 */
static EjsVar *findAll(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsVar      *funArgs[3];
    EjsBoolean  *result;
    EjsArray    *elements;
    int         i;

    mprAssert(argc == 1 && ejsIsFunction(argv[0]));

    elements = ejsCreateArray(ejs, 0);
    if (elements == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    for (i = 0; i < ap->length; i++) {
        funArgs[0] = ap->obj.properties.slots[i];               /* Array element */
        funArgs[1] = (EjsVar*) ejsCreateNumber(ejs, i);             /* element index */
        funArgs[2] = (EjsVar*) ap;                                  /* Array */
        result = (EjsBoolean*) ejsRunFunction(ejs, (EjsFunction*) argv[0], 0, 3, funArgs);
        if (result == 0 || !ejsIsBoolean(result) || !result->value) {
            setArrayProperty(ejs, elements, elements->length, ap->obj.properties.slots[i]);
        }
    }
    return (EjsVar*) elements;
}
Example #7
0
/*
 *  Post a message to this worker. Note: the worker is the destination worker which may be the parent.
 *
 *  function postMessage(data: Object, ports: Array = null): Void
 */
static EjsVar *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    EjsVar          *data;
    EjsWorker       *target;
    MprDispatcher   *dispatcher;
    Message         *msg;

    if (worker->state >= EJS_WORKER_CLOSED) {
        ejsThrowStateError(ejs, "Worker has completed");
        return 0;
    }

    /*
     *  Create the event with serialized data in the originating interpreter. It owns the data.
     */
    if ((data = ejsSerialize(ejs, argv[0], -1, 0, 0)) == 0) {
        ejsThrowArgError(ejs, "Can't serialize message data");
        return 0;
    }
    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    target = worker->pair;
    msg->data = mprStrdup(target->ejs, ejsGetString(data));
    msg->worker = target;
    msg->callback = "onmessage";
    msg->callbackSlot = ES_ejs_sys_Worker_onmessage;

    dispatcher = target->ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
    return 0;
}
Example #8
0
EjsVar *ejsCreateInstance(Ejs *ejs, EjsType *type, int argc, EjsVar **argv)
{
    EjsFunction     *fun;
    EjsVar          *vp;
    int             slotNum;

    mprAssert(type);

    vp = ejsCreateVar(ejs, type, 0);
    if (vp == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    if (type->hasConstructor) {
        slotNum = type->block.numInherited;
        fun = (EjsFunction*) ejsGetProperty(ejs, (EjsVar*) type, slotNum);
        if (fun == 0) {
            return 0;
        }
        if (!ejsIsFunction(fun)) {
            return 0;
        }

        vp->permanent = 1;
        ejsRunFunction(ejs, fun, vp, argc, argv);
        vp->permanent = 0;
    }

    return vp;
}
Example #9
0
/*
    Post a message to this worker. Note: the worker is the destination worker which may be the parent.

    function postMessage(data: Object, ports: Array = null): Void
 */
static EjsObj *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv)
{
    EjsString       *data;
    EjsWorker       *target;
    MprDispatcher   *dispatcher;
    Message         *msg;

    if (worker->state >= EJS_WORKER_CLOSED) {
        ejsThrowStateError(ejs, "Worker has completed");
        return 0;
    }
    /*
        Create the event with serialized data in the originating interpreter. It owns the data.
     */
    ejsBlockGC(ejs);
    if ((data = ejsToJSON(ejs, argv[0], NULL)) == 0) {
        ejsThrowArgError(ejs, "Cannot serialize message data");
        return 0;
    }
    if ((msg = createMessage()) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    target = worker->pair;
    msg->data = ejsToMulti(ejs, data);
    msg->worker = target;
    msg->callback = "onmessage";
    msg->callbackSlot = ES_Worker_onmessage;

    dispatcher = target->ejs->dispatcher;
    mprCreateEvent(dispatcher, "postMessage", 0, doMessage, msg, 0);
    return 0;
}
Example #10
0
static EjsObj *loadXml(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    MprFile     *file;
    MprXml      *xp;
    cchar       *filename;

    assert(argc == 1 && ejsIs(ejs, argv[0], String));

    filename = ejsToMulti(ejs, argv[0]);
    file = mprOpenFile(filename, O_RDONLY, 0664);
    if (file == 0) {
        ejsThrowIOError(ejs, "Cannot open: %s", filename);
        return 0;
    }
    //  TODO - convert to open/close
    xp = ejsCreateXmlParser(ejs, xml, filename);
    if (xp == 0) {
        ejsThrowMemoryError(ejs);
        mprCloseFile(file);
        return 0;
    }
    mprXmlSetInputStream(xp, readFileData, (void*) file);

    if (mprXmlParse(xp) < 0 && !ejsHasException(ejs)) {
        ejsThrowIOError(ejs, "Cannot parse XML file: %s\nDetails %s",  filename, mprXmlGetErrorMsg(xp));
    }
    mprCloseFile(file);
    return 0;
}
Example #11
0
/*
 *  Concatenate the supplied elements with the array to create a new array. If any arguments specify an array,
 *  their elements are catenated. This is a one level deep copy.
 *
 *  function concat(...args): Array
 */
static EjsVar *concatArray(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsArray    *args, *newArray, *vpa;
    EjsVar      *vp, **src, **dest;
    int         i, k, next;

    mprAssert(argc == 1 && ejsIsArray(argv[0]));

    args = ((EjsArray*) argv[0]);

    newArray = ejsCreateArray(ejs, ap->length);
    src = ap->data;
    dest = newArray->data;

    /*
     *  Copy the original array
     */
    for (next = 0; next < ap->length; next++) {
        dest[next] = src[next];
    }

    /*
     *  Copy the args. If any element is itself an array, then flatten it and copy its elements.
     */
    for (i = 0; i < args->length; i++) {
        vp = args->data[i];
        if (ejsIsArray(vp)) {
            vpa = (EjsArray*) vp;
            if (growArray(ejs, newArray, next + vpa->length) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
            dest = newArray->data;
            dest = newArray->data;
            for (k = 0; k < vpa->length; k++) {
                dest[next++] = vpa->data[k];
            }
        } else {
            if (growArray(ejs, newArray, next + 1) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
            dest[next++] = vp;
        }
    }
    return (EjsVar*) newArray;
}
Example #12
0
/*  
    function WebSocket(uri: Uri, protocols = null, options)

    options = {
        certificate: Path,
        verify: Boolean,
    }
 */
static EjsWebSocket *wsConstructor(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv)
{
    EjsAny      *certificate;
    bool        verify;

    assert(ejsIsPot(ejs, ws));

    ejsLoadHttpService(ejs);
    ws->ejs = ejs;
    verify = 0;

    ws->uri = httpUriToString(((EjsUri*) argv[0])->uri, 0);
    if (argc >= 2) {
        if (ejsIs(ejs, argv[1], Array)) {
            ws->protocols = sclone((ejsToString(ejs, argv[1]))->value);
        } else if (ejsIs(ejs, argv[1], String)) {
            ws->protocols = sclone(((EjsString*) argv[1])->value);
        } else {
            ws->protocols = sclone("chat");
        }
    } else {
        ws->protocols = sclone("chat");
    }
    if (*ws->protocols == '\0') {
        ejsThrowArgError(ejs, "Bad protocol");
        return 0;
    }
    if (argc >= 3) {
        ws->frames = ejsGetPropertyByName(ejs, argv[2], EN("frames")) == ESV(true);
        verify = ejsGetPropertyByName(ejs, argv[2], EN("verify")) == ESV(true);
        if ((certificate = ejsGetPropertyByName(ejs, argv[2], EN("certificate"))) != 0) {
            ws->certFile = ejsToMulti(ejs, argv[0]);
        }
    }
    if ((ws->conn = httpCreateConn(MPR->httpService, NULL, ejs->dispatcher)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    httpSetAsync(ws->conn, 1);
    httpPrepClientConn(ws->conn, 0);
    httpSetConnNotifier(ws->conn, webSocketNotify);
    httpSetWebSocketProtocols(ws->conn, ws->protocols);
    httpSetConnContext(ws->conn, ws);
    if (sstarts(ws->uri, "wss")) {
        ws->ssl = mprCreateSsl(0);
        mprVerifySslIssuer(ws->ssl, verify);
        mprVerifySslPeer(ws->ssl, verify);
#if FUTURE
        if (!hp->caFile) {
            //MOB - Some define for this.
            hp->caFile = mprJoinPath(mprGetAppDir(), "http-ca.crt");
        }
        mprSetSslCaFile(hp->ssl, hp->caFile);
        mprSetSslCaFile(hp->ssl, mprJoinPath(mprGetAppDir(), "http-ca.crt"));
#endif
    }
    startWebSocketRequest(ejs, ws);
    return ws;
}
Example #13
0
/*
 *  DB Constructor and also used for constructor for sub classes.
 *
 *  function DB(connectionString: String)
 */
static EjsVar *dbConstructor(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    sqlite3     *sdb;
    EjsDb       **dbp;
    char        *path;

    path = ejsGetString(argv[0]);    
    
    /*
     *  Create a memory context for use by sqlite. This is a virtual paged memory region.
     *  TODO - this is not ideal for long running applications.
     */
    db->arena = mprAllocArena(ejs, "sqlite", EJS_MAX_DB_MEM, 0, 0);
    if (db->arena == 0) {
        return 0;
    }
    
    /*
     *  Create a destructor object so we can cleanup and close the database. Must create after the arena so it will be
     *  invoked before the arena is freed. 
     */
    if ((dbp = mprAllocObject(ejs, 1, (MprDestructor) dbDestructor)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    *dbp = db;
    
    db->tls = mprCreateThreadLocal(db->arena);
    if (db->tls == 0) {
        return 0;
    }
    ejsSetDbMemoryContext(db->tls, db->arena);

    sdb = 0;
    if (sqlite3_open(path, &sdb /* TODO remove , SQLITE_OPEN_READWRITE, 0 */) != SQLITE_OK) {
        ejsThrowIOError(ejs, "Can't open database %s", path);
        return 0;
    }
    db->sdb = sdb;

    sqlite3_busy_timeout(sdb, 15000);

    /*
     *  Query or change the count-changes flag. Normally, when the count-changes flag is not set, INSERT, UPDATE and
     *  DELETE statements return no data. When count-changes is set, each of these commands returns a single row of
     *  data consisting of one integer value - the number of rows inserted, modified or deleted by the command. The
     *  returned change count does not include any insertions, modifications or deletions performed by triggers.
     */
//  sqlite3_exec(sdb, "PRAGMA count_changes = OFF", NULL, NULL, NULL);

    ejsSetProperty(ejs, (EjsVar*) db, ES_ejs_db_Database__connection, (EjsVar*) ejsCreateString(ejs, path));
    ejsSetProperty(ejs, (EjsVar*) db, ES_ejs_db_Database__name, (EjsVar*) ejsCreateString(ejs, mprGetBaseName(path)));
    
    return 0;
}
Example #14
0
/*
 *  Worker thread main procedure
 */
static void workerMain(EjsWorker *worker, MprWorker *mprWorker)
{
    Ejs             *ejs, *inside;
    EjsWorker       *insideWorker;
    MprDispatcher   *dispatcher;
    Message         *msg;

    mprAssert(!worker->inside);
    insideWorker = worker->pair;
    mprAssert(insideWorker->state == EJS_WORKER_BEGIN);

    ejs = worker->ejs;
    inside = insideWorker->ejs;
    insideWorker->state = EJS_WORKER_STARTED;
    
    /*
     *  Run the script or file
     */
    if (worker->scriptFile) {
        loadFile(insideWorker, worker->scriptFile);

    } else if (worker->scriptLiteral) {
        if (ejs->service->loadScriptLiteral == 0) {
            ejsThrowIOError(ejs, "worker: Compiling is not enabled");
            return;
        }
        (ejs->service->loadScriptLiteral)(inside, worker->scriptLiteral);
    }

    /*
     *  Check for exceptions
     */
    if (inside->exception) {
        handleError(ejs, worker, inside->exception);
    }
    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return;
    }

    /*
     *  Post "onclose" finalization message
     */
    msg->worker = worker;
    msg->callback = "onclose";
    msg->callbackSlot = ES_ejs_sys_Worker_onclose;

    insideWorker->state = EJS_WORKER_CLOSED;
    worker->state = EJS_WORKER_CLOSED;
    insideWorker->obj.var.permanent = 0;
    dispatcher = worker->ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
}
Example #15
0
/*
    Worker thread main procedure. Worker is the inside worker.
 */
static int workerMain(EjsWorker *insideWorker, MprEvent *event)
{
    Ejs             *outside, *inside;
    EjsWorker       *outsideWorker;
    MprDispatcher   *dispatcher;
    Message         *msg;

    assert(insideWorker->inside);
    outsideWorker = insideWorker->pair;
    assert(!outsideWorker->inside);
    assert(insideWorker->state == EJS_WORKER_BEGIN);

    outside = outsideWorker->ejs;
    inside = insideWorker->ejs;
    insideWorker->state = EJS_WORKER_STARTED;
    
    /*
        Run the script or file
     */
    if (outsideWorker->scriptFile) {
        loadFile(insideWorker, outsideWorker->scriptFile);

    } else if (outsideWorker->scriptLiteral) {
        if (outside->service->loadScriptLiteral == 0) {
            ejsThrowIOError(outside, "worker: Compiling is not enabled");
            return 0;
        }
        (outside->service->loadScriptLiteral)(inside, outsideWorker->scriptLiteral, NULL);
    }
    /*
        Check for exceptions
     */
    if (inside->exception) {
        handleError(outside, outsideWorker, inside->exception, 0);
        inside->exception = 0;
    }
    ejsBlockGC(inside);
    if ((msg = createMessage()) == 0) {
        ejsThrowMemoryError(outside);
        return 0;
    }
    /*
        Post "onclose" finalization message
     */
    msg->worker = outsideWorker;
    msg->callback = "onclose";
    msg->callbackSlot = ES_Worker_onclose;

    insideWorker->state = EJS_WORKER_CLOSED;
    outsideWorker->state = EJS_WORKER_CLOSED;
    dispatcher = outside->dispatcher;
    mprCreateEvent(dispatcher, "doMessage", 0, (MprEventProc) doMessage, msg, 0);
    return 0;
}
Example #16
0
static int checkSlot(Ejs *ejs, EjsArray *ap, int slotNum)
{
    if (slotNum < 0) {
        if (!ap->obj.var.dynamic) {
            ejsThrowTypeError(ejs, "Object is not dynamic");
            return EJS_ERR;
        }
        slotNum = ap->length;
        if (growArray(ejs, ap, ap->length + 1) < 0) {
            ejsThrowMemoryError(ejs);
            return EJS_ERR;
        }

    } else if (slotNum >= ap->length) {
        if (growArray(ejs, ap, slotNum + 1) < 0) {
            ejsThrowMemoryError(ejs);
            return EJS_ERR;
        }
    }
    return slotNum;
}
Example #17
0
static EjsObj *cloneXmlList(Ejs *ejs, EjsXML *list, bool deep)
{
    EjsXML  *newList;

    //  TODO - implement deep copy
    newList = ejsCreateObj(ejs, TYPE(list), 0);
    if (newList == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    //  TODO incomplete
    return (EjsObj*) newList;
}
Example #18
0
/*
    DB Constructor and also used for constructor for sub classes.

    function Debugger(connectionString: String)
 */
static EjsVar *debuggerConstructor(Ejs *ejs, EjsDebugger *db, int argc, EjsVar **argv)
{
    debugger3         *sdb;
    cchar           *path;

    path = ejsGetString(ejs, argv[0]);    
    db->ejs = ejs;
    
    /*
     *  Create a memory context for use by debugger. This is a virtual paged memory region.
     *  TODO OPT - Could do better for running applications.
     */
#if MAP_ALLOC
    db->arena = mprAllocArena(ejs, "debugger", EJS_MAX_SQLITE_MEM, !USE_TLS, 0);
    if (db->arena == 0) {
        return 0;
    }
    SET_CTX(db->arena);
#else
    db->arena = mprAllocHeap(ejs, "debugger", EJS_MAX_SQLITE_MEM, 1, 0);
    if (db->arena == 0) {
        return 0;
    }
    SET_CTX(db->arena);
#endif
    
#if UNUSED
    EjsDebugger       **dbp;
    /*
     *  Create a destructor object so we can cleanup and close the database. Must create after the arena so it will be
     *  invoked before the arena is freed. 
     */
    if ((dbp = mprAllocWithDestructor(ejs, sizeof(void*), (MprDestructor) sqldbDestructor)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    *dbp = db;
#endif

    sdb = 0;
    if (debugger3_open(path, &sdb) != SQLITE_OK) {
        ejsThrowIOError(ejs, "Cannot open database %s", path);
        return 0;
    }
    db->sdb = sdb;
    debugger3_busy_timeout(sdb, ME_MAX_SQLITE_DURATION);
    debugger3_soft_heap_limit(ME_MAX_SQLITE_MEM);
    return 0;
}
Example #19
0
/*  
    Read data bytes from a file
    function readBytes(count: Number = -1): ByteArray
 */
static EjsObj *readFileBytes(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsByteArray    *result;
    MprPath         info;
    ssize           count, totalRead;

    if (argc == 0) {
        count = -1;
    } else if (argc != 1) {
        count = 0;
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    } else {
        assert(argc == 1 && ejsIs(ejs, argv[0], Number));
        count = ejsGetInt(ejs, argv[0]);
    }
    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 (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);
    }
    result = ejsCreateByteArray(ejs, count);
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    totalRead = readData(ejs, fp, result, 0, count);
    if (totalRead < 0) {
        ejsThrowIOError(ejs, "Cannot read from file: %s", fp->path);
        return 0;
    } else if (totalRead == 0) {
        return ESV(null);
    }
    ejsSetByteArrayPositions(ejs, result, 0, totalRead);
    return (EjsObj*) result;
}
Example #20
0
PUBLIC EjsArray *ejsCreateArray(Ejs *ejs, int size)
{
    EjsArray    *ap;

    /*
        No need to invoke constructor
     */
    if ((ap = ejsCreatePot(ejs, ESV(Array), 0)) != 0) {
        ap->length = 0;
        if (size > 0 && growArray(ejs, ap, size) < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
    }
    return ap;
}
Example #21
0
/*
    Copy all properties of the instance including all references. If deep is true and if some properties are 
    reference types, then recursively copy all their properties and so on.

    @param ejs VM handle.
    @param sp is set to the object instance to clone. 
    @return The newly copied object
 */
static EjsObj *cloneShape(Ejs *ejs, Shape *sp, bool deep)
{
    Shape   *newShape;

    newShape = ejsCreateObj(ejs, TYPE(sp), 0);
    if (newShape == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    newShape->x = sp->x;
    newShape->y = sp->y;
    newShape->height = sp->height;
    newShape->width = sp->width;

    return (EjsObj*) newShape;
}
Example #22
0
/*
    WARNING: the inside interpreter owns the exception object. Must fully extract all fields
 */
static void handleError(Ejs *ejs, EjsWorker *worker, EjsObj *exception, int throwOutside)
{
    Ejs             *inside;
    EjsObj          *e;
    MprDispatcher   *dispatcher;
    Message         *msg;

    assert(!worker->inside);
    assert(exception);
    assert(ejs == worker->ejs);

    ejsBlockGC(ejs);
    if ((msg = createMessage()) == 0) {
        ejsThrowMemoryError(ejs);
        return;
    }
    msg->worker = worker;
    msg->callback = "onerror";
    msg->callbackSlot = ES_Worker_onerror;
    inside = worker->pair->ejs;
    
    inside->exception = 0;
    e = ejsDeserialize(ejs, ejsSerialize(inside, exception, 0));
    inside->exception = exception;

    /*
        Inside interpreter owns the exception object, so must fully extract all exception. 
        Allocate into the outside worker's interpreter.
     */
    if (ejsIsError(inside, exception)) {
        msg->message = ejsGetPropertyByName(ejs, e, EN("message"));
        msg->stack = ejsGetPropertyByName(ejs, e, EN("stack"));
    } else {
        msg->message = e;
        msg->stack = 0;
    }
    if (throwOutside) {
        if (msg->stack) {
            ejsThrowStateError(ejs, "%@\n%@", ejsToString(ejs, msg->message), ejsToString(ejs, msg->stack));
        } else {
            ejsThrowStateError(ejs, "%@", ejsToString(ejs, msg->message));
        }
    }
    dispatcher = ejs->dispatcher;
    mprCreateEvent(dispatcher, "doMessage-error", 0, (MprEventProc) doMessage, msg, 0);
}
Example #23
0
/*  
    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);
}
Example #24
0
/*  
    Read data as a string
    function readString(count: Number = -1): String
 */
static EjsString *readFileString(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsString       *result;
    MprPath         info;
    ssize           totalRead;
    int             count;

    if (argc == 0) {
        count = -1;
    } else if (argc != 1) {
        count = 0;
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    } else {
        assert(argc == 1 && ejsIs(ejs, argv[0], Number));
        count = ejsGetInt(ejs, argv[0]);
    }
    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 (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);
    }
    if ((result = ejsCreateBareString(ejs, count)) == NULL) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    totalRead = mprReadFile(fp->file, result->value, count);
    if (totalRead != count) {
        ejsThrowIOError(ejs, "Cannot read from file: %s", fp->path);
        return 0;
    }
    return ejsInternString(result);
}
Example #25
0
EjsArray *ejsCreateArray(Ejs *ejs, int size)
{
    EjsArray    *ap;

    /*
     *  No need to invoke constructor
     */
    ap = (EjsArray*) ejsCreateObject(ejs, ejs->arrayType, 0);
    if (ap != 0) {
        ap->length = 0;
        if (size > 0 && growArray(ejs, ap, size) < 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
    }
    ejsSetDebugName(ap, "array instance");
    return ap;
}
Example #26
0
/*
 *  Allocate a new variable. Size is set to the extra bytes for properties in addition to the type's instance size.
 */
EjsVar *ejsAllocVar(Ejs *ejs, EjsType *type, int extra)
{
    EjsVar      *vp;

    mprAssert(type);

    if ((vp = (EjsVar*) mprAllocZeroed(ejsGetAllocCtx(ejs), type->instanceSize + extra)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    vp->type = type;
    vp->master = (ejs->master == 0);
    ejsAddToGcStats(ejs, vp, type->id);
    if (++ejs->workDone >= ejs->workQuota) {
        ejs->gcRequired = 1;
        ejs->attention = 1;
    }
    return (EjsVar*) vp;
}
Example #27
0
/*  
    function Http(uri: Uri = null)
 */
static EjsHttp *httpConstructor(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    ejsLoadHttpService(ejs);
    hp->ejs = ejs;

    if ((hp->conn = httpCreateConn(ejs->http, NULL, ejs->dispatcher)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    httpPrepClientConn(hp->conn, 0);
    httpSetConnNotifier(hp->conn, httpEventChange);
    httpSetConnContext(hp->conn, hp);
    if (argc == 1 && ejsIs(ejs, argv[0], Null)) {
        hp->uri = httpUriToString(((EjsUri*) argv[0])->uri, HTTP_COMPLETE_URI);
    }
    hp->method = sclone("GET");
    hp->requestContent = mprCreateBuf(BIT_MAX_BUFFER, -1);
    hp->responseContent = mprCreateBuf(BIT_MAX_BUFFER, -1);
    return hp;
}
Example #28
0
/*
 *  WARNING: the inside interpreter owns the exception object. Must fully extract all fields
 */
static void handleError(Ejs *ejs, EjsWorker *worker, EjsVar *exception)
{
    EjsError        *error;
    MprDispatcher   *dispatcher;
    Message         *msg;

    mprAssert(!worker->inside);
    mprAssert(exception);
    mprAssert(ejs == worker->ejs);

    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return;
    }
    msg->worker = worker;
    msg->callback = "onerror";
    msg->callbackSlot = ES_ejs_sys_Worker_onerror;
    
    /*
     *  Inside interpreter owns the exception object, so must fully extract all exception. 
     *  Allocate into the outside worker's interpreter.
     */
    if (ejsIsError(exception)) {
        error = (EjsError*) exception;
        msg->message = mprStrdup(ejs, error->message);
        msg->filename = mprStrdup(ejs, error->filename ? error->filename : "script");
        msg->lineNumber = error->lineNumber;
        msg->stack = mprStrdup(ejs, error->stack);

    } else if (ejsIsString(exception)) {
        msg->message = mprStrdup(ejs, ejsGetString(exception));

    } else {
        msg->message = mprStrdup(ejs, ejsGetString(ejsToString(ejs, exception)));
    }
    dispatcher = ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
}
Example #29
0
static inline void pruneTypePools(Ejs *ejs)
{
    EjsPool     *pool;
    EjsGC       *gc;
    EjsVar      *vp;
    MprAlloc    *alloc;
    MprBlk      *bp, *next;
    int64       memory;
    int         i;

    gc = &ejs->gc;

    /*
     *  Still insufficient memory, must reclaim all objects from the type pools.
     */
    for (i = 0; i < gc->numPools; i++) {
        pool = gc->pools[i];
        if (pool->count) {
            for (bp = mprGetFirstChild(pool); bp; bp = next) {
                next = bp->next;
                vp = MPR_GET_PTR(bp);
                mprFree(vp);
            }
            pool->count = 0;
        }
    }
    gc->totalRedlines++;

    memory = mprGetUsedMemory(ejs);
    alloc = mprGetAllocStats(ejs);

    if (memory >= alloc->maxMemory) {
        /*
         *  Could not provide sufficient memory. Go into graceful degrade mode
         */
        ejsThrowMemoryError(ejs);
        ejsGracefulDegrade(ejs);
    }
}
Example #30
0
static EjsVar *castError(Ejs *ejs, EjsError *vp, EjsType *type)
{
    EjsVar      *sp;
    char        *buf;

    switch (type->id) {

    case ES_Boolean:
        return (EjsVar*) ejsCreateBoolean(ejs, 1);

    case ES_String:
        if ((buf = mprAsprintf(ejs, -1,
                "%s Exception: %s\nStack:\n%s\n", vp->obj.var.type->qname.name, vp->message, vp->stack)) == NULL) {
            ejsThrowMemoryError(ejs);
        }
        sp = (EjsVar*) ejsCreateString(ejs, buf);
        mprFree(buf);
        return sp;

    default:
        ejsThrowTypeError(ejs, "Unknown type");
        return 0;
    }
}