Source Code Cross Referenced for OString.java in  » Scripting » oscript-2.10.4 » oscript » data » 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 » oscript 2.10.4 » oscript.data 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*=============================================================================
0002:         *     Copyright Texas Instruments 2000-2004.  All Rights Reserved.
0003:         *   
0004:         * This program is free software; you can redistribute it and/or
0005:         * modify it under the terms of the GNU Lesser General Public
0006:         * License as published by the Free Software Foundation; either
0007:         * version 2 of the License, or (at your option) any later version.
0008:         * 
0009:         * This program is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012:         * Lesser General Public License for more details.
0013:         * 
0014:         * You should have received a copy of the GNU Lesser General Public
0015:         * License along with this library; if not, write to the Free Software
0016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0017:         * 
0018:         * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
0019:         */
0020:
0021:        package oscript.data;
0022:
0023:        import oscript.exceptions.*;
0024:
0025:        import java.util.Hashtable;
0026:
0027:        /**
0028:         * A string class.  An <code>OString</code> is immutable, once the instance is 
0029:         * constructed, it won't change.
0030:         * 
0031:         * @author Rob Clark (rob@ti.com)
0032:         */
0033:        public class OString extends OObject implements  java.io.Externalizable {
0034:            /**
0035:             * The type object for an instance of String.
0036:             */
0037:            public final static Value TYPE = BuiltinType
0038:                    .makeBuiltinType("oscript.data.OString");
0039:            public final static String PARENT_TYPE_NAME = "oscript.data.OObject";
0040:            public final static String TYPE_NAME = "String";
0041:            public final static String[] MEMBER_NAMES = new String[] {
0042:                    "castToBoolean", "castToString", "castToExactNumber",
0043:                    "castToInexactNumber", "castToJavaObject", "bopEquals",
0044:                    "bopEqualsR", "bopNotEquals", "bopNotEqualsR",
0045:                    "bopLessThan", "bopLessThanR", "bopGreaterThan",
0046:                    "bopGreaterThanR", "bopLessThanOrEquals",
0047:                    "bopLessThanOrEqualsR", "bopGreaterThanOrEquals",
0048:                    "bopGreaterThanOrEqualsR", "bopPlus", "bopPlusR", "length",
0049:                    "elementAt", "elementsAt", "match", "replace", "search",
0050:                    "substring", "intern", "indexOf", "lastIndexOf",
0051:                    "toUpperCase", "toLowerCase", "equals", "startsWith",
0052:                    "endsWith", "trim", "split" };
0053:
0054:            /*=======================================================================*/
0055:            /**
0056:             */
0057:            private Segment segment;
0058:
0059:            public OString() {
0060:            }
0061:
0062:            /**
0063:             * Derived class that implements {@link java.io.Externalizable} must
0064:             * call this if it overrides it.  It should override it to save/restore
0065:             * it's own state.
0066:             */
0067:            public void readExternal(java.io.ObjectInput in)
0068:                    throws java.io.IOException {
0069:                segment = new StringSegment(in.readUTF());
0070:            }
0071:
0072:            /**
0073:             * Derived class that implements {@link java.io.Externalizable} must
0074:             * call this if it overrides it.  It should override it to save/restore
0075:             * it's own state.
0076:             */
0077:            public void writeExternal(java.io.ObjectOutput out)
0078:                    throws java.io.IOException {
0079:                out.writeUTF(segment.toString());
0080:            }
0081:
0082:            /*=======================================================================*/
0083:
0084:            /*=======================================================================*/
0085:            /**
0086:             * Construct a new string.
0087:             * 
0088:             * @param stringVal    the value of the string
0089:             */
0090:            public OString(String stringVal) {
0091:                this (new StringSegment(stringVal));
0092:            }
0093:
0094:            private OString(Segment segment) {
0095:                super ();
0096:                this .segment = segment;
0097:            }
0098:
0099:            /*=======================================================================*/
0100:            /**
0101:             * Class Constructor.  This is the constructor that gets called via an
0102:             * <code>BuiltinType</code> instance.
0103:             * 
0104:             * @param args         arguments to this constructor
0105:             * @throws PackagedScriptObjectException(Exception) if wrong number of args
0106:             */
0107:            public OString(oscript.util.MemberTable args) {
0108:                super ();
0109:
0110:                if (args.length() != 1)
0111:                    throw PackagedScriptObjectException
0112:                            .makeExceptionWrapper(new OIllegalArgumentException(
0113:                                    "wrong number of args!"));
0114:                else
0115:                    segment = new StringSegment(args.referenceAt(0)
0116:                            .castToString());
0117:            }
0118:
0119:            /*=======================================================================*/
0120:            /**
0121:             * Get the type of this object.  The returned type doesn't have to take
0122:             * into account the possibility of a script type extending a built-in
0123:             * type, since that is handled by {@link #getType}.
0124:             * 
0125:             * @return the object's type
0126:             */
0127:            protected Value getTypeImpl() {
0128:                return TYPE;
0129:            }
0130:
0131:            /*=======================================================================*/
0132:            /**
0133:             * Get the value of this string.
0134:             * 
0135:             * @return the string as a java.lang.String
0136:             */
0137:            public final String value() {
0138:                return segment.toString();
0139:            }
0140:
0141:            /*=======================================================================*/
0142:            /**
0143:             * Return a hash code value for this object.
0144:             * 
0145:             * @return a hash code value
0146:             * @see java.lang.Object#hashCode()
0147:             */
0148:            public int hashCode() {
0149:                return segment.hashCode();
0150:            }
0151:
0152:            /*=======================================================================*/
0153:            /**
0154:             * Return a canonical representation of this OString object.  This has the
0155:             * result that <code>x.intern() == y.intern()</code> (for <code>x</code>
0156:             * and <code>y</code> that are OString objects).
0157:             * 
0158:             * @return a OString that has the same value (in the sense of <code>equals
0159:             * </code>) but is guaraneed to be from a unique pool of OStrings
0160:             */
0161:            public OString intern() {
0162:                return makeString(this , segment.toString());
0163:            }
0164:
0165:            /*=======================================================================*/
0166:            /**
0167:             * Compare two objects for equality.
0168:             * 
0169:             * @param obj          the object to compare to this object
0170:             * @return <code>true</code> if equals, else <code>false</code>
0171:             * @see java.lang.Object#equals(java.lang.Object)
0172:             */
0173:            public boolean equals(Object obj) {
0174:                if (this  == obj)
0175:                    return true;
0176:
0177:                String str = null;
0178:
0179:                if (obj instanceof  String)
0180:                    str = (String) obj;
0181:                else if (obj instanceof  Value)
0182:                    str = ((Value) obj).castToString();
0183:
0184:                if (str != null)
0185:                    return str.equals(segment.toString());
0186:
0187:                return false;
0188:            }
0189:
0190:            /*=======================================================================*/
0191:            /**
0192:             * Convert this object to a native java <code>boolean</code> value.
0193:             * 
0194:             * @return a boolean value
0195:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0196:             */
0197:            public boolean castToBoolean() throws PackagedScriptObjectException {
0198:                if (segment.toString().equals("true")) {
0199:                    return true;
0200:                } else if (segment.toString().equals("false")) {
0201:                    return false;
0202:                } else {
0203:                    throw noSuchMember("castToBoolean");
0204:                }
0205:            }
0206:
0207:            /*=======================================================================*/
0208:            /**
0209:             * Convert this object to a native java <code>String</code> value.
0210:             * 
0211:             * @return a String value
0212:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0213:             */
0214:            public String castToString() throws PackagedScriptObjectException {
0215:                return segment.toString();
0216:            }
0217:
0218:            public static Value _bopCast(Value val) {
0219:                if (val instanceof  OString)
0220:                    return val;
0221:                return new OString(val.castToString());
0222:            }
0223:
0224:            /*=======================================================================*/
0225:            /**
0226:             * Convert this object to a native java <code>long</code> value.  In order
0227:             * for a string to be converted to an exact number, it must be of the
0228:             * form:
0229:             * <pre>
0230:             *   STRING       ::== ("-")? (HEX_STRING | OCTAL_STRING | DEC_STRING)
0231:             *   HEX_STRING   ::== ("0x" | "0X") ([0-9] | [a-f] | [A-F])+
0232:             *   OCTAL_STRING ::== "0" ([0-7])+
0233:             *   DEC_STRING   ::== ([0-9])+
0234:             * </pre>
0235:             * 
0236:             * @return a long value
0237:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0238:             */
0239:            public long castToExactNumber()
0240:                    throws PackagedScriptObjectException {
0241:                /* we are spending too much time in NumberFormatException::fillInStackTrace 
0242:                 * is thrown, so instead we roll our own:
0243:                 */
0244:                if (segment.toString().length() > Byte.MAX_VALUE) {
0245:                    throw PackagedScriptObjectException
0246:                            .makeExceptionWrapper(new ONoSuchMemberException(
0247:                                    "cannot convert \"" + segment.toString()
0248:                                            + "\" to ExactNumber"));
0249:                }
0250:
0251:                byte radix = 10;
0252:                byte idx = 0;
0253:                byte sign = 1;
0254:                byte max = (byte) (segment.toString().length());
0255:
0256:                String str = segment.toString();
0257:
0258:                if (str.startsWith("-")) {
0259:                    idx += 1;
0260:                    sign = -1;
0261:                }
0262:
0263:                if (str.startsWith("0x", idx) || str.startsWith("0X", idx)) {
0264:                    idx += 2;
0265:                    radix = 16;
0266:                } else if (str.startsWith("0", idx)) {
0267:                    idx += 1;
0268:                    radix = 8;
0269:                } else if (str.startsWith("'", idx)) {
0270:                    idx += 1;
0271:                    radix = 2;
0272:                }
0273:
0274:                // check for valid number string, ie "0x", "-", etc., aren't valid:
0275:                if ((idx >= max) && (radix != 8))
0276:                    throw PackagedScriptObjectException
0277:                            .makeExceptionWrapper(new ONoSuchMemberException(
0278:                                    "cannot convert \"" + str
0279:                                            + "\" to ExactNumber"));
0280:
0281:                return parseExactNumber(segment.toString(), radix, idx, max)
0282:                        * sign;
0283:            }
0284:
0285:            // doesn't deal with sign, figure out radix, etc...
0286:            private static final long parseExactNumber(String str, byte radix,
0287:                    byte idx, byte max) {
0288:                long result = 0;
0289:
0290:                while (idx < max) {
0291:                    int digit = Character.digit(str.charAt(idx++), radix);
0292:
0293:                    // check for characters that aren't digits:
0294:                    if (digit == -1)
0295:                        throw PackagedScriptObjectException
0296:                                .makeExceptionWrapper(new ONoSuchMemberException(
0297:                                        "cannot convert \"" + str
0298:                                                + "\" to ExactNumber"));
0299:
0300:                    long oldResult = result;
0301:
0302:                    result *= radix;
0303:                    result += digit;
0304:
0305:                    // check for roll-over:
0306:                    if (result < oldResult)
0307:                        throw PackagedScriptObjectException
0308:                                .makeExceptionWrapper(new ONoSuchMemberException(
0309:                                        "cannot convert \"" + str
0310:                                                + "\" to ExactNumber"));
0311:                }
0312:
0313:                return result;
0314:            }
0315:
0316:            /*=======================================================================*/
0317:            /**
0318:             * Convert this object to a native java <code>double</code> value.  In
0319:             * order for a string to be converted to an inexact number, it must be
0320:             * of the form:
0321:             * <pre>
0322:             *   STRING       ::== ("+" | "-")? EXACT_NUMBER ("." EXACT_NUMBER)? (("e" | "E") EXACT_NUMBER)?
0323:             *   EXACT_NUMBER ::== <see convertToExactNumber>
0324:             * </pre>
0325:             * 
0326:             * @return a double value
0327:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0328:             */
0329:            public double castToInexactNumber()
0330:                    throws PackagedScriptObjectException {
0331:                String r = segment.toString();
0332:
0333:                /* we are spending too much time in NumberFormatException::fillInStackTrace 
0334:                 * is thrown, so instead we roll our own:
0335:                 */
0336:                if (r.length() > Byte.MAX_VALUE)
0337:                    throw PackagedScriptObjectException
0338:                            .makeExceptionWrapper(new ONoSuchMemberException(
0339:                                    "cannot convert \"" + segment.toString()
0340:                                            + "\" to InexactNumber"));
0341:
0342:                // in case we have something like "0x1234".castToInexactNumber()
0343:                if (r.indexOf('.') == -1)
0344:                    return (double) castToExactNumber();
0345:
0346:                double sign = 1.0;
0347:                byte tmp;
0348:
0349:                if (r.startsWith("-")) {
0350:                    sign = -1.0;
0351:                    r = r.substring(1);
0352:                } else if (r.startsWith("+")) {
0353:                    // "+" is the default sign
0354:                    r = r.substring(1);
0355:                }
0356:
0357:                // check for valid string:
0358:                if (r.length() <= 0)
0359:                    throw PackagedScriptObjectException
0360:                            .makeExceptionWrapper(new ONoSuchMemberException(
0361:                                    "cannot convert \"" + segment.toString()
0362:                                            + "\" to InexactNumber"));
0363:
0364:                String s1;
0365:                String s2;
0366:                String s3;
0367:
0368:                // look for optional s3:
0369:                tmp = (byte) (r.lastIndexOf('e'));
0370:                if (tmp == -1)
0371:                    tmp = (byte) (r.lastIndexOf('E'));
0372:
0373:                if (tmp != -1) {
0374:                    s3 = r.substring(tmp + 1);
0375:                    r = r.substring(0, tmp);
0376:                } else {
0377:                    s3 = null;
0378:                }
0379:
0380:                // look for optional s2:
0381:                tmp = (byte) (r.lastIndexOf('.'));
0382:                if (tmp != -1) {
0383:                    s2 = r.substring(tmp + 1);
0384:                    r = r.substring(0, tmp);
0385:                } else {
0386:                    s2 = null;
0387:                }
0388:
0389:                // whats left is s1:
0390:                s1 = r;
0391:
0392:                // now convert to a number:
0393:                try {
0394:                    double result = (double) parseExactNumber(s1, (byte) 10,
0395:                            (byte) 0, (byte) (s1.length()));
0396:
0397:                    if (s2 != null) {
0398:                        double dec = (double) parseExactNumber(s2, (byte) 10,
0399:                                (byte) 0, (byte) (s2.length()));
0400:
0401:                        result += dec / Math.pow(10, s2.length());
0402:                    }
0403:
0404:                    if (s3 != null) {
0405:                        byte esign = 1;
0406:                        if (s3.startsWith("-")) {
0407:                            esign = -1;
0408:                            s3 = s3.substring(1);
0409:                        } else if (s3.startsWith("+")) {
0410:                            s3 = s3.substring(1);
0411:                        }
0412:
0413:                        double exp = esign
0414:                                * (double) parseExactNumber(s3, (byte) 10,
0415:                                        (byte) 0, (byte) (s3.length()));
0416:
0417:                        result *= Math.pow(10, exp);
0418:                    }
0419:
0420:                    return sign * result;
0421:                } catch (PackagedScriptObjectException e) {
0422:                    throw PackagedScriptObjectException
0423:                            .makeExceptionWrapper(new ONoSuchMemberException(
0424:                                    "cannot convert \"" + segment.toString()
0425:                                            + "\" to InexactNumber"));
0426:                }
0427:            }
0428:
0429:            /*=======================================================================*/
0430:            /**
0431:             * Convert this object to a native java <code>Object</code> value.
0432:             * 
0433:             * @return a java object
0434:             * @throws PackagedScriptObjectException(NoSuchMemberException)
0435:             */
0436:            public Object castToJavaObject()
0437:                    throws PackagedScriptObjectException {
0438:                return segment.toString();
0439:            }
0440:
0441:            /*=======================================================================*/
0442:            /* The binary operators:
0443:             */
0444:
0445:            /*=======================================================================*/
0446:            /**
0447:             * Perform the "==" operation.
0448:             * 
0449:             * @param val          the other value
0450:             * @return the result
0451:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0452:             */
0453:            public Value bopEquals(Value val)
0454:                    throws PackagedScriptObjectException {
0455:                try {
0456:                    return OBoolean.makeBoolean(segment.toString().equals(
0457:                            val.castToString()));
0458:                } catch (PackagedScriptObjectException e) {
0459:                    return val.bopEqualsR(this , e);
0460:                }
0461:            }
0462:
0463:            public Value bopEqualsR(Value val, PackagedScriptObjectException e)
0464:                    throws PackagedScriptObjectException {
0465:                return OBoolean.makeBoolean(val.castToString().equals(
0466:                        segment.toString()));
0467:            }
0468:
0469:            /*=======================================================================*/
0470:            /**
0471:             * Perform the "!=" operation.
0472:             * 
0473:             * @param val          the other value
0474:             * @return the result
0475:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0476:             */
0477:            public Value bopNotEquals(Value val)
0478:                    throws PackagedScriptObjectException {
0479:                try {
0480:                    return OBoolean.makeBoolean(!segment.toString().equals(
0481:                            val.castToString()));
0482:                } catch (PackagedScriptObjectException e) {
0483:                    return val.bopNotEqualsR(this , e);
0484:                }
0485:            }
0486:
0487:            public Value bopNotEqualsR(Value val,
0488:                    PackagedScriptObjectException e)
0489:                    throws PackagedScriptObjectException {
0490:                return OBoolean.makeBoolean(!val.castToString().equals(
0491:                        segment.toString()));
0492:            }
0493:
0494:            /*=======================================================================*/
0495:            /**
0496:             * Perform the "<" operation.
0497:             * 
0498:             * @param val          the other value
0499:             * @return the result
0500:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0501:             */
0502:            public Value bopLessThan(Value val)
0503:                    throws PackagedScriptObjectException {
0504:                try {
0505:                    return OBoolean.makeBoolean(segment.toString().compareTo(
0506:                            val.castToString()) < 0);
0507:                } catch (PackagedScriptObjectException e) {
0508:                    return val.bopLessThanR(this , e);
0509:                }
0510:            }
0511:
0512:            public Value bopLessThanR(Value val, PackagedScriptObjectException e)
0513:                    throws PackagedScriptObjectException {
0514:                return OBoolean.makeBoolean(segment.toString().compareTo(
0515:                        val.castToString()) > 0);
0516:            }
0517:
0518:            /*=======================================================================*/
0519:            /**
0520:             * Perform the ">" operation.
0521:             * 
0522:             * @param val          the other value
0523:             * @return the result
0524:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0525:             */
0526:            public Value bopGreaterThan(Value val)
0527:                    throws PackagedScriptObjectException {
0528:                try {
0529:                    return OBoolean.makeBoolean(segment.toString().compareTo(
0530:                            val.castToString()) > 0);
0531:                } catch (PackagedScriptObjectException e) {
0532:                    return val.bopGreaterThanR(this , e);
0533:                }
0534:            }
0535:
0536:            public Value bopGreaterThanR(Value val,
0537:                    PackagedScriptObjectException e)
0538:                    throws PackagedScriptObjectException {
0539:                return OBoolean.makeBoolean(segment.toString().compareTo(
0540:                        val.castToString()) < 0);
0541:            }
0542:
0543:            /*=======================================================================*/
0544:            /**
0545:             * Perform the "<=" operation.
0546:             * 
0547:             * @param val          the other value
0548:             * @return the result
0549:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0550:             */
0551:            public Value bopLessThanOrEquals(Value val)
0552:                    throws PackagedScriptObjectException {
0553:                try {
0554:                    return OBoolean.makeBoolean(segment.toString().compareTo(
0555:                            val.castToString()) <= 0);
0556:                } catch (PackagedScriptObjectException e) {
0557:                    return val.bopLessThanOrEqualsR(this , e);
0558:                }
0559:            }
0560:
0561:            public Value bopLessThanOrEqualsR(Value val,
0562:                    PackagedScriptObjectException e)
0563:                    throws PackagedScriptObjectException {
0564:                return OBoolean.makeBoolean(segment.toString().compareTo(
0565:                        val.castToString()) >= 0);
0566:            }
0567:
0568:            /*=======================================================================*/
0569:            /**
0570:             * Perform the ">=" operation.
0571:             * 
0572:             * @param val          the other value
0573:             * @return the result
0574:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0575:             */
0576:            public Value bopGreaterThanOrEquals(Value val)
0577:                    throws PackagedScriptObjectException {
0578:                try {
0579:                    return OBoolean.makeBoolean(segment.toString().compareTo(
0580:                            val.castToString()) >= 0);
0581:                } catch (PackagedScriptObjectException e) {
0582:                    return val.bopGreaterThanOrEqualsR(this , e);
0583:                }
0584:            }
0585:
0586:            public Value bopGreaterThanOrEqualsR(Value val,
0587:                    PackagedScriptObjectException e)
0588:                    throws PackagedScriptObjectException {
0589:                return OBoolean.makeBoolean(segment.toString().compareTo(
0590:                        val.castToString()) <= 0);
0591:            }
0592:
0593:            /*=======================================================================*/
0594:            /**
0595:             * Perform the "+" operation.
0596:             * 
0597:             * @param val          the other value
0598:             * @return the result
0599:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0600:             */
0601:            public Value bopPlus(Value val)
0602:                    throws PackagedScriptObjectException {
0603:                // val might well be, for example, a Reference, which will screw up
0604:                // the instanceof below:
0605:                val = val.unhand();
0606:
0607:                try {
0608:                    Segment s;
0609:
0610:                    if (val instanceof  OString) {
0611:                        s = ((OString) val).segment;
0612:                    } else {
0613:                        String str = val.castToString();
0614:
0615:                        if (DEBUG)
0616:                            if (str == null)
0617:                                throw new ProgrammingErrorException(
0618:                                        "this shouldn't happen, val.castToString() returns null for val="
0619:                                                + val + " (" + val.getType()
0620:                                                + ")");
0621:
0622:                        s = new StringSegment(val.castToString());
0623:                    }
0624:
0625:                    return new OString(new ComboSegment(segment, s));
0626:                } catch (PackagedScriptObjectException e) {
0627:                    return val.bopPlusR(this , e);
0628:                }
0629:            }
0630:
0631:            public Value bopPlusR(Value val, PackagedScriptObjectException e)
0632:                    throws PackagedScriptObjectException {
0633:                Segment s = ((val instanceof  OString) ? ((OString) val).segment
0634:                        : new StringSegment(val.castToString()));
0635:                return new OString(new ComboSegment(s, segment));
0636:            }
0637:
0638:            /*=======================================================================*/
0639:            /* The misc operators:
0640:             */
0641:
0642:            /*=======================================================================*/
0643:            /**
0644:             * For types that implement <code>elementAt</code>, this returns the
0645:             * number of elements.  This is the same as the <i>length</i> property
0646:             * of an object.
0647:             * 
0648:             * @return an integer length
0649:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0650:             * @see #elementAt
0651:             */
0652:            public int length() throws PackagedScriptObjectException {
0653:                return segment.length();
0654:            }
0655:
0656:            /*=======================================================================*/
0657:            /**
0658:             * Get the specified index of this object.  This makes a string behave as
0659:             * an array, or at least support array indexing.
0660:             * 
0661:             * @param idx          the index to get
0662:             * @return a string of length one
0663:             * @throws PackagedScriptObjectException(NoSuchMethodException)
0664:             * @see #length
0665:             */
0666:            public Value elementAt(Value oidx)
0667:                    throws PackagedScriptObjectException {
0668:                int idx = (int) (oidx.castToExactNumber());
0669:                checkIndex(idx);
0670:
0671:                return new OString("" + segment.toString().charAt(idx));
0672:            }
0673:
0674:            /*=======================================================================*/
0675:            /**
0676:             * Get the specified range of this object, if this object is an array.  
0677:             * This returns a copy of a range of the array.
0678:             * 
0679:             * @param idx1         the index index of the beginning of the range, inclusive
0680:             * @param idx2         the index of the end of the range, inclusive
0681:             * @return a copy of the specified range of this array
0682:             * @throws PackagedScriptObjectException(NoSuchMemberException)
0683:             * @see #length
0684:             * @see #elementAt
0685:             */
0686:            public Value elementsAt(Value idx1, Value idx2)
0687:                    throws PackagedScriptObjectException {
0688:                return new OString(substring((int) (idx1.castToExactNumber()),
0689:                        (int) (idx2.castToExactNumber()) + 1));
0690:            }
0691:
0692:            /*=======================================================================*/
0693:            /* The regexp operators:
0694:             */
0695:
0696:            /*=======================================================================*/
0697:            /**
0698:             * Returns the same thing as <code>regexp.exec(this)</code>.  The
0699:             * <code>regexp</code> should either be a <code>RegExp</code> object
0700:             * or a string that can be compiled to a <code>RegExp</code> object.
0701:             * <p>
0702:             * Note: this API is modeled after the JavaScript RegExp API, for the 
0703:             * benefit of users already familiar with JavaScript.
0704:             * 
0705:             * @param regexp       the regular expression
0706:             * @return the result of <code>regexp.exec</code>.
0707:             */
0708:            public Value match(Value regexp) {
0709:                return compile(regexp).exec(this );
0710:            }
0711:
0712:            /*=======================================================================*/
0713:            /**
0714:             * Finds a match between a regular expression and this string object, and 
0715:             * replaces the matched substring with a new substring.  The second 
0716:             * parameter can be either a replacement string, or a function called to 
0717:             * determine the replacement string.
0718:             * <p>
0719:             * If the second parameter is a string, the following replacement patterns
0720:             * are evaluated and replaced with the appropriate value:
0721:             * <div id="regtable"><table>
0722:             *    <tr><th>pattern</th><th>Description</th></tr>
0723:             *    <tr><td><code>$$</code></td> <td>Inserts a <code>$</code></td></tr>
0724:             *    <tr><td><code>$&</code></td> <td>Inserts the matched substring</td></tr>
0725:             *    <tr><td><code>$`</code></td> <td>Inserts the portion of the string that precedes the matched substring</td></tr>
0726:             *    <tr><td><code>$'</code></td> <td>Inserts the portion of the string that follows the matched substring</td></tr>
0727:             *    <tr><td><code>$</code>n</td> <td>Inserts the nth parenthesized submatch string</td></tr>
0728:             * </table></div>
0729:             * If the second parameter is a function, it is called with the following
0730:             * parameters:
0731:             * <div id="regtable"><table>
0732:             *    <tr><th>param</th><th>Description</th></tr>
0733:             *    <tr><td>0</td>   <td>the matched string</td></tr>
0734:             *    <tr><td>1-n</td> <td>zero or more parameters for parenthetical matches</td></tr>
0735:             *    <tr><td>n+1</td> <td>offset of match</td></tr>
0736:             *    <tr><td>n+2</td> <td>the original string</td></tr>
0737:             * </table></div>
0738:             * <p>
0739:             * Note: this API is modeled after the JavaScript RegExp API, for the 
0740:             * benefit of users already familiar with JavaScript.
0741:             * 
0742:             * @param regexp       the regular expression
0743:             * @param strOrFxn     replacement string or function
0744:             * @return the resulting string
0745:             */
0746:            public Value replace(Value regexp, Value strOrFxn) {
0747:                RegExp re = compile(regexp);
0748:
0749:                // XXX not sure if this should always replace all, or only if /g flag on regexp?
0750:                RegExpResult r = re.exec(this );
0751:
0752:                int idx = (int) (r.getIndex().castToExactNumber());
0753:                if (idx != -1) {
0754:                    Value match = r.elementAt(JavaBridge
0755:                            .convertToScriptObject(0));
0756:                    int len = match.length();
0757:
0758:                    String pre = substring(0, idx);
0759:                    String post = substring(idx + len, length());
0760:                    String replace;
0761:
0762:                    if (strOrFxn instanceof  Function) {
0763:                        int n = r.length();
0764:                        Value[] args = new Value[n + 2];
0765:                        for (int i = 0; i < n; i++)
0766:                            args[i] = r.elementAt(JavaBridge
0767:                                    .convertToScriptObject(i));
0768:                        args[n] = JavaBridge.convertToScriptObject(idx);
0769:                        args[n + 1] = r.getInput();
0770:                        replace = strOrFxn.callAsFunction(args).castToString();
0771:                    } else {
0772:                        String str = strOrFxn.castToString();
0773:
0774:                        // handle replacement patterns:
0775:                        int escaped = 0;
0776:                        int n = -1;
0777:
0778:                        for (int i = 0; i < str.length(); i++) {
0779:                            char c = str.charAt(i);
0780:
0781:                            if (escaped > 0) {
0782:                                String a = null;
0783:
0784:                                if (n == -1) {
0785:                                    switch (c) {
0786:                                    case '$':
0787:                                        a = "$";
0788:                                        escaped++;
0789:                                        break;
0790:                                    case '&':
0791:                                        a = match.castToString();
0792:                                        escaped++;
0793:                                        break;
0794:                                    case '`':
0795:                                        a = substring(0, idx);
0796:                                        escaped++;
0797:                                        break;
0798:                                    case '\'':
0799:                                        a = substring(idx + len, length());
0800:                                        escaped++;
0801:                                        break;
0802:                                    default:
0803:                                        if (Character.isDigit(c)) {
0804:                                            n = Character.digit(c, 10);
0805:                                            escaped++;
0806:                                        }
0807:                                    }
0808:                                } else {
0809:                                    if (Character.isDigit(c)) {
0810:                                        n = (n * 10) + Character.digit(c, 10);
0811:                                        escaped++;
0812:                                    } else {
0813:                                        a = r
0814:                                                .elementAt(
0815:                                                        JavaBridge
0816:                                                                .convertToScriptObject(n))
0817:                                                .castToString();
0818:                                        i -= 1;
0819:                                    }
0820:                                }
0821:
0822:                                if (a != null) {
0823:                                    str = str.substring(0, i - escaped + 1) + a
0824:                                            + str.substring(i + 1);
0825:                                    i += a.length() - escaped;
0826:                                    escaped = 0;
0827:                                    n = -1;
0828:                                }
0829:                            } else if (c == '$') {
0830:                                escaped = 1;
0831:                            }
0832:                        }
0833:
0834:                        if (n != -1) {
0835:                            String a = r.elementAt(
0836:                                    JavaBridge.convertToScriptObject(n))
0837:                                    .castToString();
0838:                            ;
0839:                            str = str.substring(0, str.length() - escaped) + a;
0840:                        }
0841:
0842:                        replace = str;
0843:                    }
0844:
0845:                    // XXX use StringSegments..
0846:                    return new OString(pre + replace + post);
0847:                }
0848:
0849:                return this ;
0850:            }
0851:
0852:            /*=======================================================================*/
0853:            /**
0854:             * Executes the search for a match between a regular expression and this 
0855:             * string object.
0856:             * <p>
0857:             * Note: this API is modeled after the JavaScript RegExp API, for the 
0858:             * benefit of users already familiar with JavaScript.
0859:             * 
0860:             * @param regexp       the regular expression
0861:             * @return the index of the match, or <code>-1</code> if none
0862:             */
0863:            public Value search(Value regexp) {
0864:                return compile(regexp).exec(this ).getIndex();
0865:            }
0866:
0867:            /**
0868:             * utility function to compile a string to a RegExp, or if it is already
0869:             * a RegExp, cast and return...
0870:             */
0871:            private static final RegExp compile(Value regexp) {
0872:                if (regexp instanceof  RegExp)
0873:                    return (RegExp) regexp;
0874:                else
0875:                    return RegExp.createRegExp(regexp);
0876:            }
0877:
0878:            /*=======================================================================*/
0879:            /* The string operators:
0880:             */
0881:
0882:            public String substring(int begIdx) {
0883:                checkIndex(begIdx);
0884:                return segment.toString().substring(begIdx);
0885:            }
0886:
0887:            public String substring(int begIdx, int endIdx) {
0888:                if (begIdx < 0)
0889:                    throw PackagedScriptObjectException
0890:                            .makeExceptionWrapper(new OIllegalArgumentException(
0891:                                    "bad index: " + begIdx + ", length="
0892:                                            + length()));
0893:                if (endIdx > length())
0894:                    throw PackagedScriptObjectException
0895:                            .makeExceptionWrapper(new OIllegalArgumentException(
0896:                                    "bad index: " + endIdx + ", length="
0897:                                            + length()));
0898:                if (begIdx > endIdx)
0899:                    throw PackagedScriptObjectException
0900:                            .makeExceptionWrapper(new OIllegalArgumentException(
0901:                                    "bad index: " + (endIdx - begIdx)
0902:                                            + ", length=" + length()));
0903:
0904:                return segment.toString().substring(begIdx, endIdx);
0905:            }
0906:
0907:            public int indexOf(String str) {
0908:                return segment.toString().indexOf(str);
0909:            }
0910:
0911:            public int indexOf(String str, int fromIdx) {
0912:                checkIndex(fromIdx);
0913:                return segment.toString().indexOf(str, fromIdx);
0914:            }
0915:
0916:            public int lastIndexOf(String str) {
0917:                return segment.toString().lastIndexOf(str);
0918:            }
0919:
0920:            public int lastIndexOf(String str, int fromIdx) {
0921:                checkIndex(fromIdx);
0922:                return segment.toString().lastIndexOf(str, fromIdx);
0923:            }
0924:
0925:            public String toUpperCase() {
0926:                return segment.toString().toUpperCase();
0927:            }
0928:
0929:            public String toLowerCase() {
0930:                return segment.toString().toLowerCase();
0931:            }
0932:
0933:            public boolean startsWith(String str) {
0934:                return segment.toString().startsWith(str);
0935:            }
0936:
0937:            public boolean endsWith(String str) {
0938:                return segment.toString().endsWith(str);
0939:            }
0940:
0941:            public String trim() {
0942:                return segment.toString().trim();
0943:            }
0944:
0945:            public String[] split(String regex) {
0946:                return segment.toString().split(regex);
0947:            }
0948:
0949:            public String[] split(String regex, int limit) {
0950:                return segment.toString().split(regex, limit);
0951:            }
0952:
0953:            private final void checkIndex(int idx) {
0954:                if (!((0 <= idx) && (idx < length())))
0955:                    throw PackagedScriptObjectException
0956:                            .makeExceptionWrapper(new OIllegalArgumentException(
0957:                                    "bad index: " + idx + ", length="
0958:                                            + length()));
0959:            }
0960:
0961:            /*=======================================================================*/
0962:            /*=======================================================================*/
0963:            /*=======================================================================*/
0964:
0965:            /**
0966:             * Return an intern'd OString....  document this better!
0967:             */
0968:            public static final OString makeString(String str) {
0969:                return makeString(null, str);
0970:            }
0971:
0972:            private static Hashtable interndTable; // key is str, val is ostr
0973:
0974:            private static final synchronized OString makeString(OString ostr,
0975:                    String str) {
0976:                if (interndTable == null)
0977:                    interndTable = new Hashtable();
0978:
0979:                str = str.intern(); // XXX
0980:                OString val = (OString) (interndTable.get(str));
0981:
0982:                if (val == null) {
0983:                    if (ostr != null)
0984:                        val = ostr;
0985:                    else
0986:                        val = new OString(str);
0987:
0988:                    interndTable.put(str, val);
0989:                }
0990:
0991:                return val;
0992:            }
0993:
0994:            public static final String chop(String str) {
0995:                int idx = str.indexOf('\\');
0996:
0997:                if (idx == -1) {
0998:                    return str;
0999:                } else {
1000:                    char[] value = str.toCharArray();
1001:                    int len = value.length;
1002:                    StringBuffer sb = new StringBuffer(value.length);
1003:                    int lastIdx = 0;
1004:
1005:                    for (; idx < value.length - 1; idx++) {
1006:                        if (value[idx] == '\\') {
1007:                            char c = value[idx + 1];
1008:
1009:                            if (c == 'n')
1010:                                value[idx] = '\n';
1011:                            else if (c == 't')
1012:                                value[idx] = '\t';
1013:                            else if (c == 'b')
1014:                                value[idx] = '\b';
1015:                            else if (c == 'f')
1016:                                value[idx] = '\f';
1017:                            else if (c == 'r')
1018:                                value[idx] = '\r';
1019:                            else
1020:                                value[idx] = c;
1021:
1022:                            sb.append(value, lastIdx, ++idx - lastIdx);
1023:                            lastIdx = idx + 1;
1024:                        }
1025:                    }
1026:
1027:                    return sb.append(value, lastIdx, value.length - lastIdx)
1028:                            .toString();
1029:                }
1030:            }
1031:
1032:            /*=======================================================================*/
1033:            /*=======================================================================*/
1034:            /*=======================================================================*/
1035:
1036:            /**
1037:             * The actual string contents.  This abstraction enables us to perform
1038:             * some optimizations for string addition.
1039:             * <p>
1040:             * As a performance optimization, to speed up the performance of string
1041:             * addition (concationation), strings can be comprised of "string-segments"
1042:             * which get lazily converted to an actual string. 
1043:             */
1044:            private static abstract class Segment implements 
1045:                    java.io.Serializable {
1046:                abstract public int hashCode();
1047:
1048:                abstract public String toString();
1049:
1050:                abstract protected int length();
1051:
1052:                abstract protected void appendTo(StringBuffer sb);
1053:            }
1054:
1055:            private static class StringSegment extends Segment {
1056:                private String stringVal;
1057:                private int hashCode;
1058:
1059:                StringSegment(String stringVal) {
1060:                    this .stringVal = stringVal;
1061:                }
1062:
1063:                public int hashCode() {
1064:                    if (hashCode == 0)
1065:                        hashCode = stringVal.hashCode();
1066:                    return hashCode;
1067:                }
1068:
1069:                public String toString() {
1070:                    return stringVal;
1071:                }
1072:
1073:                protected int length() {
1074:                    return stringVal.length();
1075:                }
1076:
1077:                protected void appendTo(StringBuffer sb) {
1078:                    sb.append(stringVal);
1079:                }
1080:            }
1081:
1082:            private static class ComboSegment extends Segment {
1083:                private Segment s1;
1084:                private Segment s2;
1085:
1086:                private String stringVal = null; // cache combined s1+s2
1087:                private int hashCode; // cache hashcode
1088:
1089:                ComboSegment(Segment s1, Segment s2) {
1090:                    this .s1 = s1;
1091:                    this .s2 = s2;
1092:                }
1093:
1094:                public int hashCode() {
1095:                    if (stringVal == null)
1096:                        flatten();
1097:                    if (hashCode == 0)
1098:                        hashCode = stringVal.hashCode();
1099:                    return hashCode;
1100:                }
1101:
1102:                public String toString() {
1103:                    if (stringVal == null)
1104:                        flatten();
1105:                    return stringVal;
1106:                }
1107:
1108:                protected synchronized int length() {
1109:                    if (stringVal == null)
1110:                        return s1.length() + s2.length();
1111:                    else
1112:                        return stringVal.length();
1113:                }
1114:
1115:                protected synchronized void appendTo(StringBuffer sb) {
1116:                    if (stringVal == null) {
1117:                        s1.appendTo(sb);
1118:                        s2.appendTo(sb);
1119:                    } else {
1120:                        sb.append(stringVal);
1121:                    }
1122:                }
1123:
1124:                private synchronized void flatten() {
1125:                    if (stringVal == null) // do check here to, cause it's sync'd
1126:                    {
1127:                        StringBuffer sb = new StringBuffer(length());
1128:                        appendTo(sb);
1129:                        String tmp = sb.toString();
1130:
1131:                        stringVal = tmp; /* this step has to be last, because
1132:                         * an unsynchronized access to stringVal
1133:                         * is used to determin if init() is
1134:                         * complete... weird, but avoids needing
1135:                         * a state variable in an object we want
1136:                         * to keep lightweight.
1137:                         */
1138:                        s1 = s2 = null; /* post-flatten cleanup, allow to be GC'd
1139:                         */
1140:                    }
1141:                }
1142:            }
1143:        }
1144:
1145:        /*
1146:         *   Local Variables:
1147:         *   tab-width: 2
1148:         *   indent-tabs-mode: nil
1149:         *   mode: java
1150:         *   c-indentation-style: java
1151:         *   c-basic-offset: 2
1152:         *   eval: (c-set-offset 'substatement-open '0)
1153:         *   eval: (c-set-offset 'case-label '+)
1154:         *   eval: (c-set-offset 'inclass '+)
1155:         *   eval: (c-set-offset 'inline-open '0)
1156:         *   End:
1157:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.