Source Code Cross Referenced for BinaryCmd.java in  » Scripting » jacl » tcl » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * BinaryCmd.java --
0003:         *
0004:         *	Implements the built-in "binary" Tcl command.
0005:         *
0006:         * Copyright (c) 1999 Christian Krone.
0007:         * Copyright (c) 1997 by Sun Microsystems, Inc.
0008:         *
0009:         * See the file "license.terms" for information on usage and
0010:         * redistribution of this file, and for a DISCLAIMER OF ALL
0011:         * WARRANTIES.
0012:         * 
0013:         * RCS: @(#) $Id: BinaryCmd.java,v 1.3 2005/07/22 04:47:24 mdejong Exp $
0014:         *
0015:         */
0016:
0017:        package tcl.lang;
0018:
0019:        import java.text.*;
0020:
0021:        /*
0022:         * This class implements the built-in "binary" command in Tcl.
0023:         */
0024:
0025:        class BinaryCmd implements  Command {
0026:
0027:            static final private String validCmds[] = { "format", "scan", };
0028:
0029:            static final private int CMD_FORMAT = 0;
0030:            static final private int CMD_SCAN = 1;
0031:
0032:            // The following constants are used by GetFormatSpec to indicate various
0033:            // special conditions in the parsing of a format specifier.
0034:
0035:            // Use all elements in the argument.
0036:            static final private int BINARY_ALL = -1;
0037:            // No count was specified in format.
0038:            static final private int BINARY_NOCOUNT = -2;
0039:            // End of format was found.
0040:            static final private char FORMAT_END = ' ';
0041:
0042:            /*
0043:             *----------------------------------------------------------------------
0044:             *
0045:             * cmdProc --
0046:             *
0047:             *	This procedure is invoked as part of the Command interface to
0048:             *	process the "binary" Tcl command.  See the user documentation
0049:             *	for details on what it does.
0050:             *
0051:             * Results:
0052:             *	None.
0053:             *
0054:             * Side effects:
0055:             *	See the user documentation.
0056:             *
0057:             *----------------------------------------------------------------------
0058:             */
0059:
0060:            public void cmdProc(Interp interp, // Current interpreter.
0061:                    TclObject[] argv) // Argument list.
0062:                    throws TclException // A standard Tcl exception.
0063:            {
0064:                int arg; // Index of next argument to consume.
0065:                char[] format = null; // User specified format string.
0066:                char cmd; // Current format character.
0067:                int cursor; // Current position within result buffer.
0068:                int maxPos; // Greatest position within result buffer that
0069:                // cursor has visited.
0070:                int value = 0; // Current integer value to be packed.
0071:                // Initialized to avoid compiler warning.
0072:                int offset, size = 0, length, index;
0073:
0074:                if (argv.length < 2) {
0075:                    throw new TclNumArgsException(interp, 1, argv,
0076:                            "option ?arg arg ...?");
0077:                }
0078:                int cmdIndex = TclIndex.get(interp, argv[1], validCmds,
0079:                        "option", 0);
0080:
0081:                switch (cmdIndex) {
0082:                case CMD_FORMAT: {
0083:                    if (argv.length < 3) {
0084:                        throw new TclNumArgsException(interp, 2, argv,
0085:                                "formatString ?arg arg ...?");
0086:                    }
0087:
0088:                    // To avoid copying the data, we format the string in two passes.
0089:                    // The first pass computes the size of the output buffer.  The
0090:                    // second pass places the formatted data into the buffer.
0091:
0092:                    format = argv[2].toString().toCharArray();
0093:                    arg = 3;
0094:                    length = 0;
0095:                    offset = 0;
0096:                    ParsePosition parsePos = new ParsePosition(0);
0097:
0098:                    while ((cmd = GetFormatSpec(format, parsePos)) != FORMAT_END) {
0099:                        int count = GetFormatCount(format, parsePos);
0100:
0101:                        switch (cmd) {
0102:                        case 'a':
0103:                        case 'A':
0104:                        case 'b':
0105:                        case 'B':
0106:                        case 'h':
0107:                        case 'H': {
0108:                            // For string-type specifiers, the count corresponds
0109:                            // to the number of bytes in a single argument.
0110:
0111:                            if (arg >= argv.length) {
0112:                                missingArg(interp);
0113:                            }
0114:                            if (count == BINARY_ALL) {
0115:                                count = TclByteArray.getLength(interp,
0116:                                        argv[arg]);
0117:                            } else if (count == BINARY_NOCOUNT) {
0118:                                count = 1;
0119:                            }
0120:                            arg++;
0121:                            switch (cmd) {
0122:                            case 'a':
0123:                            case 'A':
0124:                                offset += count;
0125:                                break;
0126:                            case 'b':
0127:                            case 'B':
0128:                                offset += (count + 7) / 8;
0129:                                break;
0130:                            case 'h':
0131:                            case 'H':
0132:                                offset += (count + 1) / 2;
0133:                                break;
0134:                            }
0135:                            break;
0136:                        }
0137:                        case 'c':
0138:                        case 's':
0139:                        case 'S':
0140:                        case 'i':
0141:                        case 'I':
0142:                        case 'f':
0143:                        case 'd': {
0144:                            if (arg >= argv.length) {
0145:                                missingArg(interp);
0146:                            }
0147:                            switch (cmd) {
0148:                            case 'c':
0149:                                size = 1;
0150:                                break;
0151:                            case 's':
0152:                            case 'S':
0153:                                size = 2;
0154:                                break;
0155:                            case 'i':
0156:                            case 'I':
0157:                                size = 4;
0158:                                break;
0159:                            case 'f':
0160:                                size = 4;
0161:                                break;
0162:                            case 'd':
0163:                                size = 8;
0164:                                break;
0165:                            }
0166:
0167:                            // For number-type specifiers, the count corresponds
0168:                            // to the number of elements in the list stored in
0169:                            // a single argument.  If no count is specified, then
0170:                            // the argument is taken as a single non-list value.
0171:
0172:                            if (count == BINARY_NOCOUNT) {
0173:                                arg++;
0174:                                count = 1;
0175:                            } else {
0176:                                int listc = TclList.getLength(interp,
0177:                                        argv[arg++]);
0178:                                if (count == BINARY_ALL) {
0179:                                    count = listc;
0180:                                } else if (count > listc) {
0181:                                    throw new TclException(interp,
0182:                                            "number of elements in list"
0183:                                                    + " does not match count");
0184:                                }
0185:                            }
0186:                            offset += count * size;
0187:                            break;
0188:                        }
0189:                        case 'x': {
0190:                            if (count == BINARY_ALL) {
0191:                                throw new TclException(
0192:                                        interp,
0193:                                        "cannot use \"*\""
0194:                                                + " in format string with \"x\"");
0195:                            }
0196:                            if (count == BINARY_NOCOUNT) {
0197:                                count = 1;
0198:                            }
0199:                            offset += count;
0200:                            break;
0201:                        }
0202:                        case 'X': {
0203:                            if (count == BINARY_NOCOUNT) {
0204:                                count = 1;
0205:                            }
0206:                            if ((count > offset) || (count == BINARY_ALL)) {
0207:                                count = offset;
0208:                            }
0209:                            if (offset > length) {
0210:                                length = offset;
0211:                            }
0212:                            offset -= count;
0213:                            break;
0214:                        }
0215:                        case '@': {
0216:                            if (offset > length) {
0217:                                length = offset;
0218:                            }
0219:                            if (count == BINARY_ALL) {
0220:                                offset = length;
0221:                            } else if (count == BINARY_NOCOUNT) {
0222:                                alephWithoutCount(interp);
0223:                            } else {
0224:                                offset = count;
0225:                            }
0226:                            break;
0227:                        }
0228:                        default: {
0229:                            badField(interp, cmd);
0230:                        }
0231:                        }
0232:                    }
0233:                    if (offset > length) {
0234:                        length = offset;
0235:                    }
0236:                    if (length == 0) {
0237:                        return;
0238:                    }
0239:
0240:                    // Prepare the result object by preallocating the calculated
0241:                    // number of bytes and filling with nulls.
0242:
0243:                    TclObject resultObj = TclByteArray.newInstance();
0244:                    byte[] resultBytes = TclByteArray.setLength(interp,
0245:                            resultObj, length);
0246:                    interp.setResult(resultObj);
0247:
0248:                    // Pack the data into the result object.  Note that we can skip
0249:                    // the error checking during this pass, since we have already
0250:                    // parsed the string once.
0251:
0252:                    arg = 3;
0253:                    cursor = 0;
0254:                    maxPos = cursor;
0255:                    parsePos.setIndex(0);
0256:
0257:                    while ((cmd = GetFormatSpec(format, parsePos)) != FORMAT_END) {
0258:                        int count = GetFormatCount(format, parsePos);
0259:
0260:                        if ((count == 0) && (cmd != '@')) {
0261:                            arg++;
0262:                            continue;
0263:                        }
0264:
0265:                        switch (cmd) {
0266:                        case 'a':
0267:                        case 'A': {
0268:                            byte pad = (cmd == 'a') ? (byte) 0 : (byte) ' ';
0269:                            byte[] bytes = TclByteArray.getBytes(interp,
0270:                                    argv[arg++]);
0271:                            length = bytes.length;
0272:
0273:                            if (count == BINARY_ALL) {
0274:                                count = length;
0275:                            } else if (count == BINARY_NOCOUNT) {
0276:                                count = 1;
0277:                            }
0278:                            if (length >= count) {
0279:                                System.arraycopy(bytes, 0, resultBytes, cursor,
0280:                                        count);
0281:                            } else {
0282:                                System.arraycopy(bytes, 0, resultBytes, cursor,
0283:                                        length);
0284:                                for (int ix = 0; ix < count - length; ix++) {
0285:                                    resultBytes[cursor + length + ix] = pad;
0286:                                }
0287:                            }
0288:                            cursor += count;
0289:                            break;
0290:                        }
0291:                        case 'b':
0292:                        case 'B': {
0293:                            char[] str = argv[arg++].toString().toCharArray();
0294:                            if (count == BINARY_ALL) {
0295:                                count = str.length;
0296:                            } else if (count == BINARY_NOCOUNT) {
0297:                                count = 1;
0298:                            }
0299:                            int last = cursor + ((count + 7) / 8);
0300:                            if (count > str.length) {
0301:                                count = str.length;
0302:                            }
0303:                            if (cmd == 'B') {
0304:                                for (offset = 0; offset < count; offset++) {
0305:                                    value <<= 1;
0306:                                    if (str[offset] == '1') {
0307:                                        value |= 1;
0308:                                    } else if (str[offset] != '0') {
0309:                                        expectedButGot(interp, "binary",
0310:                                                new String(str));
0311:                                    }
0312:                                    if (((offset + 1) % 8) == 0) {
0313:                                        resultBytes[cursor++] = (byte) value;
0314:                                        value = 0;
0315:                                    }
0316:                                }
0317:                            } else {
0318:                                for (offset = 0; offset < count; offset++) {
0319:                                    value >>= 1;
0320:                                    if (str[offset] == '1') {
0321:                                        value |= 128;
0322:                                    } else if (str[offset] != '0') {
0323:                                        expectedButGot(interp, "binary",
0324:                                                new String(str));
0325:                                    }
0326:                                    if (((offset + 1) % 8) == 0) {
0327:                                        resultBytes[cursor++] = (byte) value;
0328:                                        value = 0;
0329:                                    }
0330:                                }
0331:                            }
0332:                            if ((offset % 8) != 0) {
0333:                                if (cmd == 'B') {
0334:                                    value <<= 8 - (offset % 8);
0335:                                } else {
0336:                                    value >>= 8 - (offset % 8);
0337:                                }
0338:                                resultBytes[cursor++] = (byte) value;
0339:                            }
0340:                            while (cursor < last) {
0341:                                resultBytes[cursor++] = 0;
0342:                            }
0343:                            break;
0344:                        }
0345:                        case 'h':
0346:                        case 'H': {
0347:                            char[] str = argv[arg++].toString().toCharArray();
0348:                            if (count == BINARY_ALL) {
0349:                                count = str.length;
0350:                            } else if (count == BINARY_NOCOUNT) {
0351:                                count = 1;
0352:                            }
0353:                            int last = cursor + ((count + 1) / 2);
0354:                            if (count > str.length) {
0355:                                count = str.length;
0356:                            }
0357:                            if (cmd == 'H') {
0358:                                for (offset = 0; offset < count; offset++) {
0359:                                    value <<= 4;
0360:                                    int c = Character.digit(str[offset], 16);
0361:                                    if (c < 0) {
0362:                                        expectedButGot(interp, "hexadecimal",
0363:                                                new String(str));
0364:                                    }
0365:                                    value |= (c & 0xf);
0366:                                    if ((offset % 2) != 0) {
0367:                                        resultBytes[cursor++] = (byte) value;
0368:                                        value = 0;
0369:                                    }
0370:                                }
0371:                            } else {
0372:                                for (offset = 0; offset < count; offset++) {
0373:                                    value >>= 4;
0374:                                    int c = Character.digit(str[offset], 16);
0375:                                    if (c < 0) {
0376:                                        expectedButGot(interp, "hexadecimal",
0377:                                                new String(str));
0378:                                    }
0379:                                    value |= ((c << 4) & 0xf0);
0380:                                    if ((offset % 2) != 0) {
0381:                                        resultBytes[cursor++] = (byte) value;
0382:                                        value = 0;
0383:                                    }
0384:                                }
0385:                            }
0386:                            if ((offset % 2) != 0) {
0387:                                if (cmd == 'H') {
0388:                                    value <<= 4;
0389:                                } else {
0390:                                    value >>= 4;
0391:                                }
0392:                                resultBytes[cursor++] = (byte) value;
0393:                            }
0394:                            while (cursor < last) {
0395:                                resultBytes[cursor++] = 0;
0396:                            }
0397:                            break;
0398:                        }
0399:                        case 'c':
0400:                        case 's':
0401:                        case 'S':
0402:                        case 'i':
0403:                        case 'I':
0404:                        case 'f':
0405:                        case 'd': {
0406:                            TclObject[] listv;
0407:
0408:                            if (count == BINARY_NOCOUNT) {
0409:                                listv = new TclObject[1];
0410:                                listv[0] = argv[arg++];
0411:                                count = 1;
0412:                            } else {
0413:                                listv = TclList
0414:                                        .getElements(interp, argv[arg++]);
0415:                                if (count == BINARY_ALL) {
0416:                                    count = listv.length;
0417:                                }
0418:                            }
0419:                            for (int ix = 0; ix < count; ix++) {
0420:                                cursor = FormatNumber(interp, cmd, listv[ix],
0421:                                        resultBytes, cursor);
0422:                            }
0423:                            break;
0424:                        }
0425:                        case 'x': {
0426:                            if (count == BINARY_NOCOUNT) {
0427:                                count = 1;
0428:                            }
0429:                            for (int ix = 0; ix < count; ix++) {
0430:                                resultBytes[cursor++] = 0;
0431:                            }
0432:                            break;
0433:                        }
0434:                        case 'X': {
0435:                            if (cursor > maxPos) {
0436:                                maxPos = cursor;
0437:                            }
0438:                            if (count == BINARY_NOCOUNT) {
0439:                                count = 1;
0440:                            }
0441:                            if (count == BINARY_ALL || count > cursor) {
0442:                                cursor = 0;
0443:                            } else {
0444:                                cursor -= count;
0445:                            }
0446:                            break;
0447:                        }
0448:                        case '@': {
0449:                            if (cursor > maxPos) {
0450:                                maxPos = cursor;
0451:                            }
0452:                            if (count == BINARY_ALL) {
0453:                                cursor = maxPos;
0454:                            } else {
0455:                                cursor = count;
0456:                            }
0457:                            break;
0458:                        }
0459:                        }
0460:                    }
0461:                    break;
0462:                }
0463:                case CMD_SCAN: {
0464:                    if (argv.length < 4) {
0465:                        throw new TclNumArgsException(interp, 2, argv,
0466:                                "value formatString ?varName varName ...?");
0467:                    }
0468:                    byte[] src = TclByteArray.getBytes(interp, argv[2]);
0469:                    length = src.length;
0470:                    format = argv[3].toString().toCharArray();
0471:                    arg = 4;
0472:                    cursor = 0;
0473:                    offset = 0;
0474:                    ParsePosition parsePos = new ParsePosition(0);
0475:
0476:                    while ((cmd = GetFormatSpec(format, parsePos)) != FORMAT_END) {
0477:                        int count = GetFormatCount(format, parsePos);
0478:
0479:                        switch (cmd) {
0480:                        case 'a':
0481:                        case 'A': {
0482:                            if (arg >= argv.length) {
0483:                                missingArg(interp);
0484:                            }
0485:                            if (count == BINARY_ALL) {
0486:                                count = length - offset;
0487:                            } else {
0488:                                if (count == BINARY_NOCOUNT) {
0489:                                    count = 1;
0490:                                }
0491:                                if (count > length - offset) {
0492:                                    break;
0493:                                }
0494:                            }
0495:
0496:                            size = count;
0497:
0498:                            // Trim trailing nulls and spaces, if necessary.
0499:
0500:                            if (cmd == 'A') {
0501:                                while (size > 0) {
0502:                                    if (src[offset + size - 1] != '\0'
0503:                                            && src[offset + size - 1] != ' ') {
0504:                                        break;
0505:                                    }
0506:                                    size--;
0507:                                }
0508:                            }
0509:
0510:                            interp.setVar(argv[arg++], TclByteArray
0511:                                    .newInstance(src, offset, size), 0);
0512:
0513:                            offset += count;
0514:                            break;
0515:                        }
0516:                        case 'b':
0517:                        case 'B': {
0518:                            if (arg >= argv.length) {
0519:                                missingArg(interp);
0520:                            }
0521:                            if (count == BINARY_ALL) {
0522:                                count = (length - offset) * 8;
0523:                            } else {
0524:                                if (count == BINARY_NOCOUNT) {
0525:                                    count = 1;
0526:                                }
0527:                                if (count > (length - offset) * 8) {
0528:                                    break;
0529:                                }
0530:                            }
0531:                            StringBuffer s = new StringBuffer(count);
0532:                            int this Offset = offset;
0533:
0534:                            if (cmd == 'b') {
0535:                                for (int ix = 0; ix < count; ix++) {
0536:                                    if ((ix % 8) != 0) {
0537:                                        value >>= 1;
0538:                                    } else {
0539:                                        value = src[this Offset++];
0540:                                    }
0541:                                    s.append((value & 1) != 0 ? '1' : '0');
0542:                                }
0543:                            } else {
0544:                                for (int ix = 0; ix < count; ix++) {
0545:                                    if ((ix % 8) != 0) {
0546:                                        value <<= 1;
0547:                                    } else {
0548:                                        value = src[this Offset++];
0549:                                    }
0550:                                    s.append((value & 0x80) != 0 ? '1' : '0');
0551:                                }
0552:                            }
0553:
0554:                            interp.setVar(argv[arg++], TclString.newInstance(s
0555:                                    .toString()), 0);
0556:
0557:                            offset += (count + 7) / 8;
0558:                            break;
0559:                        }
0560:                        case 'h':
0561:                        case 'H': {
0562:                            if (arg >= argv.length) {
0563:                                missingArg(interp);
0564:                            }
0565:                            if (count == BINARY_ALL) {
0566:                                count = (length - offset) * 2;
0567:                            } else {
0568:                                if (count == BINARY_NOCOUNT) {
0569:                                    count = 1;
0570:                                }
0571:                                if (count > (length - offset) * 2) {
0572:                                    break;
0573:                                }
0574:                            }
0575:                            StringBuffer s = new StringBuffer(count);
0576:                            int this Offset = offset;
0577:
0578:                            if (cmd == 'h') {
0579:                                for (int ix = 0; ix < count; ix++) {
0580:                                    if ((ix % 2) != 0) {
0581:                                        value >>= 4;
0582:                                    } else {
0583:                                        value = src[this Offset++];
0584:                                    }
0585:                                    s.append(Character
0586:                                            .forDigit(value & 0xf, 16));
0587:                                }
0588:                            } else {
0589:                                for (int ix = 0; ix < count; ix++) {
0590:                                    if ((ix % 2) != 0) {
0591:                                        value <<= 4;
0592:                                    } else {
0593:                                        value = src[this Offset++];
0594:                                    }
0595:                                    s.append(Character.forDigit(
0596:                                            value >> 4 & 0xf, 16));
0597:                                }
0598:                            }
0599:
0600:                            interp.setVar(argv[arg++], TclString.newInstance(s
0601:                                    .toString()), 0);
0602:
0603:                            offset += (count + 1) / 2;
0604:                            break;
0605:                        }
0606:                        case 'c':
0607:                        case 's':
0608:                        case 'S':
0609:                        case 'i':
0610:                        case 'I':
0611:                        case 'f':
0612:                        case 'd': {
0613:                            if (arg >= argv.length) {
0614:                                missingArg(interp);
0615:                            }
0616:                            switch (cmd) {
0617:                            case 'c':
0618:                                size = 1;
0619:                                break;
0620:                            case 's':
0621:                            case 'S':
0622:                                size = 2;
0623:                                break;
0624:                            case 'i':
0625:                            case 'I':
0626:                                size = 4;
0627:                                break;
0628:                            case 'f':
0629:                                size = 4;
0630:                                break;
0631:                            case 'd':
0632:                                size = 8;
0633:                                break;
0634:                            }
0635:                            TclObject valueObj;
0636:                            if (count == BINARY_NOCOUNT) {
0637:                                if (length - offset < size) {
0638:                                    break;
0639:                                }
0640:                                valueObj = ScanNumber(src, offset, cmd);
0641:                                offset += size;
0642:                            } else {
0643:                                if (count == BINARY_ALL) {
0644:                                    count = (length - offset) / size;
0645:                                }
0646:                                if (length - offset < count * size) {
0647:                                    break;
0648:                                }
0649:                                valueObj = TclList.newInstance();
0650:                                int this Offset = offset;
0651:                                for (int ix = 0; ix < count; ix++) {
0652:                                    TclList.append(null, valueObj, ScanNumber(
0653:                                            src, this Offset, cmd));
0654:                                    this Offset += size;
0655:                                }
0656:                                offset += count * size;
0657:                            }
0658:
0659:                            interp.setVar(argv[arg++], valueObj, 0);
0660:
0661:                            break;
0662:                        }
0663:                        case 'x': {
0664:                            if (count == BINARY_NOCOUNT) {
0665:                                count = 1;
0666:                            }
0667:                            if (count == BINARY_ALL || count > length - offset) {
0668:                                offset = length;
0669:                            } else {
0670:                                offset += count;
0671:                            }
0672:                            break;
0673:                        }
0674:                        case 'X': {
0675:                            if (count == BINARY_NOCOUNT) {
0676:                                count = 1;
0677:                            }
0678:                            if (count == BINARY_ALL || count > offset) {
0679:                                offset = 0;
0680:                            } else {
0681:                                offset -= count;
0682:                            }
0683:                            break;
0684:                        }
0685:                        case '@': {
0686:                            if (count == BINARY_NOCOUNT) {
0687:                                alephWithoutCount(interp);
0688:                            }
0689:                            if (count == BINARY_ALL || count > length) {
0690:                                offset = length;
0691:                            } else {
0692:                                offset = count;
0693:                            }
0694:                            break;
0695:                        }
0696:                        default: {
0697:                            badField(interp, cmd);
0698:                        }
0699:                        }
0700:                    }
0701:
0702:                    // Set the result to the last position of the cursor.
0703:
0704:                    interp.setResult(arg - 4);
0705:                }
0706:                }
0707:            }
0708:
0709:            /*
0710:             *----------------------------------------------------------------------
0711:             *
0712:             * GetFormatSpec --
0713:             *
0714:             *	This function parses the format strings used in the binary
0715:             *	format and scan commands.
0716:             *
0717:             * Results:
0718:             *	Moves the parsePos to the start of the next command. Returns
0719:             *	the current command character or FORMAT_END if the string did
0720:             *	not have a format specifier.
0721:             *
0722:             * Side effects:
0723:             *	None.
0724:             *
0725:             *----------------------------------------------------------------------
0726:             */
0727:
0728:            private char GetFormatSpec(char[] format, // Format string.
0729:                    ParsePosition parsePos) // Current position in input.
0730:            {
0731:                int ix = parsePos.getIndex();
0732:
0733:                // Skip any leading blanks.
0734:
0735:                while (ix < format.length && format[ix] == ' ') {
0736:                    ix++;
0737:                }
0738:
0739:                // The string was empty, except for whitespace, so fail.
0740:
0741:                if (ix >= format.length) {
0742:                    parsePos.setIndex(ix);
0743:                    return FORMAT_END;
0744:                }
0745:
0746:                // Extract the command character.
0747:
0748:                parsePos.setIndex(ix + 1);
0749:
0750:                return format[ix++];
0751:            }
0752:
0753:            /*
0754:             *----------------------------------------------------------------------
0755:             *
0756:             * GetFormatCount --
0757:             *
0758:             *	This function parses the format strings used in the binary
0759:             *	format and scan commands.
0760:             *
0761:             * Results:
0762:             *	Moves the formatPtr to the start of the next command. Returns
0763:             *	the current command count. The count is set to BINARY_ALL if the
0764:             *	count character was '*' or BINARY_NOCOUNT if no count was
0765:             *	specified.
0766:             *
0767:             * Side effects:
0768:             *	None.
0769:             *
0770:             *----------------------------------------------------------------------
0771:             */
0772:
0773:            private int GetFormatCount(char[] format, // Format string.
0774:                    ParsePosition parsePos) // Current position in input.
0775:            {
0776:                int ix = parsePos.getIndex();
0777:
0778:                // Extract any trailing digits or '*'.
0779:
0780:                if (ix < format.length && format[ix] == '*') {
0781:                    parsePos.setIndex(ix + 1);
0782:                    return BINARY_ALL;
0783:                } else if (ix < format.length && Character.isDigit(format[ix])) {
0784:                    int length = 1;
0785:                    while (ix + length < format.length
0786:                            && Character.isDigit(format[ix + length])) {
0787:                        length++;
0788:                    }
0789:                    parsePos.setIndex(ix + length);
0790:                    return Integer.parseInt(new String(format, ix, length));
0791:                } else {
0792:                    return BINARY_NOCOUNT;
0793:                }
0794:            }
0795:
0796:            /**
0797:             *----------------------------------------------------------------------
0798:             *
0799:             * FormatNumber --
0800:             *
0801:             *	This method is called by the binary cmdProc to format a number
0802:             *	into a location pointed at by cursor.
0803:             *
0804:             * Results:
0805:             *	None
0806:             *
0807:             * Side effects:
0808:             *	None.
0809:             *
0810:             *----------------------------------------------------------------------
0811:             */
0812:
0813:            static int FormatNumber(Interp interp, // Current interpreter.
0814:                    char type, // Type of number to format.
0815:                    TclObject src, // Number to format.
0816:                    byte[] resultBytes, int cursor) throws TclException // A standard Tcl exception.
0817:            {
0818:                if (type == 'd') {
0819:                    double dvalue = TclDouble.get(interp, src);
0820:                    //System.out.println("double value is \"" + dvalue + "\"");
0821:                    long lvalue = Double.doubleToLongBits(dvalue);
0822:                    //System.out.println("long hex value is \"" + Long.toHexString(lvalue) + "\"");
0823:                    for (int ix = 7; ix >= 0; ix--) {
0824:                        resultBytes[cursor++] = (byte) (lvalue >> ix * 8);
0825:                        //byte b = resultBytes[cursor - 1];
0826:                        //System.out.println("index " + ix + " is " + Integer.toHexString(b & 0xff));
0827:                    }
0828:                } else if (type == 'f') {
0829:                    float fvalue;
0830:                    double dvalue = TclDouble.get(interp, src);
0831:                    //System.out.println("double value is \"" + dvalue + "\"");
0832:                    // Restrict the double value to the valid float range
0833:                    if (dvalue == Double.POSITIVE_INFINITY) {
0834:                        fvalue = Float.POSITIVE_INFINITY;
0835:                    } else if (dvalue == Double.NEGATIVE_INFINITY) {
0836:                        fvalue = Float.NEGATIVE_INFINITY;
0837:                    } else if (Math.abs(dvalue) > (double) Float.MAX_VALUE) {
0838:                        fvalue = (dvalue >= 0.0) ? Float.MAX_VALUE
0839:                                : -Float.MAX_VALUE;
0840:                    } else if (Math.abs(dvalue) < (double) Float.MIN_VALUE) {
0841:                        fvalue = (dvalue >= 0.0) ? 0.0f : -0.0f;
0842:                    } else {
0843:                        fvalue = (float) dvalue;
0844:                    }
0845:                    //System.out.println("float value is \"" + fvalue + "\"");
0846:                    int ivalue = Float.floatToIntBits(fvalue);
0847:                    //System.out.println("int hex value is \"" + Integer.toHexString(ivalue) + "\"");
0848:                    for (int ix = 3; ix >= 0; ix--) {
0849:                        resultBytes[cursor++] = (byte) (ivalue >> ix * 8);
0850:                        //byte b = resultBytes[cursor - 1];
0851:                        //System.out.println("index " + ix + " is " + Integer.toHexString(b & 0xff));
0852:                    }
0853:                } else {
0854:                    int value = TclInteger.get(interp, src);
0855:
0856:                    if (type == 'c') {
0857:                        resultBytes[cursor++] = (byte) value;
0858:                    } else if (type == 's') {
0859:                        resultBytes[cursor++] = (byte) value;
0860:                        resultBytes[cursor++] = (byte) (value >> 8);
0861:                    } else if (type == 'S') {
0862:                        resultBytes[cursor++] = (byte) (value >> 8);
0863:                        resultBytes[cursor++] = (byte) value;
0864:                    } else if (type == 'i') {
0865:                        resultBytes[cursor++] = (byte) value;
0866:                        resultBytes[cursor++] = (byte) (value >> 8);
0867:                        resultBytes[cursor++] = (byte) (value >> 16);
0868:                        resultBytes[cursor++] = (byte) (value >> 24);
0869:                    } else if (type == 'I') {
0870:                        resultBytes[cursor++] = (byte) (value >> 24);
0871:                        resultBytes[cursor++] = (byte) (value >> 16);
0872:                        resultBytes[cursor++] = (byte) (value >> 8);
0873:                        resultBytes[cursor++] = (byte) value;
0874:                    }
0875:                }
0876:                return cursor;
0877:            }
0878:
0879:            /**
0880:             *----------------------------------------------------------------------
0881:             *
0882:             * ScanNumber --
0883:             *
0884:             *	This routine is called by Tcl_BinaryObjCmd to scan a number
0885:             *	out of a buffer.
0886:             *
0887:             * Results:
0888:             *	Returns a newly created object containing the scanned number.
0889:             *	This object has a ref count of zero.
0890:             *
0891:             * Side effects:
0892:             *	None.
0893:             *
0894:             *----------------------------------------------------------------------
0895:             */
0896:
0897:            private static TclObject ScanNumber(byte[] src, // Buffer to scan number from.
0898:                    int pos, //
0899:                    int type) // Format character from "binary scan"
0900:            {
0901:                switch (type) {
0902:                case 'c': {
0903:                    return TclInteger.newInstance((int) src[pos]);
0904:                }
0905:                case 's': {
0906:                    short value = (short) ((src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8));
0907:                    return TclInteger.newInstance((int) value);
0908:                }
0909:                case 'S': {
0910:                    short value = (short) ((src[pos + 1] & 0xff) + ((src[pos] & 0xff) << 8));
0911:                    return TclInteger.newInstance((int) value);
0912:                }
0913:                case 'i': {
0914:                    int value = (src[pos] & 0xff)
0915:                            + ((src[pos + 1] & 0xff) << 8)
0916:                            + ((src[pos + 2] & 0xff) << 16)
0917:                            + ((src[pos + 3] & 0xff) << 24);
0918:                    return TclInteger.newInstance(value);
0919:                }
0920:                case 'I': {
0921:                    int value = (src[pos + 3] & 0xff)
0922:                            + ((src[pos + 2] & 0xff) << 8)
0923:                            + ((src[pos + 1] & 0xff) << 16)
0924:                            + ((src[pos] & 0xff) << 24);
0925:                    return TclInteger.newInstance(value);
0926:                }
0927:                case 'f': {
0928:                    int value = (src[pos + 3] & 0xff)
0929:                            + ((src[pos + 2] & 0xff) << 8)
0930:                            + ((src[pos + 1] & 0xff) << 16)
0931:                            + ((src[pos] & 0xff) << 24);
0932:                    return TclDouble.newInstance(Float.intBitsToFloat(value));
0933:                }
0934:                case 'd': {
0935:                    long value = (((long) src[pos + 7]) & 0xff)
0936:                            + (((long) (src[pos + 6] & 0xff)) << 8)
0937:                            + (((long) (src[pos + 5] & 0xff)) << 16)
0938:                            + (((long) (src[pos + 4] & 0xff)) << 24)
0939:                            + (((long) (src[pos + 3] & 0xff)) << 32)
0940:                            + (((long) (src[pos + 2] & 0xff)) << 40)
0941:                            + (((long) (src[pos + 1] & 0xff)) << 48)
0942:                            + (((long) (src[pos] & 0xff)) << 56);
0943:                    return TclDouble
0944:                            .newInstance(Double.longBitsToDouble(value));
0945:                }
0946:                }
0947:                return null;
0948:            }
0949:
0950:            /**
0951:             * Called whenever a format specifier was detected
0952:             * but there are not enough arguments specified.
0953:             *
0954:             * @param interp  - The TclInterp which called the cmdProc method.
0955:             */
0956:
0957:            private static void missingArg(Interp interp) // Current interpreter.
0958:                    throws TclException // A standard Tcl exception.
0959:            {
0960:                throw new TclException(interp,
0961:                        "not enough arguments for all format specifiers");
0962:            }
0963:
0964:            /**
0965:             * Called whenever an invalid format specifier was detected.
0966:             *
0967:             * @param interp  - The TclInterp which called the cmdProc method.
0968:             * @param cmd     - The invalid field specifier.
0969:             */
0970:
0971:            private static void badField(Interp interp, // Current interpreter.
0972:                    char cmd) // the invalid field specifier.
0973:                    throws TclException // A standard Tcl exception.
0974:            {
0975:                throw new TclException(interp, "bad field specifier \"" + cmd
0976:                        + "\"");
0977:            }
0978:
0979:            /**
0980:             * Called whenever a letter aleph character (@) was detected
0981:             * but there was no count specified.
0982:             *
0983:             * @param interp  - The TclInterp which called the cmdProc method.
0984:             */
0985:
0986:            private static void alephWithoutCount(Interp interp) // Current interpreter.
0987:                    throws TclException // A standard Tcl exception.
0988:            {
0989:                throw new TclException(interp,
0990:                        "missing count for \"@\" field specifier");
0991:            }
0992:
0993:            /**
0994:             * Called whenever a format was found which restricts the valid range
0995:             * of characters in the specified string, but the string contains
0996:             * at least one char not in this range.
0997:             *
0998:             * @param interp  - The TclInterp which called the cmdProc method.
0999:             */
1000:
1001:            private static void expectedButGot(Interp interp, // Current interpreter.
1002:                    String expected, // Classification of what was expected.
1003:                    String str) // Was was found instead.
1004:                    throws TclException // A standard Tcl exception.
1005:            {
1006:                throw new TclException(interp, "expected " + expected
1007:                        + " string but got \"" + str + "\" instead");
1008:            }
1009:
1010:        } // end BinaryCmd
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.