lib/tcl-duktape.c
/*
 * Convert Tcl item to a JavaScript item
 */
Convert Tcl item to a JavaScript item
Convert Tcl item to a JavaScript item
static duk_idx_t Tclduk_TclToJS(Tcl_Interp *interp, Tcl_Obj *value, duk_context *ctx, const char *type) {
    Tcl_Obj *typeObj, *firstTypeObj, *itemObj;
    char *firstTypeString, *otherTypesString;
    const char *valueString;
    unsigned int type_hash;
    enum {
        TCLDUK_TYPE_BOOLEAN,
        TCLDUK_TYPE_BYTEARRAY,
        TCLDUK_TYPE_STRING,
        TCLDUK_TYPE_UNDEFINED,
        TCLDUK_TYPE_NULL,
        TCLDUK_TYPE_DOUBLE,
        TCLDUK_TYPE_INTEGER,
        TCLDUK_TYPE_BIGINT,
        TCLDUK_TYPE_ARRAY,
        TCLDUK_TYPE_JSON
    } string_format;
    double valueDouble;
    duk_idx_t checkRet;
    int valueBoolean;
    int valueStringLength, firstTypeStringLength;
    int idx, numItems;
    int tclRet;
    if (!type) {
        type = "string";
    }
    typeObj = Tcl_NewStringObj(type, -1);
    tclRet = Tcl_ListObjIndex(NULL, typeObj, 0, &firstTypeObj);
    if (tclRet != TCL_OK || !firstTypeObj) {
        firstTypeObj = typeObj;
    }
    firstTypeString = Tcl_GetStringFromObj(firstTypeObj, &firstTypeStringLength);
    type_hash = Tcl_ZlibCRC32(0, (const unsigned char *) firstTypeString, firstTypeStringLength);
    switch (type_hash) {
        case 0x0: 
        case 0x9ebeb2a9: 
            string_format = TCLDUK_TYPE_STRING;
            break;
        case 0x8a858868: 
            string_format = TCLDUK_TYPE_BOOLEAN;
            break;
        case 0xb3444c: 
            string_format = TCLDUK_TYPE_BYTEARRAY;
            break;
        case 0xfedc304f: 
            string_format = TCLDUK_TYPE_UNDEFINED;
            break;
        case 0x25cbfc4f: 
            string_format = TCLDUK_TYPE_NULL;
            break;
        case 0xdae7f2ef: 
            string_format = TCLDUK_TYPE_DOUBLE;
            break;
        case 0x5a0fab0b: 
            string_format = TCLDUK_TYPE_INTEGER;
            break;
        case 0x2d3dd6d7: 
            string_format = TCLDUK_TYPE_BIGINT;
            break;
        case 0xa10ceeb7: 
            string_format = TCLDUK_TYPE_ARRAY;
            break;
        case 0x6b072545: 
            string_format = TCLDUK_TYPE_JSON;
            break;
        default:
            duk_push_error_object(ctx, DUK_ERR_ERROR, ERROR_INVALID_TYPE, type);
            return(-1);
            break;
    }
    switch (string_format) {
        case TCLDUK_TYPE_UNDEFINED:
            return(0);
        case TCLDUK_TYPE_BOOLEAN:
            tclRet = Tcl_GetBooleanFromObj(NULL, value, &valueBoolean);
            if (tclRet != TCL_OK) {
                return(0);
            }
            duk_push_boolean(ctx, valueBoolean);
            return(1);
        case TCLDUK_TYPE_NULL:
            duk_push_null(ctx);
            return(1);
        case TCLDUK_TYPE_BYTEARRAY:
            valueString = (const char *) Tcl_GetByteArrayFromObj(value, &valueStringLength);
            duk_push_lstring(ctx, valueString, valueStringLength);
            duk_to_buffer(ctx, -1, NULL);
            return(1);
        case TCLDUK_TYPE_BIGINT:
        case TCLDUK_TYPE_STRING:
        case TCLDUK_TYPE_JSON:
            valueString = Tcl_GetStringFromObj(value, &valueStringLength);
            duk_push_lstring(ctx, valueString, valueStringLength);
            if (string_format == TCLDUK_TYPE_JSON) {
                duk_json_decode(ctx, -1);
            }
            return(1);
        case TCLDUK_TYPE_DOUBLE:
        case TCLDUK_TYPE_INTEGER:
            tclRet = Tcl_GetDoubleFromObj(NULL, value, &valueDouble);
            if (tclRet != TCL_OK) {
                return(0);
            }
            if (valueDouble != valueDouble) {
                duk_push_nan(ctx);
            } else {
                duk_push_number(ctx, valueDouble);
            }
            return(1);
        case TCLDUK_TYPE_ARRAY:
            tclRet = Tcl_ListObjReplace(NULL, typeObj, 0, 1, 0, NULL);
            otherTypesString = Tcl_GetStringFromObj(typeObj, NULL);
            tclRet = Tcl_ListObjLength(NULL, value, &numItems);
            if (tclRet != TCL_OK) {
                duk_push_null(ctx);
                return(1);
            }
            duk_push_array(ctx);
            for (idx = 0; idx < numItems; idx++) {
                tclRet = Tcl_ListObjIndex(NULL, value, idx, &itemObj);
                if (tclRet != TCL_OK) {
                    duk_push_null(ctx);
                } else {
                    checkRet = Tclduk_TclToJS(interp, itemObj, ctx, otherTypesString);
                    if (checkRet == 0) {
                        duk_push_null(ctx);
                    } else if (checkRet != 1) {
                    }
                }
                duk_put_prop_index(ctx, -2, idx);
            }
            return(1);
    }
    return(0);
}
static duk_idx_t Tclduk_TclToJS ( Tcl_Interp * interp , Tcl_Obj * value , duk_context * ctx , const char * type ) { Tcl_Obj * typeObj , * firstTypeObj , * itemObj ; char * firstTypeString , * otherTypesString ; const char * valueString ; unsigned int type_hash ; enum { TCLDUK_TYPE_BOOLEAN , TCLDUK_TYPE_BYTEARRAY , TCLDUK_TYPE_STRING , TCLDUK_TYPE_UNDEFINED , TCLDUK_TYPE_NULL , TCLDUK_TYPE_DOUBLE , TCLDUK_TYPE_INTEGER , TCLDUK_TYPE_BIGINT , TCLDUK_TYPE_ARRAY , TCLDUK_TYPE_JSON } string_format ; double valueDouble ; duk_idx_t checkRet ; int valueBoolean ; int valueStringLength , firstTypeStringLength ; int idx , numItems ; int tclRet ; if ( ! type ) { type = " " ; } typeObj = Tcl_NewStringObj ( type , -1 ) ; tclRet = Tcl_ListObjIndex ( NULL , typeObj , 0 , & firstTypeObj ) ; if ( tclRet != TCL_OK || ! firstTypeObj ) { firstTypeObj = typeObj ; } firstTypeString = Tcl_GetStringFromObj ( firstTypeObj , & firstTypeStringLength ) ; type_hash = Tcl_ZlibCRC32 ( 0 , ( const unsigned char * ) firstTypeString , firstTypeStringLength ) ; switch ( type_hash ) { case 0x0 : case 0x9ebeb2a9 : string_format = TCLDUK_TYPE_STRING ; break ; case 0x8a858868 : string_format = TCLDUK_TYPE_BOOLEAN ; break ; case 0xb3444c : string_format = TCLDUK_TYPE_BYTEARRAY ; break ; case 0xfedc304f : string_format = TCLDUK_TYPE_UNDEFINED ; break ; case 0x25cbfc4f : string_format = TCLDUK_TYPE_NULL ; break ; case 0xdae7f2ef : string_format = TCLDUK_TYPE_DOUBLE ; break ; case 0x5a0fab0b : string_format = TCLDUK_TYPE_INTEGER ; break ; case 0x2d3dd6d7 : string_format = TCLDUK_TYPE_BIGINT ; break ; case 0xa10ceeb7 : string_format = TCLDUK_TYPE_ARRAY ; break ; case 0x6b072545 : string_format = TCLDUK_TYPE_JSON ; break ; default : duk_push_error_object ( ctx , DUK_ERR_ERROR , ERROR_INVALID_TYPE , type ) ; return ( -1 ) ; break ; } switch ( string_format ) { case TCLDUK_TYPE_UNDEFINED : return ( 0 ) ; case TCLDUK_TYPE_BOOLEAN : tclRet = Tcl_GetBooleanFromObj ( NULL , value , & valueBoolean ) ; if ( tclRet != TCL_OK ) { return ( 0 ) ; } duk_push_boolean ( ctx , valueBoolean ) ; return ( 1 ) ; case TCLDUK_TYPE_NULL : duk_push_null ( ctx ) ; return ( 1 ) ; case TCLDUK_TYPE_BYTEARRAY : valueString = ( const char * ) Tcl_GetByteArrayFromObj ( value , & valueStringLength ) ; duk_push_lstring ( ctx , valueString , valueStringLength ) ; duk_to_buffer ( ctx , -1 , NULL ) ; return ( 1 ) ; case TCLDUK_TYPE_BIGINT : case TCLDUK_TYPE_STRING : case TCLDUK_TYPE_JSON : valueString = Tcl_GetStringFromObj ( value , & valueStringLength ) ; duk_push_lstring ( ctx , valueString , valueStringLength ) ; if ( string_format == TCLDUK_TYPE_JSON ) { duk_json_decode ( ctx , -1 ) ; } return ( 1 ) ; case TCLDUK_TYPE_DOUBLE : case TCLDUK_TYPE_INTEGER : tclRet = Tcl_GetDoubleFromObj ( NULL , value , & valueDouble ) ; if ( tclRet != TCL_OK ) { return ( 0 ) ; } if ( valueDouble != valueDouble ) { duk_push_nan ( ctx ) ; } else { duk_push_number ( ctx , valueDouble ) ; } return ( 1 ) ; case TCLDUK_TYPE_ARRAY : tclRet = Tcl_ListObjReplace ( NULL , typeObj , 0 , 1 , 0 , NULL ) ; otherTypesString = Tcl_GetStringFromObj ( typeObj , NULL ) ; tclRet = Tcl_ListObjLength ( NULL , value , & numItems ) ; if ( tclRet != TCL_OK ) { duk_push_null ( ctx ) ; return ( 1 ) ; } duk_push_array ( ctx ) ; for ( idx = 0 ; idx < numItems ; idx ++ ) { tclRet = Tcl_ListObjIndex ( NULL , value , idx , & itemObj ) ; if ( tclRet != TCL_OK ) { duk_push_null ( ctx ) ; } else { checkRet = Tclduk_TclToJS ( interp , itemObj , ctx , otherTypesString ) ; if ( checkRet == 0 ) { duk_push_null ( ctx ) ; } else if ( checkRet != 1 ) { } } duk_put_prop_index ( ctx , -2 , idx ) ; } return ( 1 ) ; } return ( 0 ) ; }
Convert Tcl item to a JavaScript item
Convert Tcl item to a JavaScript item
/*
     * If the return type is ignored, return without bothering
     * fetch the result
     */ /* (empty string) */ /* string */ /* boolean */ /* bytearray */ /* undefined */ /* null */ /* double */ /* integer */ /* bigint */ /* array */ /* json */ /* If JSON is being pushed, convert to an object */ /*
             * Remove the first item from the list of types
             */ /*
             * For each item in the list, format using this
             * function
             */ /* XXX:TODO: Handle this ? */