Beispiel #1
0
  private static Object dereferenceArrayDims(
      Interp interp, // Current
      // interpreter.
      Object arrayObj, // Array to dereference. Must be an array.
      int numDerefDims, // Number of dimensions to dereference.
      TclObject indexListObj) // Index to dereference in each dim.
      throws TclException // May encounter bad array index or
        // dereference a null array value.
      {
    // Before derefencing any dimensions, check that the indexList isn't too
    // large--we want to return an array.

    int numDims = JavaInfoCmd.getNumDimsFromClass(arrayObj.getClass());
    if (numDims < numDerefDims) {
      throw new TclException(
          interp,
          "bad indexList \""
              + indexListObj.toString()
              + "\": javaObj only has "
              + numDims
              + " dimension(s)");
    }

    Object subArrayObj = arrayObj;
    for (int dim = 0; dim < numDerefDims - 1; dim++) {

      int index = TclInteger.getInt(interp, TclList.index(interp, indexListObj, dim));
      try {
        subArrayObj = Array.get(subArrayObj, index);
      } catch (ArrayIndexOutOfBoundsException e) {
        int max = Array.getLength(subArrayObj) - 1;
        throw new TclException(
            interp, "array index \"" + index + "\" is out of bounds: must be between 0 and " + max);
      }
      if (subArrayObj == null) {
        throw new TclException(
            interp,
            "null value in dimension " + dim + ": can't dereference " + numDims + " dimensions");
      }
    }
    return subArrayObj;
  }
Beispiel #2
0
  public void cmdProc(
      Interp interp, // Current interpreter.
      TclObject argv[]) // Argument list.
      throws TclException // If wrong number of args, a
        // standard Tcl exception;
        // If an exception is encountered
        // during the invokation of the method,
        // the Exception object will be stored
        // in the errorCode of the interp.
      {
    boolean convert;
    int optionIdx, numArgs;
    Object subArrayObj;
    Class subArrayClass;
    int option, index, numDims, count;
    TclObject indexListObj;

    if (argv.length < 2) {
      throw new TclNumArgsException(interp, 1, argv, "?-noconvert? option ?arg arg ...?");
    }

    String arg1 = argv[1].toString();
    if ((arg1.length() >= 2) && (NOCONVERT.startsWith(arg1))) {
      // numArgs is the number of optional arguments after the
      // sub-command.

      convert = false;
      optionIdx = 2;
      numArgs = argv.length - 3;
    } else {
      convert = true;
      optionIdx = 1;
      numArgs = argv.length - 2;
    }

    if (numArgs < 0) {
      throw new TclNumArgsException(interp, 1, argv, "?-noconvert? option ?arg arg ...?");
    }

    // If the <option> argument to the array object command is one of the
    // array sub-commands, then proceed to the switch statement below.
    // Otherwise, the array object behaves as a reflect object by calling
    // ReflectObject.cmdProc, and <option> will be treated as a method
    // of the array object.
    //
    // We can be sure that there is no conflect between the array
    // sub-commands and the method of the array object. This is
    // because the array object is an instance of java.lang.Object,
    // which has only the following methods (as of JDK 1.1): getClass,
    // hashCode, equals, wait, toString, notify, notifyAll

    try {
      option = TclIndex.get(interp, argv[optionIdx], validCmds, "option", TCL.EXACT);
    } catch (TclException e) {
      try {
        int startIdx = optionIdx + 1;

        FuncSig.get(
            interp, javaClass, argv[optionIdx], argv, startIdx, argv.length - startIdx, false);
      } catch (TclException e1) {
        throw new TclException(
            interp,
            "bad option \""
                + argv[optionIdx]
                + "\": must be length, get, getrange, "
                + "set, setrange, or a valid method signature");
      }

      super.cmdProc(interp, argv);
      return;
    }

    switch (option) {
      case OPT_LENGTH:
        if (numArgs != 0) {
          throw new TclNumArgsException(interp, optionIdx + 1, argv, "");
        }
        if (convert == false) {
          throw new TclException(
              interp, "-noconvert flag not allowed for the \"length\" sub-command");
        }
        interp.setResult(Array.getLength(javaObj));
        return;

      case OPT_GET:
        if (numArgs != 1) {
          throw new TclNumArgsException(interp, optionIdx + 1, argv, "indexList");
        }
        indexListObj = argv[optionIdx + 1];
        numDims = TclList.getLength(interp, indexListObj);
        if (numDims == 0) {
          subArrayObj = javaObj;
          subArrayClass = dereferenceClassDims(interp, javaClass, 1);
          index = 0;
        } else {
          // Dereference all but the last dimension specified. Set
          // the interpreter result to the index'th element of the
          // "subArrayObj".

          subArrayObj = dereferenceArrayDims(interp, javaObj, numDims, indexListObj);
          subArrayClass = dereferenceClassDims(interp, javaClass, numDims);
          index = TclInteger.getInt(interp, TclList.index(interp, indexListObj, numDims - 1));
        }

        // Set the interpreter result to a TclObject containing the index'th
        // element of "subArrayObj".

        interp.setResult(getArrayElt(interp, subArrayObj, subArrayClass, index, convert));
        return;

      case OPT_SET:
        if (numArgs != 2) {
          throw new TclNumArgsException(interp, optionIdx + 1, argv, "indexList value");
        }
        if (convert == false) {
          throw new TclException(interp, "-noconvert flag not allowed for the \"set\" sub-command");
        }

        indexListObj = argv[optionIdx + 1];
        numDims = TclList.getLength(interp, indexListObj);
        if (numDims == 0) {
          subArrayObj = javaObj;
          subArrayClass = dereferenceClassDims(interp, javaClass, 1);
          index = 0;
        } else {
          // Dereference all but the last dimension specified. Set
          // the value of index'th element of the "subArrayObj" to
          // the value in argv[optionIdx + 2].

          subArrayObj = dereferenceArrayDims(interp, javaObj, numDims, indexListObj);
          subArrayClass = dereferenceClassDims(interp, javaClass, numDims);
          index = TclInteger.getInt(interp, TclList.index(interp, indexListObj, numDims - 1));
        }

        // Set the value of the index'th element of "subArrayObj" to the
        // value
        // in the TclObject argv[optionIdx + 2].

        setArrayElt(interp, subArrayObj, subArrayClass, index, argv[optionIdx + 2]);
        interp.resetResult();
        return;

      case OPT_GETRANGE:
        if (numArgs > 2) {
          throw new TclNumArgsException(interp, optionIdx + 1, argv, "?indexList ?count??");
        }

        // If an index list is specified, dereference all but the last
        // dimension specified. If the index list is empty, getrange
        // behaves as an identity function and returns argv[0].

        subArrayObj = javaObj;
        subArrayClass = dereferenceClassDims(interp, javaClass, 1);
        index = 0;

        if (numArgs > 0) {
          indexListObj = argv[optionIdx + 1];
          numDims = TclList.getLength(interp, indexListObj);
          if (numDims > 0) {
            subArrayObj = dereferenceArrayDims(interp, javaObj, numDims, indexListObj);
            subArrayClass = dereferenceClassDims(interp, javaClass, numDims);
            index = TclInteger.getInt(interp, TclList.index(interp, indexListObj, numDims - 1));
          }
        }

        // The variable "count" represents the number of elements to
        // return. The default is the array size less the first index
        // (the remaining elements of the array). If a count is
        // specified and is smaller than the default, the default is
        // overridden.

        count = Array.getLength(subArrayObj) - index;
        if (numArgs > 1) {
          count = Math.min(count, TclInteger.getInt(interp, argv[optionIdx + 2]));
        }

        // Set the interpreter result to a TclList containing "count"
        // elements
        // of the "subArrayObj", starting with the index'th element.

        interp.setResult(getArrayElts(interp, subArrayObj, subArrayClass, index, count, convert));
        return;

      case OPT_SETRANGE:
        if ((numArgs < 1) || (numArgs > 3)) {
          throw new TclNumArgsException(
              interp, optionIdx + 1, argv, "?indexList ?count?? valueList");
        }
        if (convert == false) {
          throw new TclException(
              interp, "-noconvert flag not allowed for the \"setrange\" sub-command");
        }

        TclObject tclValueListObj = argv[argv.length - 1];

        // If an index list is specified, dereference all but the last
        // dimension specified. If the index list is empty, setrange
        // initialized the array object as it would in the java::new
        // command.

        subArrayObj = javaObj;
        subArrayClass = dereferenceClassDims(interp, javaClass, 1);
        index = 0;

        if (numArgs > 1) {
          indexListObj = argv[optionIdx + 1];
          numDims = TclList.getLength(interp, indexListObj);
          if (numDims > 0) {
            subArrayObj = dereferenceArrayDims(interp, javaObj, numDims, indexListObj);
            subArrayClass = dereferenceClassDims(interp, javaClass, numDims);
            index = TclInteger.getInt(interp, TclList.index(interp, indexListObj, numDims - 1));
          }
        }

        // "count" represents the number of elements to set. The
        // default is the minimum of the valueList size and array size
        // less the first index (the remaining elements of the array).
        // If a count is specified and is smaller than the default,
        // the default is overridden.

        count =
            Math.min(
                TclList.getLength(interp, tclValueListObj), Array.getLength(subArrayObj) - index);

        if (numArgs > 2) {
          count = Math.min(count, TclInteger.getInt(interp, argv[optionIdx + 2]));
        }

        // Set the value of "count" elements of the "subArrayObj", starting
        // with the index'th element, to the values in tclValueListObj.

        setArrayElts(interp, subArrayObj, subArrayClass, index, count, tclValueListObj);
        interp.resetResult();
        return;
    }
  }
Beispiel #3
0
  static Object initArray(
      Interp interp, // Current interpreter.
      TclObject sizeListObj, // List of dimension sizes.
      int sizeListLen, // Size of sizeListObj.
      int dim, // Current dimension.
      int numDims, // Number of dimensions to allocate.
      Class cls, // Type of Array.
      TclObject valueListObj) // List to populate the Array.
      throws TclException // May encounter TclList elt of wrong
        // type in sizeListObj or valueListObj.
      {
    Class compCls = cls.getComponentType();
    int valueListLen = 0;
    if (valueListObj != null) {
      valueListLen = TclList.getLength(interp, valueListObj);
    }

    // Set arrayLength to be the dim'th dimension size in sizeListObj. If
    // sizeListObj doesn't contain dim elts, the array length is the length
    // of valueListObj.
    //
    // Initialize the "arrayObj" to size "arrayLength".

    int arrayLength;
    if (dim < sizeListLen) {
      arrayLength = TclInteger.getInt(interp, TclList.index(interp, sizeListObj, dim));
    } else {
      arrayLength = valueListLen;
    }
    if ((arrayLength == 0) && (dim < (numDims - 1))) {
      throw new TclException(
          interp,
          "cannot initialize a "
              + numDims
              + " dimensional array with zero size in dimension "
              + dim);
    }

    Object arrayObj;
    try {
      arrayObj = Array.newInstance(compCls, arrayLength);
    } catch (NegativeArraySizeException ex) {
      throw new TclException(interp, "negative array size " + arrayLength);
    }

    if (compCls.isArray()) {
      // Initialize each subArray "i" according to the dim+1'st elt in
      // sizeListObj and i'th elt in valueListObj.

      int nextDim = dim + 1;
      for (int i = 0; i < arrayLength; i++) {

        TclObject subValueListObj = null;
        if (i < valueListLen) {
          subValueListObj = TclList.index(interp, valueListObj, i);
        }

        Object subArrayObj =
            initArray(interp, sizeListObj, sizeListLen, nextDim, numDims, compCls, subValueListObj);
        Array.set(arrayObj, i, subArrayObj);
      }
    } else if (valueListLen > 0) {
      // Set the value of "count" elements of the "subArrayObj", starting
      // with the 0'th element, to the values in valueListObj.

      int count = Math.min(arrayLength, valueListLen);
      setArrayElts(interp, arrayObj, compCls, 0, count, valueListObj);
    }
    return arrayObj;
  }