Example #1
0
/*  
    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;
}
Example #2
0
/* 
    Write another block of data
 */
static ssize writeHttpData(Ejs *ejs, EjsHttp *hp)
{
    EjsByteArray    *ba;
    HttpConn        *conn;
    ssize           count, nbytes;

    conn = hp->conn;
    ba = hp->data;
    nbytes = 0;
    if (ba && (count = ejsGetByteArrayAvailableData(ba)) > 0) {
        if (conn->tx->finalizedOutput) {
            ejsThrowIOError(ejs, "Cannot write to socket");
            return 0;
        }
        //  MOB - or should this be non-blocking
        nbytes = httpWriteBlock(conn->writeq, (cchar*) &ba->value[ba->readPosition], count, HTTP_BLOCK);
        if (nbytes < 0) {
            ejsThrowIOError(ejs, "Cannot write to socket");
            return 0;
        }
        ba->readPosition += nbytes;
    }
    httpServiceQueues(conn);
    return nbytes;
}
Example #3
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 #4
0
/*  
    Set the current working directory
    function chdir(value: String|Path): void
 */
static EjsObj *app_chdir(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    cchar   *path;

    assert(argc == 1);

    if (ejsIs(ejs, argv[0], Path)) {
        path = ((EjsPath*) argv[0])->value;

    } else if (ejsIs(ejs, argv[0], String)) {
        path = ejsToMulti(ejs, argv[0]);

    } else {
        ejsThrowIOError(ejs, "Bad path");
        return NULL;
    }
#if WINDOWS
{
    MprFileSystem   *fs;
    fs = mprLookupFileSystem(path);
    if (!mprPathExists(path, X_OK) && *path == '/') {
        path = sjoin(fs->cygwin, path, NULL);
    }
}
#endif
    if (chdir((char*) path) < 0) {
        ejsThrowIOError(ejs, "Cannot change the current directory");
    }
    return 0;
}
Example #5
0
/*  
    Constructor
    function File(path: Object, options: Object = null)
 */
static EjsFile *fileConstructor(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsObj      *pp, *options;
    cchar       *path;

    if (argc < 1 || argc > 2) {
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    }
    pp = argv[0];
    if (ejsIs(ejs, pp, Path)) {
        path = ((EjsPath*) pp)->value;
    } else if (ejsIs(ejs, pp, String)) {
        path = ejsToMulti(ejs, pp);
    } else {
        ejsThrowIOError(ejs, "Bad path");
        return 0;
    }
    fp->path = mprNormalizePath(path);
    if (argc == 2) {
        options = (argc >= 2) ? argv[1] : 0;
        openFile(ejs, fp, 1, &options);
    }
    return fp;
}
Example #6
0
/*  
    Read the required number of bytes into the response content buffer. Count < 0 means transfer the entire content.
    Returns the number of bytes read. Returns null on EOF.
 */ 
static ssize readHttpData(Ejs *ejs, EjsHttp *hp, ssize count)
{
    MprBuf      *buf;
    HttpConn    *conn;
    ssize       len, space, nbytes;

    conn = hp->conn;
    buf = hp->responseContent;
    mprResetBufIfEmpty(buf);
    while (count < 0 || mprGetBufLength(buf) < count) {
        len = (count < 0) ? BIT_MAX_BUFFER : (count - mprGetBufLength(buf));
        space = mprGetBufSpace(buf);
        if (space < len) {
            mprGrowBuf(buf, len - space);
        }
        if ((nbytes = httpRead(conn, mprGetBufEnd(buf), len)) < 0) {
            ejsThrowIOError(ejs, "Cannot read required data");
            return MPR_ERR_CANT_READ;
        }
        mprAdjustBufEnd(buf, nbytes);
        if (hp->conn->async || (nbytes == 0 && conn->state > HTTP_STATE_CONTENT)) {
            break;
        }
    }
    if (count < 0) {
        return mprGetBufLength(buf);
    }
    return min(count, mprGetBufLength(buf));
}
Example #7
0
/*
 *  Return an array of table names in the database.
 *  function get tables(): Array
 */
static EjsVar *tables(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    EjsArray    *ap;
    char        **data, *error;
    int         rc, rowCount, i;

    ejsSetDbMemoryContext(db->tls, db->arena);

    ap = ejsCreateArray(ejs, 0);

    rc = sqlite3_get_table(db->sdb,
      "SELECT name FROM sqlite_master "
      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type IN ('table','view') "
      "ORDER BY 1",
      &data, &rowCount, 0, &error);

    if (error) {
        ejsThrowIOError(ejs, "%s", error);
        sqlite3_free(error);
    }
    if (rc == SQLITE_OK){
        for (i = 1; i <= rowCount; i++) {
            ejsSetProperty(ejs, (EjsVar*) ap, i - 1, (EjsVar*) ejsCreateString(ejs, data[i]));
        }
    }
    sqlite3_free_table(data);
    return (EjsVar*) ap;
}
Example #8
0
/*  
    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;
}
Example #9
0
/*  
    Constructor
    function open(options: Object = null): File
    NOTE: options can be an options hash or as mode string
 */
static EjsObj *openFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsObj  *options;
    cchar   *mode;
    int     perms, omode;

    if (argc < 0 || argc > 1) {
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    }
    options = argv[0];
    if (argc == 0 || !ejsIsDefined(ejs, options)) {
        omode = O_RDONLY | O_BINARY;
        perms = EJS_FILE_PERMS;
        fp->mode = EJS_FILE_READ;
        mode = "r";
    } else {
        if (ejsIs(ejs, options, String)) {
            mode = ejsToMulti(ejs, options);
            perms = EJS_FILE_PERMS;
        } else {
            perms = ejsGetNumOption(ejs, options, "permissions", EJS_FILE_PERMS, 1);
            mode = getStrOption(ejs, options, "mode", "r", 1);
            if (ejs->exception) {
                return 0;
            }
        }
        omode = mapMode(mode);
        if (!(omode & O_WRONLY)) {
            fp->mode |= EJS_FILE_READ;
        }
        if (omode & (O_WRONLY | O_RDWR)) {
            fp->mode |= EJS_FILE_WRITE;
        }
    }
    fp->modeString = sclone(mode);
    fp->perms = perms;

    if (fp->file) {
        mprCloseFile(fp->file);
    }
    fp->file = mprOpenFile(fp->path, omode, perms);
    if (fp->file == 0) {
        ejsThrowIOError(ejs, "Cannot open %s", fp->path);
        return 0;
    }
    if (options) {
        ejsSetPathAttributes(ejs, fp->path, options);
    }
#if ME_CC_MMU && FUTURE
    mprGetPathInfo(&fp->info);
    fp->mapped = mapFile(fp, fp->info.size, MPR_MAP_READ | MPR_MAP_WRITE);
#endif
    fp->mode |= EJS_FILE_OPEN;
    return (EjsObj*) fp;
}
Example #10
0
/*  
    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;
}
Example #11
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 #12
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 #13
0
/*
 *  Set the current working directory
 *
 *  function chdir(value: String|Path): void
 */
static EjsVar *changeCurrentDir(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv)
{
    char    *path;

    mprAssert(argc == 1);

    if (ejsIsPath(argv[0])) {
        path = ((EjsPath*) argv[0])->path;
    } else if (ejsIsString(argv[0])) {
        path = ejsGetString(argv[0]);
    } else {
        ejsThrowIOError(ejs, "Bad path");
        return NULL;
    }

    if (chdir(path) < 0) {
        ejsThrowIOError(ejs, "Can't change the current directory");
    }
    return 0;
}
Example #14
0
/*  
    Write data to the file
    function write(data: Object): Number
 */
PUBLIC EjsObj *writeFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *ap;
    EjsObj          *vp;
    EjsString       *str;
    cchar           *buf;
    ssize           len, written;
    int             i;

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

    args = (EjsArray*) argv[0];

    if (!(fp->mode & EJS_FILE_WRITE)) {
        ejsThrowStateError(ejs, "File not opened for writing");
        return 0;
    }
    written = 0;

    for (i = 0; i < args->length; i++) {
        vp = ejsGetProperty(ejs, (EjsObj*) args, i);
        assert(vp);
        switch (TYPE(vp)->sid) {
        case S_ByteArray:
            ap = (EjsByteArray*) vp;
            //  TODO UNICODE ENCODING
            buf = (cchar*) &ap->value[ap->readPosition];
            len = ap->writePosition - ap->readPosition;
            break;

        case S_String: // UNICODE
#if UNICODE && FUTURE
            buf = awtom(((EjsString*) vp)->value, &len);
#else
            buf = ((EjsString*) vp)->value;
            len = ((EjsString*) vp)->length;
#endif
            break;

        default:
            str = ejsToString(ejs, vp);
            buf = awtom(((EjsString*) str)->value, &len);
            break;
        }
        if (mprWriteFile(fp->file, buf, len) != len) {
            ejsThrowIOError(ejs, "Cannot write to %s", fp->path);
            return 0;
        }
        written += len;
        /* Use GC to free buf as it may not be allocated */
    }
    return (EjsObj*) ejsCreateNumber(ejs, (MprNumber) written);
}
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
/*  
    Index into a file and extract a byte. This is random access reading.
 */
static EjsNumber *getFileProperty(Ejs *ejs, EjsFile *fp, int slotNum)
{
    MprOff  offset;
    int     c;

    if (!(fp->mode & EJS_FILE_OPEN)) {
        ejsThrowIOError(ejs, "File is not open");
        return 0;
    }
#if KEEP
    if (fp->mode & EJS_FILE_READ) {
        if (slotNum >= fp->info.size) {
            ejsThrowOutOfBoundsError(ejs, "Bad file index");
            return 0;
        }
    }
    if (slotNum < 0) {
        ejsThrowOutOfBoundsError(ejs, "Bad file index");
        return 0;
    }
#endif

#if ME_CC_MMU && FUTURE
    //  must check against mapped size here.
    c = fp->mapped[slotNum];
#else
    offset = mprSeekFile(fp->file, SEEK_CUR, 0);
    if (offset != slotNum) {
        if (mprSeekFile(fp->file, SEEK_SET, slotNum) != slotNum) {
            ejsThrowIOError(ejs, "Cannot seek to file offset");
            return 0;
        }
    }
    c = mprPeekFileChar(fp->file);
    if (c < 0) {
        ejsThrowIOError(ejs, "Cannot read file");
        return 0;
    }
#endif
    return ejsCreateNumber(ejs, c);
}
Example #17
0
/*
    uncompressBytes(data: ByteArray): ByteArray
 */
static EjsObj *zlib_uncompressBytes(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsByteArray    *in, *out;
    z_stream        zs;
    uchar           outbuf[ZBUFSIZE];
    ssize           nbytes, size;
    int             rc;

    in = (EjsByteArray*) argv[0];
    if ((out = ejsCreateByteArray(ejs, in->size)) == 0) {
        return 0;
    }
    if ((size = (int) ejsGetByteArrayAvailableData(in)) == 0) {
        return (EjsObj*) out;
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    zs.avail_in = 0;
    rc = inflateInit(&zs);
    zs.next_in = &in->value[in->readPosition];
    zs.avail_in = (int) size;

    do {
        if (zs.avail_in == 0) {
            break;
        }
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = (uchar*) outbuf;
            if ((rc = inflate(&zs, Z_NO_FLUSH)) == Z_NEED_DICT) {
                inflateEnd(&zs);
                return 0;
            } else if (rc == Z_DATA_ERROR || rc == Z_MEM_ERROR) {
                inflateEnd(&zs);
                return 0;
            } else {
                nbytes = ZBUFSIZE - zs.avail_out;
            }
            if (ejsCopyToByteArray(ejs, out, -1, (char*) outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to byte array");
                inflateEnd(&zs);
                return 0;
            }
            out->writePosition += nbytes;
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (rc != Z_STREAM_END);

    deflateEnd(&zs);
    return (EjsObj*) out;
}
Example #18
0
/*
    uncompressString(data: String): String
 */
static EjsString *zlib_uncompressString(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsString       *in;
    MprBuf          *out;
    z_stream        zs;
    uchar           outbuf[ZBUFSIZE];
    ssize           nbytes, size;
    int             rc;

    in = (EjsString*) argv[0];
    if ((out = mprCreateBuf(ZBUFSIZE, -1)) == 0) {
        return 0;
    }
    if ((size = in->length) == 0) {
        return ESV(empty);
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    zs.avail_in = 0;
    rc = inflateInit(&zs);
    zs.next_in = (uchar*) in->value;
    zs.avail_in = (int) size;

    do {
        if (zs.avail_in == 0) {
            break;
        }
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = outbuf;
            if ((rc = inflate(&zs, Z_NO_FLUSH)) == Z_NEED_DICT) {
                inflateEnd(&zs);
                return 0;
            } else if (rc == Z_DATA_ERROR || rc == Z_MEM_ERROR) {
                inflateEnd(&zs);
                return 0;
            } else {
                nbytes = ZBUFSIZE - zs.avail_out;
            }
            if (mprPutBlockToBuf(out, (char*) outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to byte array");
                inflateEnd(&zs);
                return 0;
            }
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (rc != Z_STREAM_END);

    deflateEnd(&zs);
    return ejsCreateStringFromBytes(ejs, mprGetBufStart(out), mprGetBufLength(out));
}
Example #19
0
/*  
    function sendBlock(content, options): Number
 */
static EjsNumber *ws_sendBlock(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv)
{
    EjsByteArray    *ba;
    EjsAny          *content, *vp;
    ssize           nbytes;
    cchar           *str;
    int             last, mode, type, flags;

    assert(argc == 2);

    if (ws->conn->state < HTTP_STATE_PARSED && !waitForHttpState(ws, HTTP_STATE_PARSED, -1, 1)) {
        return ESV(null);
    }
    content = argv[0];
    last = ejsGetPropertyByName(ejs, argv[1], EN("last")) != ESV(false);
    if ((vp = ejsGetPropertyByName(ejs, argv[1], EN("mode"))) != 0) {
        mode = (int) ejsGetNumber(ejs, vp);
        if (mode != HTTP_BUFFER && mode != HTTP_BLOCK && mode != HTTP_NON_BLOCK) {
            ejsThrowArgError(ejs, "Bad message mode");
            return 0;
        }
    } else {
        mode = HTTP_BUFFER;
    }
    if ((vp = ejsGetPropertyByName(ejs, argv[1], EN("type"))) != 0) {
        type = (int) ejsGetNumber(ejs, vp);
        if (type != WS_MSG_CONT && type != WS_MSG_TEXT && type != WS_MSG_BINARY) {
            ejsThrowArgError(ejs, "Bad message type");
            return 0;
        }
    } else {
        type = WS_MSG_TEXT;
    }
    flags = mode;
    if (!last) {
        flags |= HTTP_MORE;
    }
    if (ejsIs(ejs, content, ByteArray)) {
        ba = (EjsByteArray*) content;
        nbytes = ejsGetByteArrayAvailableData(ba);
        nbytes = httpSendBlock(ws->conn, type, (cchar*) &ba->value[ba->readPosition], nbytes, flags);
    } else {
        str = ejsToMulti(ejs, content);
        nbytes = httpSendBlock(ws->conn, type, str, slen(str), flags);
    }
    if (nbytes < 0) {
        ejsThrowIOError(ejs, "Cannot send block");
        return 0;
    }
    return ejsCreateNumber(ejs, (MprNumber) nbytes);
}
Example #20
0
static EjsObj *saveXml(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    MprBuf      *buf;
    MprFile     *file;
    char        *filename;
    ssize       bytes, len;

    if (argc != 1 || !ejsIs(ejs, argv[0], String)) {
        ejsThrowArgError(ejs, "Bad args. Usage: save(filename);");
        return 0;
    }
    filename = awtom(((EjsString*) argv[0])->value, NULL);

    /*
        Create a buffer to hold the output. All in memory.
     */
    buf = mprCreateBuf(ME_MAX_BUFFER, -1);
    mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>\n");

    if (ejsXMLToBuf(ejs, buf, xml, 0) < 0) {
        return 0;
    }
    file = mprOpenFile(filename,  O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664);
    if (file == 0) {
        ejsThrowIOError(ejs, "Cannot open: %s, %d", filename, mprGetOsError(ejs));
        return 0;
    }
    len = mprGetBufLength(buf);
    bytes = mprWriteFile(file, buf->start, len);
    if (bytes != len) {
        ejsThrowIOError(ejs, "Cannot write to: %s", filename);
        mprCloseFile(file);
        return 0;
    }
    mprWriteFile(file, "\n", 1);
    mprCloseFile(file);
    return 0;
}
Example #21
0
/*
    uncompress(src: Path, dest: Path = null)
 */
static EjsObj *zlib_uncompress(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    MprFile     *out;
    gzFile      in;
    cchar       *src, *dest;
    uchar       inbuf[MPR_BUFSIZE];
    ssize       nbytes;

    src = ((EjsPath*) argv[0])->value;
    dest = (argc >= 2) ? ejsToMulti(ejs, argv[1]) : 0;
    if (!dest) {
        dest = sjoin(src, ".gz", NULL);
    }
    if ((in = gzopen(src, "rb")) == 0) {
        ejsThrowIOError(ejs, "Cannot open from %s", src);
        return 0;
    }
    if ((out = mprOpenFile(dest, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644)) == 0) {
        ejsThrowIOError(ejs, "Cannot open destination %s", dest);
        return 0;
    }
    while (1) {
        if ((nbytes = gzread(in, inbuf, sizeof(inbuf))) < 0) {
            ejsThrowIOError(ejs, "Cannot read from %s", src);
            return 0;
        } else if (nbytes == 0) {
            break;
        }
        if (mprWriteFile(out, inbuf, (int) nbytes) != nbytes) {
            ejsThrowIOError(ejs, "Cannot write to %s", dest);
            return 0;
        }
    }
    mprCloseFile(out);
    gzclose(in);
    return 0;
}
Example #22
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 #23
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 #24
0
static int lookupFileProperty(Ejs *ejs, EjsFile *fp, EjsName qname)
{
    int     index;

    if (qname.name == 0 || !isdigit((uchar) qname.name->value[0])) {
        return EJS_ERR;
    }
    if (!(fp->mode & EJS_FILE_OPEN)) {
        ejsThrowIOError(ejs, "File is not open");
        return 0;
    }
    index = ejsAtoi(ejs, qname.name, 10);
    if (index < mprGetFileSize(fp->file)) {
        return index;
    }
    return EJS_ERR;
}
Example #25
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 #26
0
/*  
    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;
}
Example #27
0
static EjsObj *startWebSocketRequest(Ejs *ejs, EjsWebSocket *ws)
{
    HttpConn        *conn;

    conn = ws->conn;
    if (ws->certFile) {
        if (!ws->ssl) {
            ws->ssl = mprCreateSsl(0);
        }
        mprSetSslCertFile(ws->ssl, ws->certFile);
    }
    if (httpConnect(conn, "GET", ws->uri, ws->ssl) < 0) {
        ejsThrowIOError(ejs, "Cannot issue request for \"%s\"", ws->uri);
        return 0;
    }
    httpEnableConnEvents(ws->conn);
    return 0;
}
Example #28
0
/*
    compressString(data: String): String
 */
static EjsString *zlib_compressString(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsString       *in;
    MprBuf          *out;
    z_stream        zs;
    uchar           outbuf[ZBUFSIZE];
    ssize           size, nbytes;
    int             level, flush;

    in = (EjsString*) argv[0];
    if ((size = in->length) == 0) {
        return ESV(empty);
    }
    if ((out = mprCreateBuf(in->length, 0)) == 0) {
        return 0;
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    level = Z_DEFAULT_COMPRESSION;
    deflateInit(&zs, level);
    zs.next_in = (uchar*) in->value;
    zs.avail_in = (int) size;
    do {
        flush = (zs.avail_in == 0) ? Z_FINISH : Z_NO_FLUSH;
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = outbuf;
            deflate(&zs, flush);
            nbytes = ZBUFSIZE - zs.avail_out;
            if (mprPutBlockToBuf(out, (char*) outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to output buffer");
                deflateEnd(&zs);
                return 0;
            }
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (flush != Z_FINISH);

    deflateEnd(&zs);
    return ejsCreateStringFromBytes(ejs, mprGetBufStart(out), mprGetBufLength(out));
}
Example #29
0
/*  
    Read the specified count of bytes into the byte array. Grow the array if required and growable
 */
static ssize readData(Ejs *ejs, EjsFile *fp, EjsByteArray *ap, ssize offset, ssize count)
{
    ssize   room, bytes;

    if (count <= 0) {
        return 0;
    }
    room = ap->size - offset;
    if (room < count) {
        if (ap->resizable) {
            ejsGrowByteArray(ejs, ap, ap->size + (count - room));
        } else {
            count = min(room, count);
        }
    }
    bytes = mprReadFile(fp->file, &ap->value[offset], count);
    if (bytes < 0) {
        ejsThrowIOError(ejs, "Error reading from %s", fp->path);
    }
    return bytes;
}
Example #30
0
/*
    Load a file into the worker. This can be a script file or a module. This runs on the inside interpreter
 */
static void loadFile(EjsWorker *worker, cchar *path)
{
    Ejs         *ejs;
    cchar       *cp;

    assert(worker->inside);
    assert(worker->pair && worker->pair->ejs);

    ejs = worker->ejs;
    if ((cp = strrchr(path, '.')) != NULL && strcmp(cp, EJS_MODULE_EXT) != 0) {
        if (ejs->service->loadScriptFile == 0) {
            ejsThrowIOError(ejs, "load: Compiling is not enabled for %s", path);
            return;
        }
        (ejs->service->loadScriptFile)(ejs, path, NULL);

    } else {
        /* Error reporting via thrown exceptions */
        ejsLoadModule(ejs, ejsCreateStringFromAsc(ejs, path), -1, -1, EJS_LOADER_RELOAD);
    }
}