Exemple #1
0
static int
rcOutput (ClientData cd_, const char* buf, int toWrite, int* errorCodePtr)
{
  ReflectingChannel* chan = (ReflectingChannel*) cd_;
  int n = -1;

  if (chan->_validMask & TCL_WRITABLE) {
    Tcl_SavedResult sr;
    Tcl_Obj* cmd = rcBuildCmdList(chan, chan->_write);
    Tcl_Interp* ip = chan->_interp;

    Tcl_ListObjAppendElement(NULL, cmd,
	      		Tcl_NewByteArrayObj((unsigned char*) buf, toWrite));
    Tcl_SaveResult(ip, &sr);

    if (Tcl_EvalObjEx(ip, cmd, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT) == TCL_OK &&
      	Tcl_GetIntFromObj(NULL, Tcl_GetObjResult(ip), &n) == TCL_OK)
      if (0 <= n && n <= toWrite)
      	chan->_watchMask = chan->_validMask;
      else
      	n = -1;

    Tcl_RestoreResult(ip, &sr);
    Tcl_DecrRefCount(cmd);
  }

  if (n < 0)
    *errorCodePtr = EINVAL;
  return n;
}
Exemple #2
0
static int
Ta4r_Bytes_Cmd (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
	int nbytes;
	Tcl_Obj *o;
	unsigned char *buf;

	if (objc != 2) {
		Tcl_WrongNumArgs(interp, 1, objv, "nbytes");
		return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[1], &nbytes) != TCL_OK) {
		return TCL_ERROR;
	}
	if (nbytes < 1) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad value \"%d\" for nbytes: must be > 0", nbytes));
		return TCL_ERROR;
	}

	o = Tcl_NewByteArrayObj(NULL, 0);
	Tcl_IncrRefCount(o);
	buf = Tcl_SetByteArrayLength(o, nbytes);

	arc4random_buf(buf, nbytes);

	Tcl_SetObjResult(interp, o);
	Tcl_DecrRefCount(o);

	return TCL_OK;
}
Exemple #3
0
static int
StringWritePPM(
    Tcl_Interp *interp,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;

    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);

    /*
     * Construct a byte array of the right size with the header and
     * get a pointer to the data part of it.
     */

    size = strlen(header);
    byteArrayObj = Tcl_NewByteArrayObj((unsigned char *)header, size);
    byteArray = Tcl_SetByteArrayLength(byteArrayObj,
	    size + 3*blockPtr->width*blockPtr->height);
    byteArray += size;

    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    /*
     * Check if we can do the data move in single action.
     */

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {
	memcpy(byteArray, pixLinePtr,
		(unsigned)blockPtr->height * blockPtr->pitch);
    } else {
	for (h = blockPtr->height; h > 0; h--) {
	    unsigned char *pixelPtr = pixLinePtr;

	    for (w = blockPtr->width; w > 0; w--) {
		*byteArray++ = pixelPtr[0];
		*byteArray++ = pixelPtr[greenOffset];
		*byteArray++ = pixelPtr[blueOffset];
		pixelPtr += blockPtr->pixelSize;
	    }
	    pixLinePtr += blockPtr->pitch;
	}
    }

    /*
     * Return the object in the interpreter result.
     */

    Tcl_SetObjResult(interp, byteArrayObj);
    return TCL_OK;
}
Exemple #4
0
int NS(ReadN) (NS_ARGS)
{
  SETUP_mqctx
  MQ_CBI val;
  MQ_SIZE len;
  CHECK_NOARGS
  ErrorMqToTclWithCheck(MqReadN(mqctx, &val, &len));
  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(val,len));
  RETURN_TCL
}
Exemple #5
0
SEXP RTcl_ObjFromRawVector(SEXP args)
{
    int count;
    Tcl_Obj *tclobj; 
    SEXP val; 

    val = CADR(args);

    count = length(val);
    tclobj = Tcl_NewByteArrayObj(RAW(val), count);

    return makeRTclObject(tclobj);
}
Exemple #6
0
int SaveToFile(Tcl_Interp * interp, CxImage * image, char * fileName, int Type) {

    Tcl_Channel chan = Tcl_OpenFileChannel(interp, fileName, "w", 0644);
    BYTE * FileData = NULL;
    long length = 0;

    if (chan == NULL)
        return FALSE;


    if (Type == CXIMAGE_FORMAT_UNKNOWN) {
        Type = GetFileTypeFromFileName((char *)fileName);
    }

    if (Type == CXIMAGE_FORMAT_UNKNOWN) {
        Type = CXIMAGE_FORMAT_GIF;
    }

    Tcl_SetChannelOption(interp, chan, "-encoding", "binary");
    Tcl_SetChannelOption(interp, chan, "-translation", "binary");


    if (!image->Encode(FileData, length, Type) ) {
        Tcl_AppendResult(interp, image->GetLastError(), NULL);
        return TCL_ERROR;
    }

    Tcl_WriteObj(chan, Tcl_NewByteArrayObj(FileData, length));

    image->FreeMemory(FileData);

    Tcl_ResetResult(interp);

    if (Tcl_Close(interp, chan) == TCL_ERROR)
        return FALSE;
    else
        return TRUE;

}
Exemple #7
0
static Tcl_Obj *ObjFromSqliteValue(sqlite3_value *sqlvalP, VTableDB *vtdbP)
{
    int   len;
    sqlite_int64 i64;

    /* The following uses the same call sequences for conversion
       as in the sqlite tclSqlFunc function. */
    switch (sqlite3_value_type(sqlvalP)) {
    case SQLITE_INTEGER:
        /* Ints are always 64 bit in sqlite3 values */
        i64 = sqlite3_value_int64(sqlvalP);
        if (i64 >= -2147483647 && i64 <= 2147483647)
            return Tcl_NewIntObj((int) i64);
        else
            return Tcl_NewWideIntObj(i64);

    case SQLITE_FLOAT:
        return Tcl_NewDoubleObj(sqlite3_value_double(sqlvalP));

    case SQLITE_BLOB:
        len = sqlite3_value_bytes(sqlvalP);
        return Tcl_NewByteArrayObj(sqlite3_value_blob(sqlvalP), len);
        
    case SQLITE_NULL:
        /*
         * Note we do not increment the ref count for nullObjP. The caller
         * has to be careful to not unref without doing a ref first else
         * vtdbP->nullObjP will be a dangling pointer with bad results.
         */
        return vtdbP->null_objP;

    case SQLITE_TEXT:
    default:
        len = sqlite3_value_bytes(sqlvalP);
        return Tcl_NewStringObj((char *)sqlite3_value_text(sqlvalP), len);
    }
}
Exemple #8
0
** object with the encoded representation of the string, including
** the NULL terminator.
*/
static int binarize(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int len;
  char *bytes;
  Tcl_Obj *pRet;
  assert(objc==2);

  bytes = Tcl_GetStringFromObj(objv[1], &len);
  pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1);
  Tcl_SetObjResult(interp, pRet);
  return TCL_OK;
}

/*
** Usage: test_value_overhead <repeat-count> <do-calls>.
**
** This routine is used to test the overhead of calls to
** sqlite3_value_text(), on a value that contains a UTF-8 string. The idea
** is to figure out whether or not it is a problem to use sqlite3_value
** structures with collation sequence functions.
**
** If <do-calls> is 0, then the calls to sqlite3_value_text() are not
** actually made.
*/
Exemple #9
0
void
Tcl_RegisterConfig(
    Tcl_Interp *interp,		/* Interpreter the configuration command is
				 * registered in. */
    const char *pkgName,	/* Name of the package registering the
				 * embedded configuration. ASCII, thus in
				 * UTF-8 too. */
    const Tcl_Config *configuration,	/* Embedded configuration. */
    const char *valEncoding)	/* Name of the encoding used to store the
				 * configuration values, ASCII, thus UTF-8. */
{
    Tcl_Obj *pDB, *pkgDict;
    Tcl_DString cmdName;
    const Tcl_Config *cfg;
    QCCD *cdPtr = ckalloc(sizeof(QCCD));

    cdPtr->interp = interp;
    if (valEncoding) {
	cdPtr->encoding = ckalloc(strlen(valEncoding)+1);
	strcpy(cdPtr->encoding, valEncoding);
    } else {
	cdPtr->encoding = NULL;
    }
    cdPtr->pkg = Tcl_NewStringObj(pkgName, -1);

    /*
     * Phase I: Adding the provided information to the internal database of
     * package meta data.
     *
     * Phase II: Create a command for querying this database, specific to the
     * package registering its configuration. This is the approved interface
     * in TIP 59. In the future a more general interface should be done, as
     * follow-up to TIP 59. Simply because our database is now general across
     * packages, and not a structure tied to one package.
     *
     * Note, the created command will have a reference through its clientdata.
     */

    Tcl_IncrRefCount(cdPtr->pkg);

    /*
     * For venc == NULL aka bogus encoding we skip the step setting up the
     * dictionaries visible at Tcl level. I.e. they are not filled
     */

    pDB = GetConfigDict(interp);

    /*
     * Retrieve package specific configuration...
     */

    if (Tcl_DictObjGet(interp, pDB, cdPtr->pkg, &pkgDict) != TCL_OK
	    || (pkgDict == NULL)) {
	pkgDict = Tcl_NewDictObj();
    } else if (Tcl_IsShared(pkgDict)) {
	pkgDict = Tcl_DuplicateObj(pkgDict);
    }

    /*
     * Extend the package configuration...
     * We cannot assume that the encodings are initialized, therefore
     * store the value as-is in a byte array. See Bug [9b2e636361].
     */

    for (cfg=configuration ; cfg->key!=NULL && cfg->key[0]!='\0' ; cfg++) {
	Tcl_DictObjPut(interp, pkgDict, Tcl_NewStringObj(cfg->key, -1),
		Tcl_NewByteArrayObj((unsigned char *)cfg->value, strlen(cfg->value)));
    }

    /*
     * Write the changes back into the overall database.
     */

    Tcl_DictObjPut(interp, pDB, cdPtr->pkg, pkgDict);

    /*
     * Now create the interface command for retrieval of the package
     * information.
     */

    Tcl_DStringInit(&cmdName);
    TclDStringAppendLiteral(&cmdName, "::");
    Tcl_DStringAppend(&cmdName, pkgName, -1);

    /*
     * The incomplete command name is the name of the namespace to place it
     * in.
     */

    if (Tcl_FindNamespace(interp, Tcl_DStringValue(&cmdName), NULL,
	    TCL_GLOBAL_ONLY) == NULL) {
	if (Tcl_CreateNamespace(interp, Tcl_DStringValue(&cmdName),
		NULL, NULL) == NULL) {
	    Tcl_Panic("%s.\n%s: %s",
		    Tcl_GetStringResult(interp), "Tcl_RegisterConfig",
		    "Unable to create namespace for package configuration.");
	}
    }

    TclDStringAppendLiteral(&cmdName, "::pkgconfig");

    if (Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName),
	    QueryConfigObjCmd, cdPtr, QueryConfigDelete) == NULL) {
	Tcl_Panic("%s: %s", "Tcl_RegisterConfig",
		"Unable to create query command for package configuration");
    }

    Tcl_DStringFree(&cmdName);
}
Exemple #10
0
int NS(ReadALL) (NS_ARGS)
{
  SETUP_mqctx
  Tcl_Obj *RET = Tcl_NewListObj(0,NULL);
  Tcl_Obj *OBJ;
  MQ_BUF buf;
  CHECK_NOARGS
  while (MqReadItemExists(mqctx)) {
    OBJ = NULL;
    MqReadU(mqctx, &buf);
    switch (buf->type) {
      case MQ_BYTT: {
	OBJ = Tcl_NewIntObj(buf->cur.A->Y);
	break;
      }
      case MQ_BOLT: {
	OBJ = Tcl_NewBooleanObj(buf->cur.A->O);
	break;
      }
      case MQ_SRTT: {
	OBJ = Tcl_NewIntObj(buf->cur.A->S);
	break;
      }
      case MQ_INTT: {
	OBJ = Tcl_NewIntObj(buf->cur.A->I);
	break;
      }
      case MQ_FLTT: {
	OBJ = Tcl_NewDoubleObj(buf->cur.A->F);
	break;
      }
      case MQ_WIDT: {
	OBJ = Tcl_NewWideIntObj(buf->cur.A->W);
	break;
      }
      case MQ_DBLT: {
	OBJ = Tcl_NewDoubleObj(buf->cur.A->D);
	break;
      }
      case MQ_BINT: {
	OBJ = Tcl_NewByteArrayObj(buf->cur.B,buf->cursize);
	break;
      }
      case MQ_STRT: {
	OBJ = Tcl_NewStringObj(buf->cur.C,-1);
	break;
      }
      case MQ_LSTT: {
	MqReadL_START(mqctx, buf);
	NS(ReadALL)(interp, tclctx, skip, objc, objv);
	MqReadL_END(mqctx);
	OBJ = Tcl_GetObjResult(interp);
	break;
      }
      case MQ_TRAT: {
	break;
      }
    }
    if (OBJ != NULL) Tcl_ListObjAppendElement(interp, RET, OBJ);
  }
  Tcl_SetObjResult(interp, RET);
  RETURN_TCL
}
Exemple #11
0
int
mongotcl_bsontoarray_raw (Tcl_Interp *interp, char *arrayName, char *typeArrayName, const char *data , int depth) {
    bson_iterator i;
    const char *key;
    bson_timestamp_t ts;
    char oidhex[25];
	Tcl_Obj *obj;
	char *type;

	if (data == NULL) {
		return TCL_OK;
	}

    bson_iterator_from_buffer(&i, data);

    while (bson_iterator_next (&i)) {
        bson_type t = bson_iterator_type (&i);
        if (t == 0) {
            break;
		}

        key = bson_iterator_key (&i);

        switch (t) {
			case BSON_DOUBLE: {
				obj = Tcl_NewDoubleObj (bson_iterator_double (&i));
				type = "double";
				break;
		}

			case BSON_SYMBOL: {
				obj = Tcl_NewStringObj (bson_iterator_string (&i), -1);
				type = "symbol";
				break;
			}

			case BSON_STRING: {
				obj = Tcl_NewStringObj (bson_iterator_string (&i), -1);
				type = "string";
				break;
			}

			case BSON_OID: {
				bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
				obj = Tcl_NewStringObj (oidhex, -1);
				type = "oid";
				break;
			}

			case BSON_BOOL: {
				obj = Tcl_NewBooleanObj (bson_iterator_bool (&i));
				type = "bool";
				break;
			}

			case BSON_DATE: {
				obj = Tcl_NewLongObj ((long) bson_iterator_date(&i));
				type = "date";
				break;
			}

			case BSON_BINDATA: {
				unsigned char *bindata = (unsigned char *)bson_iterator_bin_data (&i);
				int binlen = bson_iterator_bin_len (&i);

				obj = Tcl_NewByteArrayObj (bindata, binlen);
				type = "bin";
				break;
			}

			case BSON_UNDEFINED: {
				obj = Tcl_NewObj ();
				type = "undefined";
				break;
			}

			case BSON_NULL: {
				obj = Tcl_NewObj ();
				type = "null";
				break;
			}

			case BSON_REGEX: {
				obj = Tcl_NewStringObj (bson_iterator_regex (&i), -1);
				type = "regex";
				break;
			}

			case BSON_CODE: {
				obj = Tcl_NewStringObj (bson_iterator_code (&i), -1);
				type = "code";
				break;
			}

			case BSON_CODEWSCOPE: {
				// bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
				/* bson_init( &scope ); */ /* review - stepped on by bson_iterator_code_scope? */
				// bson_iterator_code_scope( &i, &scope );
				// bson_printf( "\n\t SCOPE: " );
				// bson_print( &scope );
				/* bson_destroy( &scope ); */ /* review - causes free error */
				break;
			}

			case BSON_INT: {
				obj = Tcl_NewIntObj (bson_iterator_int (&i));
				type = "int";
				break;
			}

			case BSON_LONG: {
				obj = Tcl_NewLongObj ((uint64_t)bson_iterator_long (&i));
				type = "long";
				break;
			}

			case BSON_TIMESTAMP: {
				char string[64];

				ts = bson_iterator_timestamp (&i);
				snprintf(string, sizeof(string), "%d:%d", ts.i, ts.t);
				obj = Tcl_NewStringObj (bson_iterator_string (&i), -1);
				type = "timestamp";
				break;
			}

			case BSON_ARRAY: {
				obj = Tcl_NewObj();
				obj = mongotcl_bsontolist_raw (interp, obj, bson_iterator_value (&i), depth + 1);
				type = "array";

				break;
			}

			case BSON_OBJECT: {
				Tcl_Obj *subList = Tcl_NewObj ();

				obj = mongotcl_bsontolist_raw (interp, subList, bson_iterator_value (&i), depth + 1);
				type = "object";
				break;
			}

			default: {
				obj = Tcl_NewIntObj (t);
				type = "unknown";
				break;
			}
		}

		if (Tcl_SetVar2Ex (interp, arrayName, key, obj, TCL_LEAVE_ERR_MSG) == NULL) {
			return TCL_ERROR;
		}

		if (typeArrayName != NULL) {
			if (Tcl_SetVar2Ex (interp, typeArrayName, key, Tcl_NewStringObj (type, -1), TCL_LEAVE_ERR_MSG) == NULL) {
				return TCL_ERROR;
			}
		}
    }
	return TCL_OK; 
}
Exemple #12
0
Tcl_Obj *
mongotcl_bsontolist_raw (Tcl_Interp *interp, Tcl_Obj *listObj, const char *data , int depth) {
    bson_iterator i;
    const char *key;
    bson_timestamp_t ts;
    char oidhex[25];
    bson scope;

	if (data == NULL) {
		return listObj;
	}

    bson_iterator_from_buffer(&i, data);

    while (bson_iterator_next (&i)) {
        bson_type t = bson_iterator_type (&i);
        if (t == 0) {
            break;
		}

        key = bson_iterator_key (&i);

		switch (t) {
			case BSON_DOUBLE: {
				append_list_type_object (interp, listObj, "double", key, Tcl_NewDoubleObj (bson_iterator_double (&i)));
				break;
			}

			case BSON_STRING: {
				append_list_type_object (interp, listObj, "string", key, Tcl_NewStringObj (bson_iterator_string (&i), -1));
				break;
			}

			case BSON_SYMBOL: {
				append_list_type_object (interp, listObj, "symbol", key, Tcl_NewStringObj (bson_iterator_string (&i), -1));
				break;
			}

			case BSON_OID: {
				bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
				append_list_type_object (interp, listObj, "oid", key, Tcl_NewStringObj (oidhex, -1));
				break;
			}

			case BSON_BOOL: {
			append_list_type_object (interp, listObj, "bool", key, Tcl_NewBooleanObj (bson_iterator_bool (&i)));
				break;
			}

			case BSON_DATE: {
				append_list_type_object (interp, listObj, "date", key, Tcl_NewLongObj ((long) bson_iterator_date(&i)));
				break;
			}

			case BSON_BINDATA: {
				unsigned char *bindata = (unsigned char *)bson_iterator_bin_data (&i);
				int binlen = bson_iterator_bin_len (&i);

				append_list_type_object (interp, listObj, "bin", key, Tcl_NewByteArrayObj (bindata, binlen));
				break;
			}

			case BSON_UNDEFINED: {
				append_list_type_object (interp, listObj, "undefined", key, Tcl_NewObj ());
				break;
			}

			case BSON_NULL: {
				append_list_type_object (interp, listObj, "null", key, Tcl_NewObj ());
				break;
			}

			case BSON_REGEX: {
				append_list_type_object (interp, listObj, "regex", key, Tcl_NewStringObj (bson_iterator_regex (&i), -1));
				break;
			}

			case BSON_CODE: {
				append_list_type_object (interp, listObj, "code", key, Tcl_NewStringObj (bson_iterator_code (&i), -1));
				break;
			}

			case BSON_CODEWSCOPE: {
				bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
				/* bson_init( &scope ); */ /* review - stepped on by bson_iterator_code_scope? */
				bson_iterator_code_scope( &i, &scope );
				bson_printf( "\n\t SCOPE: " );
				bson_print( &scope );
				/* bson_destroy( &scope ); */ /* review - causes free error */
				break;
			}

			case BSON_INT: {
				append_list_type_object (interp, listObj, "int", key, Tcl_NewIntObj (bson_iterator_int (&i)));
				break;
			}

			case BSON_LONG: {
				append_list_type_object (interp, listObj, "long", key, Tcl_NewLongObj ((uint64_t)bson_iterator_long (&i)));
				break;
			}

			case BSON_TIMESTAMP: {
				char string[64];

				ts = bson_iterator_timestamp (&i);
				snprintf(string, sizeof(string), "%d:%d", ts.i, ts.t);
				append_list_type_object (interp, listObj, "timestamp", key, Tcl_NewStringObj (bson_iterator_string (&i), -1));
				break;
			}

			case BSON_ARRAY: {
				Tcl_Obj *subList = Tcl_NewObj ();

				subList = mongotcl_bsontolist_raw (interp, subList, bson_iterator_value (&i), depth + 1);
				append_list_type_object (interp, listObj, "array", key, subList);
				break;
			}

			case BSON_OBJECT: {
				Tcl_Obj *subList = Tcl_NewObj ();

				subList = mongotcl_bsontolist_raw (interp, subList, bson_iterator_value (&i), depth + 1);
				append_list_type_object (interp, listObj, "object", key, subList);
				break;
			}

			default: {
				append_list_type_object (interp, listObj, "unknown", key, Tcl_NewIntObj (t));
				break;
			}
		}
    }
    return listObj;
}
Exemple #13
0
static int
ExecuteCallback(
    TransformChannelData *dataPtr,
				/* Transformation with the callback. */
    Tcl_Interp *interp,		/* Current interpreter, possibly NULL. */
    unsigned char *op,		/* Operation invoking the callback. */
    unsigned char *buf,		/* Buffer to give to the script. */
    int bufLen,			/* And its length. */
    int transmit,		/* Flag, determines whether the result of the
				 * callback is sent to the underlying channel
				 * or not. */
    int preserve)		/* Flag. If true the procedure will preserve
				 * the result state of all accessed
				 * interpreters. */
{
    Tcl_Obj *resObj;		/* See below, switch (transmit). */
    int resLen;
    unsigned char *resBuf;
    Tcl_InterpState state = NULL;
    int res = TCL_OK;
    Tcl_Obj *command = TclListObjCopy(NULL, dataPtr->command);
    Tcl_Interp *eval = dataPtr->interp;

    Tcl_Preserve(eval);

    /*
     * Step 1, create the complete command to execute. Do this by appending
     * operation and buffer to operate upon to a copy of the callback
     * definition. We *cannot* create a list containing 3 objects and then use
     * 'Tcl_EvalObjv', because the command may contain additional prefixed
     * arguments. Feather's curried commands would come in handy here.
     */

    if (preserve == P_PRESERVE) {
	state = Tcl_SaveInterpState(eval, res);
    }

    Tcl_IncrRefCount(command);
    Tcl_ListObjAppendElement(NULL, command, Tcl_NewStringObj((char *) op, -1));

    /*
     * Use a byte-array to prevent the misinterpretation of binary data coming
     * through as UTF while at the tcl level.
     */

    Tcl_ListObjAppendElement(NULL, command, Tcl_NewByteArrayObj(buf, bufLen));

    /*
     * Step 2, execute the command at the global level of the interpreter used
     * to create the transformation. Destroy the command afterward. If an
     * error occured and the current interpreter is defined and not equal to
     * the interpreter for the callback, then copy the error message into
     * current interpreter. Don't copy if in preservation mode.
     */

    res = Tcl_EvalObjEx(eval, command, TCL_EVAL_GLOBAL);
    Tcl_DecrRefCount(command);
    command = NULL;

    if ((res != TCL_OK) && (interp != NULL) && (eval != interp)
	    && (preserve == P_NO_PRESERVE)) {
	Tcl_SetObjResult(interp, Tcl_GetObjResult(eval));
	Tcl_Release(eval);
	return res;
    }

    /*
     * Step 3, transmit a possible conversion result to the underlying
     * channel, or ourselves.
     */

    switch (transmit) {
    case TRANSMIT_DONT:
	/* nothing to do */
	break;

    case TRANSMIT_DOWN:
	if (dataPtr->self == NULL) {
	    break;
	}
	resObj = Tcl_GetObjResult(eval);
	resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
	Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf,
		resLen);
	break;

    case TRANSMIT_SELF:
	if (dataPtr->self == NULL) {
	    break;
	}
	resObj = Tcl_GetObjResult(eval);
	resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
	Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen);
	break;

    case TRANSMIT_IBUF:
	resObj = Tcl_GetObjResult(eval);
	resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
	ResultAdd(&dataPtr->result, resBuf, resLen);
	break;

    case TRANSMIT_NUM:
	/*
	 * Interpret result as integer number.
	 */

	resObj = Tcl_GetObjResult(eval);
	TclGetIntFromObj(eval, resObj, &dataPtr->maxRead);
	break;
    }

    Tcl_ResetResult(eval);
    if (preserve == P_PRESERVE) {
	(void) Tcl_RestoreInterpState(eval, state);
    }
    Tcl_Release(eval);
    return res;
}
Exemple #14
0
static Tcl_Obj *
convertFromSafeArray (
    SAFEARRAY *psa,
    VARTYPE elementType,
    unsigned dim,
    long *pIndices,
    const Type &type,
    Tcl_Interp *interp,
    int bytes)
{
    HRESULT hr;
    Tcl_Obj *pResult;

    if ( bytes ) {
	int dimsize ; 
        int length = 1 ; 
        for(int i = 0 ; i < psa->cDims ; ++i) { 
            dimsize = psa->cbElements * (psa->rgsabound[i].cElements);
            length *= dimsize; 
        } 

        unsigned char *pData;
        hr = SafeArrayAccessData(psa, reinterpret_cast<void **>(&pData));
        if (FAILED(hr)) {
            _com_issue_error(hr);
        }

        pResult = Tcl_NewByteArrayObj((unsigned char *)psa->pvData, length);

        hr = SafeArrayUnaccessData(psa);
        if (FAILED(hr)) {
            _com_issue_error(hr);
        }

	return pResult;
    }


    // Get index range.
    long lowerBound;
    hr = SafeArrayGetLBound(psa, dim, &lowerBound);
    if (FAILED(hr)) {
        _com_issue_error(hr);
    }

    long upperBound;
    hr = SafeArrayGetUBound(psa, dim, &upperBound);
    if (FAILED(hr)) {
        _com_issue_error(hr);
    }

    if (dim < SafeArrayGetDim(psa)) {
        // Create list of list for multi-dimensional array.
        pResult = Tcl_NewListObj(0, 0);
        for (long i = lowerBound; i <= upperBound; ++i) {
            pIndices[dim - 1] = i;
            Tcl_Obj *pElement = convertFromSafeArray(
                psa, elementType, dim + 1, pIndices, type, interp, 0);
            Tcl_ListObjAppendElement(interp, pResult, pElement);
        }
        return pResult;
    }

    if (elementType == VT_UI1 && SafeArrayGetDim(psa) == 1) {
        unsigned char *pData;
        hr = SafeArrayAccessData(psa, reinterpret_cast<void **>(&pData));
        if (FAILED(hr)) {
            _com_issue_error(hr);
        }

        long length = upperBound - lowerBound + 1;
        pResult =
#if TCL_MINOR_VERSION >= 1
            // Convert array of bytes to Tcl byte array.
            Tcl_NewByteArrayObj(pData, length);
#else
            // Convert array of bytes to Tcl string.
            Tcl_NewStringObj(reinterpret_cast<char *>(pData), length);
#endif

        hr = SafeArrayUnaccessData(psa);
        if (FAILED(hr)) {
            _com_issue_error(hr);
        }

    } else {
        // Create list of Tcl values.
        pResult = Tcl_NewListObj(0, 0);
        for (long i = lowerBound; i <= upperBound; ++i) {
            NativeValue elementVar;

            pIndices[dim - 1] = i;
            if (elementType == VT_VARIANT) {
                hr = SafeArrayGetElement(psa, pIndices, &elementVar);
            } else {
                // I hope the element can be contained in a VARIANT.
                V_VT(&elementVar) = elementType;
                hr = SafeArrayGetElement(psa, pIndices, &elementVar.punkVal);
            }
            if (FAILED(hr)) {
                _com_issue_error(hr);
            }

            TclObject element(&elementVar, type, interp, 0);
            Tcl_ListObjAppendElement(interp, pResult, element);
        }
    }

    return pResult;
}