Example #1
0
static EjsAny *invokeNamespaceOperator(Ejs *ejs, EjsNamespace *lhs, int opCode, EjsNamespace *rhs)
{
    bool        boolResult;

    switch (opCode) {
    case EJS_OP_COMPARE_EQ:
        if (!ejsIsDefined(ejs, rhs)) {
            return ((opCode == EJS_OP_COMPARE_EQ) ? ESV(false): ESV(true));
        }
        boolResult = ejsCompareString(ejs, lhs->value, rhs->value) == 0;
        break;

    case EJS_OP_COMPARE_STRICTLY_EQ:
        boolResult = lhs == rhs;
        break;

    case EJS_OP_COMPARE_NE:
        if (!ejsIsDefined(ejs, rhs)) {
            return ((opCode == EJS_OP_COMPARE_EQ) ? ESV(false): ESV(true));
        }
        boolResult = !(ejsCompareString(ejs, lhs->value, rhs->value) == 0);
        break;

    case EJS_OP_COMPARE_STRICTLY_NE:
        boolResult = !(lhs == rhs);
        break;

    default:
        ejsThrowTypeError(ejs, "Operation is not valid on this type");
        return 0;
    }
    return ejsCreateBoolean(ejs, boolResult);
}
Example #2
0
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));
}
Example #3
0
/*  
    Expand a template with {word} tokens from the given options objects

    function template(pattern: String, ...options): Uri
 */
static EjsUri *uri_template(Ejs *ejs, EjsUri *up, int argc, EjsObj **argv)
{
    EjsArray    *options;
    EjsObj      *obj, *value;
    MprBuf      *buf;
    cchar       *pattern, *cp, *ep, *str;
    char        *token;
    int         i, len;

    pattern = ejsToMulti(ejs, argv[0]);
    options = (EjsArray*) argv[1];

    buf = mprCreateBuf(-1, -1);
    for (cp = pattern; *cp; cp++) {
        if (*cp == '~' && (cp == pattern || cp[-1] != '\\')) {
            for (i = 0; i < options->length; i++) {
                obj = options->data[i];
                if ((value = ejsGetPropertyByName(ejs, obj, N(NULL, "scriptName"))) != 0 && ejsIsDefined(ejs, value)) {
                    str = ejsToMulti(ejs, value);
                    if (str && *str) {
                        mprPutStringToBuf(buf, str);
                        break;
                    } else {
                        value = 0;
                    }
                }
            }
        } else if (*cp == '{' && (cp == pattern || cp[-1] != '\\')) {
            if ((ep = strchr(++cp, '}')) != 0) {
                len = (int) (ep - cp);
                token = mprMemdup(cp, len + 1);
                token[len] = '\0';
                value = 0;
                for (i = 0; i < options->length; i++) {
                    obj = options->data[i];
                    if ((value = ejsGetPropertyByName(ejs, obj, N(NULL, token))) != 0 && ejsIsDefined(ejs, value)) {
                        str = ejsToMulti(ejs, value);
                        if (str && *str) {
                            mprPutStringToBuf(buf, str);
                            break;
                        } else {
                            value = 0;
                        }
                    }
                }
                if (!ejsIsDefined(ejs, value)) {
                    //  MOB - remove this. Should not be erasing the prior "/"
                    if (cp >= &pattern[2] && cp[-2] == '/') {
                        mprAdjustBufEnd(buf, -1);
                    }
                }
                cp = ep;
            }
        } else {
            mprPutCharToBuf(buf, *cp);
        }
    }
    mprAddNullToBuf(buf);
    return ejsCreateUriFromAsc(ejs, mprGetBufStart(buf));
}
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
File: ejsUri.c Project: coordcn/ejs
static HttpUri *toHttpUri(Ejs *ejs, EjsObj *arg, int dup)
{
    HttpUri     *uri;

    if (!ejsIsDefined(ejs, arg)) {
        arg = ESV(empty);
    } 
    if (ejsIs(ejs, arg, String)) {
        uri = httpCreateUri(ejsToMulti(ejs, arg), 0);

    } else if (ejsIs(ejs, arg, Uri)) {
        if (dup) {
            uri = httpCloneUri(((EjsUri*) arg)->uri, 0);
        } else {
            uri = ((EjsUri*) arg)->uri;
        }

    } else if (ejsIs(ejs, arg, Path)) {
        uri = httpCreateUri(((EjsPath*) arg)->value, 0);

    } else if (ejsGetLength(ejs, arg) > 0) {
        uri = createHttpUriFromHash(ejs, arg, 0);

    } else {
        arg = (EjsObj*) ejsToString(ejs, arg);
        uri = httpCreateUri(ejsToMulti(ejs, arg), 0);
    }
    return uri;
}
Example #6
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 #7
0
/*
    native function XML(value: Object = null)
 */
static EjsObj *xmlConstructor(Ejs *ejs, EjsXML *thisObj, int argc, EjsObj **argv)
{
    EjsObj      *arg, *vp;
    wchar       *str;

    //  TODO - should be also able to handle a File object

    if (thisObj == 0) {
        /*
            Called as a function - cast the arg
         */
        if (argc > 0) {
            if ((arg = ejsCast(ejs, argv[0], String)) == 0) {
                return 0;
            }
        }
        thisObj = ejsCreateXML(ejs, 0, N(NULL, NULL), NULL, NULL);
    }
    if (argc == 0) {
        return (EjsObj*) thisObj;
    }

    arg = argv[0];
    assert(arg);

    if (!ejsIsDefined(ejs, arg)) {
        return (EjsObj*) thisObj;
    }
    arg = ejsCast(ejs, argv[0], String);
    if (arg && ejsIs(ejs, arg, String)) {
        str = ((EjsString*) arg)->value;
        if (str == 0) {
            return 0;
        }
        while (isspace((uchar) *str)) str++;
        if (*str == '<') {
            /* XML Literal */
            ejsLoadXMLString(ejs, thisObj, (EjsString*) arg);

        } else {
            /* Load from file */
            loadXml(ejs, thisObj, argc, argv);
        }
    } else if (arg && ejsIsXML(ejs, arg)) {
        if ((vp = xmlToString(ejs, argv[0], 0, NULL)) != 0) {
            ejsLoadXMLString(ejs, thisObj, (EjsString*) vp);
        }

    } else {
        ejsThrowArgError(ejs, "Bad type passed to XML constructor");
        return 0;
    }
    return (EjsObj*) thisObj;
}
Example #8
0
/*
    Cast operands as required for invokeArrayOperator
 */
static EjsObj *coerceArrayOperands(Ejs *ejs, EjsObj *lhs, int opcode, EjsObj *rhs)
{
    switch (opcode) {
    /*
        Binary operators
     */
    case EJS_OP_ADD:
        return ejsInvokeOperator(ejs, arrayToString(ejs, (EjsArray*) lhs, 0, 0), opcode, rhs);

    case EJS_OP_AND: case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_OR: case EJS_OP_REM:
    case EJS_OP_SHL: case EJS_OP_SHR: case EJS_OP_SUB: case EJS_OP_USHR: case EJS_OP_XOR:
        return ejsInvokeOperator(ejs, ESV(zero), opcode, rhs);

    case EJS_OP_COMPARE_EQ: case EJS_OP_COMPARE_NE:
        if (!ejsIsDefined(ejs, rhs)) {
            return ((opcode == EJS_OP_COMPARE_EQ) ? ESV(false): ESV(true));
        } else if (ejsIs(ejs, rhs, Number)) {
            return ejsInvokeOperator(ejs, ejsToNumber(ejs, lhs), opcode, rhs);
        }
        return ejsInvokeOperator(ejs, ejsToString(ejs, lhs), opcode, rhs);

    case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_LT:
    case EJS_OP_COMPARE_GE: case EJS_OP_COMPARE_GT:
        if (ejsIs(ejs, rhs, Number)) {
            return ejsInvokeOperator(ejs, ejsToNumber(ejs, lhs), opcode, rhs);
        }
        return ejsInvokeOperator(ejs, ejsToString(ejs, lhs), opcode, rhs);

    case EJS_OP_COMPARE_STRICTLY_NE:
    case EJS_OP_COMPARE_UNDEFINED:
    case EJS_OP_COMPARE_NOT_ZERO:
    case EJS_OP_COMPARE_NULL:
        return ESV(true);

    case EJS_OP_COMPARE_STRICTLY_EQ:
    case EJS_OP_COMPARE_FALSE:
    case EJS_OP_COMPARE_TRUE:
    case EJS_OP_COMPARE_ZERO:
        return ESV(false);

    /*
        Unary operators
     */
    case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG:
        return 0;

    default:
        ejsThrowTypeError(ejs, "Opcode %d not valid for type %@", opcode, TYPE(lhs)->qname.name);
        return ESV(undefined);
    }
}
Example #9
0
static EjsAny *coerceUriOperands(Ejs *ejs, EjsUri *lhs, int opcode,  EjsAny *rhs)
{
    HttpUri     *uri;
    char        *ustr;

    switch (opcode) {
    /*
        Binary operators
     */
    case EJS_OP_ADD:
        uri = lhs->uri;
        ustr = httpFormatUri(uri->scheme, uri->host, uri->port, uri->path, uri->reference, uri->query, 0);
        return ejsInvokeOperator(ejs, ejsCreateStringFromAsc(ejs, ustr), opcode, rhs);

    case EJS_OP_COMPARE_EQ: case EJS_OP_COMPARE_NE:
    case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_LT:
    case EJS_OP_COMPARE_GE: case EJS_OP_COMPARE_GT:
        if (!ejsIsDefined(ejs, rhs)) {
            return ((opcode == EJS_OP_COMPARE_EQ) ? ESV(false): ESV(true));
        }
        uri = lhs->uri;
        ustr = httpFormatUri(uri->scheme, uri->host, uri->port, uri->path, uri->reference, uri->query, 0);
        return ejsInvokeOperator(ejs, ejsCreateStringFromAsc(ejs, ustr), opcode, rhs);

    case EJS_OP_COMPARE_STRICTLY_NE:
        return ESV(true);

    case EJS_OP_COMPARE_STRICTLY_EQ:
        return ESV(false);

    case EJS_OP_COMPARE_NOT_ZERO:
    case EJS_OP_COMPARE_TRUE:
        return ESV(true);

    case EJS_OP_COMPARE_ZERO:
    case EJS_OP_COMPARE_FALSE:
        return ESV(false);

    case EJS_OP_COMPARE_UNDEFINED:
    case EJS_OP_COMPARE_NULL:
        return ESV(false);

    default:
        ejsThrowTypeError(ejs, "Opcode %d not valid for type %@", opcode, TYPE(lhs)->qname.name);
        return ESV(undefined);
    }
    return 0;
}
Example #10
0
/*
    Compact an array. Remove all null elements.

    function compact() : Array
 */
static EjsArray *compactArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsObj      **data, **src, **dest;
    int         i, oldLen;

    data = ap->data;
    src = dest = &data[0];
    for (i = 0; i < ap->length; i++, src++) {
        if (*src == 0 || !ejsIsDefined(ejs, *src)) {
            continue;
        }
        *dest++ = *src;
    }
    oldLen = ap->length;
    ap->length = (int) (dest - &data[0]);
    for (i = ap->length; i < oldLen; i++) {
        *dest++ = ESV(undefined);
    }
    return ap;
}
Example #11
0
static EjsUri *completeUri(Ejs *ejs, EjsUri *up, EjsObj *missing, int includeQuery)
{
    EjsUri      *missingUri;

    if (!ejsIsDefined(ejs, missing)) {
        missingUri = 0;
    } else if (ejsGetLength(ejs, missing) > 0) {
        missingUri = ejsCreateObj(ejs, ESV(Uri), 0);
        missingUri->uri = createHttpUriFromHash(ejs, missing, HTTP_COMPLETE_URI);
    } else {
        missingUri = ejsToUri(ejs, missing);
    }
    if (missingUri == 0) {
        if (!includeQuery) {
            up->uri->query = NULL;
        }
        httpCompleteUri(up->uri, NULL);
    } else {
        httpCompleteUri(up->uri, missingUri->uri);
    }
    return up;
}
Example #12
0
/* UNUSED */
static EjsString *joinArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsString       *result, *sep;
    EjsObj          *vp;
    int             i;

    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];
    }
    result = ESV(empty);
    for (i = 0; i < ap->length; i++) {
        vp = ap->data[i];
        if (!ejsIsDefined(ejs, vp)) {
            continue;
        }
        if (i > 0 && sep) {
            result = ejsJoinString(ejs, result, sep);
        }
        result = ejsJoinString(ejs, result, ejsToString(ejs, vp));
    }
    return result;
}
Example #13
0
static EjsString *serialize(Ejs *ejs, EjsAny *vp, Json *json)
{
    EjsName     qname;
    EjsFunction *fn;
    EjsString   *result, *sv;
    EjsTrait    *trait;
    EjsObj      *pp, *obj, *replacerArgs[2];
    wchar       *cp;
    cchar       *key;
    int         c, isArray, i, count, slotNum, quotes;

    /*
        The main code below can handle Arrays, Objects, objects derrived from Object and also native classes with properties.
        All others just use toString.
     */
    count = ejsIsPot(ejs, vp) ? ejsGetLength(ejs, vp) : 0;
    if (count == 0 && TYPE(vp) != ESV(Object) && TYPE(vp) != ESV(Array)) {
        //  OPT - need some flag for this test.
        if (!ejsIsDefined(ejs, vp) || ejsIs(ejs, vp, Boolean) || ejsIs(ejs, vp, Number)) {
            return ejsToString(ejs, vp);
        } else if (json->regexp) {
            return ejsToString(ejs, vp);
        } else {
            return ejsToLiteralString(ejs, vp);
        }
    }
    obj = vp;
    json->nest++;
    if (json->buf == 0) {
        json->buf = mprCreateBuf(0, 0);
        mprAddRoot(json->buf);
    }
    isArray = ejsIs(ejs, vp, Array);
    mprPutCharToWideBuf(json->buf, isArray ? '[' : '{');
    if (json->pretty) {
        mprPutCharToWideBuf(json->buf, '\n');
    }
    if (++ejs->serializeDepth <= json->depth && !VISITED(obj)) {
        SET_VISITED(obj, 1);
        for (slotNum = 0; slotNum < count && !ejs->exception; slotNum++) {
            trait = ejsGetPropertyTraits(ejs, obj, slotNum);
            if (trait && (trait->attributes & (EJS_TRAIT_HIDDEN | EJS_TRAIT_DELETED | EJS_FUN_INITIALIZER | 
                    EJS_FUN_MODULE_INITIALIZER)) && !json->hidden) {
                continue;
            }
            pp = ejsGetProperty(ejs, obj, slotNum);
            if (ejs->exception) {
                SET_VISITED(obj, 0);
                json->nest--;
                return 0;
            }
            if (pp == 0) {
                continue;
            }
            if (isArray) {
                key = itos(slotNum);
                qname.name = ejsCreateStringFromAsc(ejs, key);
                qname.space = ESV(empty);
            } else {
                qname = ejsGetPropertyName(ejs, vp, slotNum);
            }

            quotes = json->quotes;
            if (!quotes) {
                //  UNICODE
                for (cp = qname.name->value; cp < &qname.name->value[qname.name->length]; cp++) {
                    if (!isalnum((uchar) *cp) && *cp != '_') {
                        quotes = 1;
                        break;
                    }
                }
            }
            if (json->pretty) {
                for (i = 0; i < ejs->serializeDepth; i++) {
                    mprPutStringToWideBuf(json->buf, json->indent);
                }
            }
            if (!isArray) {
                if (json->namespaces) {
                    if (qname.space != ESV(empty)) {
                        mprPutToBuf(json->buf, "\"%@\"::", qname.space);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                for (cp = qname.name->value; cp && *cp; cp++) {
                    c = *cp;
                    if (c == '"' || c == '\\') {
                        mprPutCharToWideBuf(json->buf, '\\');
                        mprPutCharToWideBuf(json->buf, c);
                    } else {
                        mprPutCharToWideBuf(json->buf, c);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                mprPutCharToWideBuf(json->buf, ':');
                if (json->pretty) {
                    mprPutCharToWideBuf(json->buf, ' ');
                }
            }
            fn = (EjsFunction*) ejsGetPropertyByName(ejs, TYPE(pp)->prototype, N(NULL, "toJSON"));
            // OPT - check that this is going directly to serialize most of the time
            if (!ejsIsFunction(ejs, fn) || (fn->isNativeProc && fn->body.proc == (EjsProc) ejsObjToJSON)) {
                sv = serialize(ejs, pp, json);
            } else {
                sv = (EjsString*) ejsRunFunction(ejs, fn, pp, 1, &json->options);
            }
            if (sv == 0 || !ejsIs(ejs, sv, String)) {
                if (ejs->exception) {
                    ejsThrowTypeError(ejs, "Cannot serialize property %@", qname.name);
                    SET_VISITED(obj, 0);
                    return 0;
                }
            } else {
                if (json->replacer) {
                    replacerArgs[0] = (EjsObj*) qname.name; 
                    replacerArgs[1] = (EjsObj*) sv; 

                    /* function replacer(key: String, value: String): String */
                    sv = ejsRunFunction(ejs, json->replacer, obj, 2, (EjsObj**) replacerArgs);
                }
                mprPutBlockToBuf(json->buf, sv->value, sv->length * sizeof(wchar));
            }
            if ((slotNum + 1) < count || json->commas) {
                mprPutCharToWideBuf(json->buf, ',');
            }
            if (json->pretty) {
                mprPutCharToWideBuf(json->buf, '\n');
            }
        }
        SET_VISITED(obj, 0);
    }
    --ejs->serializeDepth; 
    if (json->pretty) {
        for (i = ejs->serializeDepth; i > 0; i--) {
            mprPutStringToWideBuf(json->buf, json->indent);
        }
    }
    mprPutCharToWideBuf(json->buf, isArray ? ']' : '}');
    mprAddNullToWideBuf(json->buf);

    if (--json->nest == 0) {
        result = ejsCreateString(ejs, mprGetBufStart(json->buf), mprGetBufLength(json->buf) / sizeof(wchar));
        mprRemoveRoot(json->buf);
    } else {
        result = 0;
    }
    return result;
}