/* 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)); }
static EjsString *joinArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv) { EjsString *sep, *sp; MprBuf *buf; ssize len; int i, nonString; sep = (argc == 1) ? (EjsString*) argv[0] : NULL; if (sep == ESV(empty) && ap->length == 1 && ejsIs(ejs, ap->data[0], String)) { /* Optimized path for joining [string]. This happens frequently with fun(...args) */ return (EjsString*) ap->data[0]; } /* Get an estimate of the string length */ len = 0; nonString = 0; for (i = 0; i < ap->length; i++) { sp = (EjsString*) ap->data[i]; if (!ejsIs(ejs, sp, String)) { nonString = 1; continue; } len += sp->length; } if (sep) { len += (ap->length * sep->length); } if (nonString) { len += ME_MAX_BUFFER; } buf = mprCreateBuf(len + 1, -1); for (i = 0; i < ap->length; i++) { sp = (EjsString*) ap->data[i]; if (!ejsIsDefined(ejs, sp)) { continue; } sp = ejsToString(ejs, sp); if (!ejsIsDefined(ejs, sp)) { continue; } if (i > 0 && sep) { mprPutBlockToBuf(buf, sep->value, sep->length); } mprPutBlockToBuf(buf, sp->value, sp->length); } mprAddNullToBuf(buf); return ejsCreateStringFromBytes(ejs, mprGetBufStart(buf), mprGetBufLength(buf)); }
/* 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)); }
/* Connection callback */ static void webSocketNotify(HttpConn *conn, int event, int arg) { Ejs *ejs; EjsWebSocket *ws; EjsByteArray *ba; EjsAny *data; HttpPacket *packet; MprBuf *content; ssize len; if ((ws = httpGetConnContext(conn)) == 0) { return; } ejs = ws->ejs; if (!ejs->service) { /* Shutting down */ return; } switch (event) { case HTTP_EVENT_STATE: if (arg == HTTP_STATE_CONTENT) { ws->protocol = (char*) httpGetHeader(conn, "Sec-WebSocket-Protocol"); mprTrace(3, "Web socket protocol %s", ws->protocol); onWebSocketEvent(ws, HTTP_EVENT_APP_OPEN, 0, 0); } break; case HTTP_EVENT_READABLE: packet = httpGetPacket(conn->readq); content = packet->content; if (packet->type == WS_MSG_TEXT) { data = ejsCreateStringFromBytes(ejs, mprGetBufStart(content), mprGetBufLength(content)); } else { len = httpGetPacketLength(packet); assert(len > 0); if ((ba = ejsCreateByteArray(ejs, len)) == 0) { return; } memcpy(ba->value, mprGetBufStart(content), len); ejsSetByteArrayPositions(ejs, ba, -1, len); data = ba; } onWebSocketEvent(ws, event, data, packet); break; case HTTP_EVENT_ERROR: if (!ws->error && !ws->closed) { ws->error = 1; onWebSocketEvent(ws, event, 0, 0); ws->closed = 1; onWebSocketEvent(ws, HTTP_EVENT_APP_CLOSE, 0, 0); } break; case HTTP_EVENT_APP_CLOSE: if (!ws->closed) { ws->closed = 1; onWebSocketEvent(ws, event, 0, 0); } break; } }