Пример #1
0
 public static TclObject Tcl_NewByteArrayObj(string value, int bytes)
 {
     if (value == null || bytes == 0)
     {
         return(TclByteArray.NewInstance());
     }
     else
     {
         return(TclByteArray.NewInstance(System.Text.Encoding.UTF8.GetBytes(value.Substring(0, bytes))));
     }
 }
Пример #2
0
 public static TclObject Tcl_NewByteArrayObj(byte[] value, int bytes)
 {
     if (value == null || value.Length == 0 || bytes == 0)
     {
         return(TclByteArray.NewInstance());
     }
     else
     {
         return(TclByteArray.NewInstance(value, 0, bytes));
     }
 }
Пример #3
0
        /// <summary> This procedure is invoked to process the "read" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan;                // The channel being operated on this
            // method
            int       i      = 1;        // Index to the next arg in argv
            int       toRead = 0;        // Number of bytes or chars to read from channel
            int       charactersRead;    // Number of bytes or chars read from channel
            bool      readAll   = true;  // If true read-all else toRead
            bool      noNewline = false; // If true, strip the newline if there
            TclObject result;


            if ((argv.Length != 2) && (argv.Length != 3))
            {
                errorWrongNumArgs(interp, argv[0].ToString());
            }


            if (argv[i].ToString().Equals("-nonewline"))
            {
                noNewline = true;
                i++;
            }

            if (i == argv.Length)
            {
                errorWrongNumArgs(interp, argv[0].ToString());
            }


            chan = TclIO.getChannel(interp, argv[i].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[i].ToString() + "\"");
            }

            // Consumed channel name.

            i++;

            // Compute how many bytes or chars to read, and see whether the final
            // noNewline should be dropped.

            if (i < argv.Length)
            {
                string arg = argv[i].ToString();

                if (System.Char.IsDigit(arg[0]))
                {
                    toRead  = TclInteger.Get(interp, argv[i]);
                    readAll = false;
                }
                else if (arg.Equals("nonewline"))
                {
                    noNewline = true;
                }
                else
                {
                    throw new TclException(interp, "bad argument \"" + arg + "\": should be \"nonewline\"");
                }
            }

            try
            {
                if ((System.Object)chan.Encoding == null)
                {
                    result = TclByteArray.NewInstance();
                }
                else
                {
                    result = TclString.NewInstance(new StringBuilder(64));
                }
                if (readAll)
                {
                    charactersRead = chan.read(interp, result, TclIO.READ_ALL, 0);

                    // If -nonewline was specified, and we have not hit EOF
                    // and the last char is a "\n", then remove it and return.

                    if (noNewline)
                    {
                        string inStr = result.ToString();
                        if ((charactersRead > 0) && (inStr[charactersRead - 1] == '\n'))
                        {
                            interp.SetResult(inStr.Substring(0, ((charactersRead - 1)) - (0)));
                            return(TCL.CompletionCode.RETURN);
                        }
                    }
                }
                else
                {
                    // FIXME: Bug here, the -nonewline flag must be respected
                    // when reading a set number of bytes
                    charactersRead = chan.read(interp, result, TclIO.READ_N_BYTES, toRead);
                }

                /*
                 * // FIXME: Port this -nonewline logic from the C code.
                 * if (charactersRead < 0) {
                 * Tcl_ResetResult(interp);
                 * Tcl_AppendResult(interp, "error reading \"", name, "\": ",
                 * Tcl_PosixError(interp), (char *) NULL);
                 * Tcl_DecrRefCount(resultPtr);
                 * return TCL_ERROR;
                 * }
                 *
                 * // If requested, remove the last newline in the channel if at EOF.
                 *
                 * if ((charactersRead > 0) && (newline != 0)) {
                 * char *result;
                 * int length;
                 *
                 * result = Tcl_GetStringFromObj(resultPtr, length);
                 * if (result[length - 1] == '\n') {
                 * Tcl_SetObjLength(resultPtr, length - 1);
                 * }
                 * }
                 *
                 */

                interp.SetResult(result);
            }
            catch (IOException e)
            {
                throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName);
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #4
0
        /// <summary> This procedure is invoked to process the "encoding" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "option ?arg ...?");
            }

            int index = TclIndex.Get(interp, argv[1], validCmds, "option", 0);

            switch (index)
            {
            case OPT_CONVERTTO:
            case OPT_CONVERTFROM:
            {
                string    tclEncoding;
                Encoding  javaEncoding;
                TclObject data;

                if (argv.Length == 3)
                {
                    tclEncoding = systemTclEncoding;
                    data        = argv[2];
                }
                else if (argv.Length == 4)
                {
                    tclEncoding = argv[2].ToString();
                    data        = argv[3];
                }
                else
                {
                    throw new TclNumArgsException(interp, 2, argv, "?encoding? data");
                }

                javaEncoding = getJavaName(tclEncoding);

                if ((System.Object)javaEncoding == null)
                {
                    throw new TclException(interp, "unknown encoding \"" + tclEncoding + "\"");
                }

                try
                {
                    if (index == OPT_CONVERTFROM)
                    {
                        // Treat the string as binary data
                        byte[] bytes = TclByteArray.getBytes(interp, data);

                        // ATK
                        interp.SetResult(System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length));
                    }
                    else
                    {
                        // Store the result as binary data


                        // ATK byte[] bytes = data.ToString().getBytes(javaEncoding);
                        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data.ToString());
                        interp.SetResult(TclByteArray.NewInstance(bytes));
                    }
                }
                catch (IOException ex)
                {
                    throw new TclRuntimeError("Encoding.cmdProc() error: " + "unsupported java encoding \"" + javaEncoding + "\"");
                }

                break;
            }

            case OPT_NAMES:
            {
                if (argv.Length > 2)
                {
                    throw new TclNumArgsException(interp, 2, argv, null);
                }

                TclObject list = TclList.NewInstance();
                for (int i = 0; i < tclNames.Length; i++)
                {
                    TclList.Append(interp, list, TclString.NewInstance(tclNames[i]));
                }
                interp.SetResult(list);
                break;
            }

            case OPT_SYSTEM:
            {
                if (argv.Length > 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "?encoding?");
                }

                if (argv.Length == 2)
                {
                    interp.SetResult(systemTclEncoding);
                }
                else
                {
                    string   tclEncoding  = argv[2].ToString();
                    Encoding javaEncoding = getJavaName(tclEncoding);

                    if (javaEncoding == null)
                    {
                        throw new TclException(interp, "unknown encoding \"" + tclEncoding + "\"");
                    }

                    systemTclEncoding  = tclEncoding;
                    systemJavaEncoding = javaEncoding;
                }

                break;
            }

            default:
            {
                throw new TclRuntimeError("Encoding.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #5
0
        private const char FORMAT_END    = ' '; // End of format was found.

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int arg;                         // Index of next argument to consume.

            char[] format = null;            // User specified format string.
            char   cmd;                      // Current format character.
            int    cursor;                   // Current position within result buffer.
            int    maxPos;                   // Greatest position within result buffer that cursor has visited.
            int    value = 0;                // Current integer value to be packed.
            int    offset, size = 0, length; // Initialized to avoid compiler warning.

            if (argv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "option ?arg arg ...?");
            }
            int cmdIndex = TclIndex.Get(interp, argv[1], _validCmds, "option", 0);

            switch (cmdIndex)
            {
            case CMD_FORMAT:
            {
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "formatString ?arg arg ...?");
                }
                // To avoid copying the data, we format the string in two passes. The first pass computes the size of the output buffer.  The
                // second pass places the formatted data into the buffer.
                format = argv[2].ToString().ToCharArray();
                arg    = 3;
                length = 0;
                offset = 0;
                int parsePos = 0;
                while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END)
                {
                    int count = GetFormatCount(format, ref parsePos);
                    switch (cmd)
                    {
                    case 'a':
                    case 'A':
                    case 'b':
                    case 'B':
                    case 'h':
                    case 'H':
                    {
                        // For string-type specifiers, the count corresponds to the number of bytes in a single argument.
                        if (arg >= argv.Length)
                        {
                            MissingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = TclByteArray.getLength(interp, argv[arg]);
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        arg++;
                        switch (cmd)
                        {
                        case 'a':
                        case 'A':
                            offset += count;
                            break;

                        case 'b':
                        case 'B':
                            offset += (count + 7) / 8;
                            break;

                        case 'h':
                        case 'H':
                            offset += (count + 1) / 2;
                            break;
                        }
                        break;
                    }

                    case 'c':
                    case 's':
                    case 'S':
                    case 'i':
                    case 'I':
                    case 'f':
                    case 'd':
                    {
                        if (arg >= argv.Length)
                        {
                            MissingArg(interp);
                        }
                        switch (cmd)
                        {
                        case 'c':
                            size = 1;
                            break;

                        case 's':
                        case 'S':
                            size = 2;
                            break;

                        case 'i':
                        case 'I':
                            size = 4;
                            break;

                        case 'f':
                            size = 4;
                            break;

                        case 'd':
                            size = 8;
                            break;
                        }
                        // For number-type specifiers, the count corresponds to the number of elements in the list stored in
                        // a single argument.  If no count is specified, then the argument is taken as a single non-list value.
                        if (count == BINARY_NOCOUNT)
                        {
                            arg++;
                            count = 1;
                        }
                        else
                        {
                            int listc = TclList.getLength(interp, argv[arg++]);
                            if (count == BINARY_ALL)
                            {
                                count = listc;
                            }
                            else if (count > listc)
                            {
                                throw new TclException(interp, "number of elements in list" + " does not match count");
                            }
                        }
                        offset += count * size;
                        break;
                    }

                    case 'x':
                    {
                        if (count == BINARY_ALL)
                        {
                            throw new TclException(interp, "cannot use \"*\"" + " in format string with \"x\"");
                        }
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        offset += count;
                        break;
                    }

                    case 'X':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count > offset || count == BINARY_ALL)
                        {
                            count = offset;
                        }
                        if (offset > length)
                        {
                            length = offset;
                        }
                        offset -= count;
                        break;
                    }

                    case '@':
                    {
                        if (offset > length)
                        {
                            length = offset;
                        }
                        if (count == BINARY_ALL)
                        {
                            offset = length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            AlephWithoutCount(interp);
                        }
                        else
                        {
                            offset = count;
                        }
                        break;
                    }

                    default:
                    {
                        BadField(interp, cmd);
                    }
                    break;
                    }
                }
                if (offset > length)
                {
                    length = offset;
                }
                if (length == 0)
                {
                    return(TCL.CompletionCode.RETURN);
                }

                // Prepare the result object by preallocating the calculated number of bytes and filling with nulls.
                TclObject resultObj   = TclByteArray.NewInstance();
                byte[]    resultBytes = TclByteArray.SetLength(interp, resultObj, length);
                interp.SetResult(resultObj);
                // Pack the data into the result object.  Note that we can skip the error checking during this pass, since we have already parsed the string once.
                arg      = 3;
                cursor   = 0;
                maxPos   = cursor;
                parsePos = 0;
                while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END)
                {
                    int count = GetFormatCount(format, ref parsePos);
                    if (count == 0 && cmd != '@')
                    {
                        arg++;
                        continue;
                    }
                    switch (cmd)
                    {
                    case 'a':
                    case 'A':
                    {
                        byte   pad   = (cmd == 'a' ? (byte)0 : (byte)SupportClass.Identity(' '));
                        byte[] bytes = TclByteArray.getBytes(interp, argv[arg++]);
                        length = bytes.Length;
                        if (count == BINARY_ALL)
                        {
                            count = length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (length >= count)
                        {
                            Array.Copy(bytes, 0, resultBytes, cursor, count);
                        }
                        else
                        {
                            Array.Copy(bytes, 0, resultBytes, cursor, length);
                            for (int ix = 0; ix < count - length; ix++)
                            {
                                resultBytes[cursor + length + ix] = pad;
                            }
                        }
                        cursor += count;
                        break;
                    }

                    case 'b':
                    case 'B':
                    {
                        char[] str = argv[arg++].ToString().ToCharArray();
                        if (count == BINARY_ALL)
                        {
                            count = str.Length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        int last = cursor + ((count + 7) / 8);
                        if (count > str.Length)
                        {
                            count = str.Length;
                        }
                        if (cmd == 'B')
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value <<= 1;
                                if (str[offset] == '1')
                                {
                                    value |= 1;
                                }
                                else if (str[offset] != '0')
                                {
                                    ExpectedButGot(interp, "binary", new string(str));
                                }
                                if (((offset + 1) % 8) == 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        else
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value >>= 1;
                                if (str[offset] == '1')
                                {
                                    value |= 128;
                                }
                                else if (str[offset] != '0')
                                {
                                    ExpectedButGot(interp, "binary", new string(str));
                                }
                                if (((offset + 1) % 8) == 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        if ((offset % 8) != 0)
                        {
                            if (cmd == 'B')
                            {
                                value <<= 8 - (offset % 8);
                            }
                            else
                            {
                                value >>= 8 - (offset % 8);
                            }
                            resultBytes[cursor++] = (byte)value;
                        }
                        while (cursor < last)
                        {
                            resultBytes[cursor++] = 0;
                        }
                        break;
                    }

                    case 'h':
                    case 'H':
                    {
                        char[] str = argv[arg++].ToString().ToCharArray();
                        if (count == BINARY_ALL)
                        {
                            count = str.Length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        int last = cursor + ((count + 1) / 2);
                        if (count > str.Length)
                        {
                            count = str.Length;
                        }
                        if (cmd == 'H')
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value <<= 4;
                                int c = HEXDIGITS.IndexOf(Char.ToLower(str[offset]));
                                if (c < 0)
                                {
                                    ExpectedButGot(interp, "hexadecimal", new string(str));
                                }
                                value |= (c & 0xf);
                                if ((offset % 2) != 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        else
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value >>= 4;
                                int c = HEXDIGITS.IndexOf(Char.ToLower(str[offset]));
                                if (c < 0)
                                {
                                    ExpectedButGot(interp, "hexadecimal", new string(str));
                                }
                                value |= ((c << 4) & 0xf0);
                                if ((offset % 2) != 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        if ((offset % 2) != 0)
                        {
                            if (cmd == 'H')
                            {
                                value <<= 4;
                            }
                            else
                            {
                                value >>= 4;
                            }
                            resultBytes[cursor++] = (byte)value;
                        }
                        while (cursor < last)
                        {
                            resultBytes[cursor++] = 0;
                        }
                        break;
                    }

                    case 'c':
                    case 's':
                    case 'S':
                    case 'i':
                    case 'I':
                    case 'f':
                    case 'd':
                    {
                        TclObject[] listv;
                        if (count == BINARY_NOCOUNT)
                        {
                            listv    = new TclObject[1];
                            listv[0] = argv[arg++];
                            count    = 1;
                        }
                        else
                        {
                            listv = TclList.getElements(interp, argv[arg++]);
                            if (count == BINARY_ALL)
                            {
                                count = listv.Length;
                            }
                        }
                        for (int ix = 0; ix < count; ix++)
                        {
                            cursor = FormatNumber(interp, cmd, listv[ix], resultBytes, cursor);
                        }
                        break;
                    }

                    case 'x':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        for (int ix = 0; ix < count; ix++)
                        {
                            resultBytes[cursor++] = 0;
                        }
                        break;
                    }

                    case 'X':
                    {
                        if (cursor > maxPos)
                        {
                            maxPos = cursor;
                        }
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count == BINARY_ALL || count > cursor)
                        {
                            cursor = 0;
                        }
                        else
                        {
                            cursor -= count;
                        }
                        break;
                    }

                    case '@':
                    {
                        if (cursor > maxPos)
                        {
                            maxPos = cursor;
                        }
                        if (count == BINARY_ALL)
                        {
                            cursor = maxPos;
                        }
                        else
                        {
                            cursor = count;
                        }
                        break;
                    }
                    }
                }
                break;
            }

            case CMD_SCAN:
            {
                if (argv.Length < 4)
                {
                    throw new TclNumArgsException(interp, 2, argv, "value formatString ?varName varName ...?");
                }
                byte[] src = TclByteArray.getBytes(interp, argv[2]);
                length = src.Length;
                format = argv[3].ToString().ToCharArray();
                arg    = 4;
                cursor = 0;
                offset = 0;
                int parsePos = 0;
                while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END)
                {
                    int count = GetFormatCount(format, ref parsePos);
                    switch (cmd)
                    {
                    case 'a':
                    case 'A':
                    {
                        if (arg >= argv.Length)
                        {
                            MissingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = length - offset;
                        }
                        else
                        {
                            if (count == BINARY_NOCOUNT)
                            {
                                count = 1;
                            }
                            if (count > length - offset)
                            {
                                break;
                            }
                        }
                        size = count;
                        // Trim trailing nulls and spaces, if necessary.
                        if (cmd == 'A')
                        {
                            while (size > 0)
                            {
                                if (src[offset + size - 1] != '\x0000' && src[offset + size - 1] != ' ')
                                {
                                    break;
                                }
                                size--;
                            }
                        }
                        interp.SetVar(argv[arg++], TclByteArray.NewInstance(src, offset, size), 0);
                        offset += count;
                        break;
                    }

                    case 'b':
                    case 'B':
                    {
                        if (arg >= argv.Length)
                        {
                            MissingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = (length - offset) * 8;
                        }
                        else
                        {
                            if (count == BINARY_NOCOUNT)
                            {
                                count = 1;
                            }
                            if (count > (length - offset) * 8)
                            {
                                break;
                            }
                        }
                        StringBuilder s          = new StringBuilder(count);
                        int           thisOffset = offset;
                        if (cmd == 'b')
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 8) != 0)
                                {
                                    value >>= 1;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append((value & 1) != 0 ? '1' : '0');
                            }
                        }
                        else
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 8) != 0)
                                {
                                    value <<= 1;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append((value & 0x80) != 0 ? '1' : '0');
                            }
                        }
                        interp.SetVar(argv[arg++], TclString.NewInstance(s.ToString()), 0);
                        offset += (count + 7) / 8;
                        break;
                    }

                    case 'h':
                    case 'H':
                    {
                        if (arg >= argv.Length)
                        {
                            MissingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = (length - offset) * 2;
                        }
                        else
                        {
                            if (count == BINARY_NOCOUNT)
                            {
                                count = 1;
                            }
                            if (count > (length - offset) * 2)
                            {
                                break;
                            }
                        }
                        StringBuilder s          = new StringBuilder(count);
                        int           thisOffset = offset;
                        if (cmd == 'h')
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 2) != 0)
                                {
                                    value >>= 4;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append(HEXDIGITS[value & 0xf]);
                            }
                        }
                        else
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 2) != 0)
                                {
                                    value <<= 4;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append(HEXDIGITS[value >> 4 & 0xf]);
                            }
                        }
                        interp.SetVar(argv[arg++], TclString.NewInstance(s.ToString()), 0);
                        offset += (count + 1) / 2;
                        break;
                    }

                    case 'c':
                    case 's':
                    case 'S':
                    case 'i':
                    case 'I':
                    case 'f':
                    case 'd':
                    {
                        if (arg >= argv.Length)
                        {
                            MissingArg(interp);
                        }
                        switch (cmd)
                        {
                        case 'c':
                            size = 1;
                            break;

                        case 's':
                        case 'S':
                            size = 2;
                            break;

                        case 'i':
                        case 'I':
                            size = 4;
                            break;

                        case 'f':
                            size = 4;
                            break;

                        case 'd':
                            size = 8;
                            break;
                        }
                        TclObject valueObj;
                        if (count == BINARY_NOCOUNT)
                        {
                            if (length - offset < size)
                            {
                                break;
                            }
                            valueObj = ScanNumber(src, offset, cmd);
                            offset  += size;
                        }
                        else
                        {
                            if (count == BINARY_ALL)
                            {
                                count = (length - offset) / size;
                            }
                            if (length - offset < count * size)
                            {
                                break;
                            }
                            valueObj = TclList.NewInstance();
                            int thisOffset = offset;
                            for (int ix = 0; ix < count; ix++)
                            {
                                TclList.Append(null, valueObj, ScanNumber(src, thisOffset, cmd));
                                thisOffset += size;
                            }
                            offset += count * size;
                        }
                        interp.SetVar(argv[arg++], valueObj, 0);
                        break;
                    }

                    case 'x':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count == BINARY_ALL || count > length - offset)
                        {
                            offset = length;
                        }
                        else
                        {
                            offset += count;
                        }
                        break;
                    }

                    case 'X':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count == BINARY_ALL || count > offset)
                        {
                            offset = 0;
                        }
                        else
                        {
                            offset -= count;
                        }
                        break;
                    }

                    case '@':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            AlephWithoutCount(interp);
                        }
                        if (count == BINARY_ALL || count > length)
                        {
                            offset = length;
                        }
                        else
                        {
                            offset = count;
                        }
                        break;
                    }

                    default:
                    {
                        BadField(interp, cmd);
                    }
                    break;
                    }
                }
                // Set the result to the last position of the cursor.
                interp.SetResult(arg - 4);
            }
            break;
            }
            return(TCL.CompletionCode.RETURN);
        }