KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > es > ESString


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.es;
30
31 import com.caucho.util.CharBuffer;
32 import com.caucho.util.IntMap;
33
34 import java.text.CharacterIterator JavaDoc;
35
36 /**
37  * Implementation class for JavaScript strings.
38  */

39 public class ESString extends ESBase {
40   static ESId NULL;
41   static ESId LENGTH;
42   private static ESId ints[];
43
44   protected String JavaDoc string;
45   protected int hashCode;
46
47   /**
48    * Create a new object based on a prototype
49    */

50   protected ESString(String JavaDoc string)
51   {
52     if (ints == null) {
53       ints = new ESId[128];
54       NULL = ESId.intern("");
55       LENGTH = ESId.intern("length");
56
57       for (int i = 0; i < ints.length; i++)
58     ints[i] = ESId.intern(String.valueOf(i));
59     }
60
61     prototype = esNull;
62     this.string = string;
63   }
64
65   public static ESString create(String JavaDoc string)
66   {
67     return string == null ? NULL : new ESString(string);
68   }
69
70   public static ESBase toStr(String JavaDoc string)
71   {
72     return string == null ? esNull : new ESString(string);
73   }
74
75   public static ESString create(int i)
76   {
77     if (i >= 0 && i < ints.length)
78       return ints[i];
79
80     return new ESString(String.valueOf(i));
81   }
82
83   public static ESString createFromCharCode(char c)
84   {
85     return new ESString(String.valueOf((char) c));
86   }
87
88   public static ESString create(CharBuffer cb)
89   {
90     return new ESString(cb.toString());
91   }
92
93   /**
94    * Create a new string from a java object.
95    */

96   public static ESString create(Object JavaDoc obj)
97   {
98     return new ESString(String.valueOf(obj));
99   }
100
101   public ESBase typeof() throws ESException
102   {
103     return ESString.create("string");
104   }
105
106   public Class JavaDoc getJavaType()
107   {
108     return String JavaDoc.class;
109   }
110
111   public double toNum()
112   {
113     return parseFloat(this, true);
114   }
115
116   public ESString toStr()
117   {
118     return this;
119   }
120
121   public boolean isString()
122   {
123     return true;
124   }
125
126   public ESString toSource(IntMap map, boolean isLoopPass)
127   {
128     if (isLoopPass)
129       return null;
130
131     return ESString.create("\"" + string + "\"");
132   }
133
134   public ESObject toObject()
135   {
136     ESObject obj = new ESWrapper("String", Global.getGlobalProto().stringProto, this);
137
138     obj.put(LENGTH, ESNumber.create(this.string.length()),
139         DONT_ENUM|DONT_DELETE|READ_ONLY);
140
141     return obj;
142   }
143
144   public Object JavaDoc toJavaObject()
145   {
146     return string;
147   }
148
149   public ESBase getProperty(ESString key) throws Throwable JavaDoc
150   {
151     if (key.equals(LENGTH))
152       return ESNumber.create(this.string.length());
153     else
154       return Global.getGlobalProto().stringProto.getProperty(key);
155   }
156
157   public boolean ecmaEquals(ESBase b) throws Throwable JavaDoc
158   {
159     if (b == esNull)
160       return false;
161     else if (b instanceof ESString)
162       return string.equals(((ESString) b).string);
163     else if (b instanceof ESObject) {
164       ESBase pb = b.toPrimitive(NONE);
165       if (pb instanceof ESString)
166     return equals(pb);
167       else
168     return toNum() == pb.toNum();
169     } else {
170       return toNum() == b.toNum();
171     }
172   }
173
174   public ESBase plus(ESBase b) throws Throwable JavaDoc
175   {
176     ESBase prim = b.toPrimitive(NONE);
177
178     return ESString.create(string + prim.toStr().toString());
179   }
180
181   char charAt(int i) { return string.charAt(i); }
182
183   public char carefulCharAt(int i)
184   {
185     if (i >= string.length())
186       return CharacterIterator.DONE;
187     else
188       return string.charAt(i);
189   }
190
191   int length() { return string.length(); }
192
193   boolean regionMatches(int i, String JavaDoc test, int j, int len)
194   {
195     return string.regionMatches(i, test, j, len);
196   }
197
198   public int hashCode()
199   {
200     int hash = hashCode;
201
202     if (hash != 0)
203       return hash;
204
205     hash = 1021;
206     int len = string.length();
207
208     for (int i = 0; i < len; i++)
209       hash = 65521 * hash + (string.charAt(i) + 1) * 251;
210
211     hashCode = hash;
212
213     return hash;
214   }
215
216   public boolean equals(Object JavaDoc a)
217   {
218     if (this == a)
219       return true;
220     else if (a instanceof ESString)
221       return string.equals(((ESString) a).string);
222     else
223       return false;
224   }
225
226   int compareTo(ESString b)
227   {
228     return string.compareTo(b.string);
229   }
230
231   int indexOf(ESString a, int pos) { return string.indexOf(a.string, pos); }
232   int lastIndexOf(ESString a, int pos)
233   {
234     return string.lastIndexOf(a.string, pos);
235   }
236
237   ESString substring(int begin, int end)
238   {
239     return ESString.create(string.substring(begin, end));
240   }
241
242   ESString substring(int begin)
243   {
244     return substring(begin, string.length());
245   }
246
247   ESString toLowerCase()
248   {
249     return ESString.create(string.toLowerCase());
250   }
251
252   ESString toUpperCase()
253   {
254     return ESString.create(string.toUpperCase());
255   }
256
257   ESBoolean contains(ESBase b) throws Throwable JavaDoc
258   {
259     ESString sb = b.toStr();
260     if (sb.string.length() == 0)
261       return ESBoolean.TRUE;
262
263     int len = string.length();
264     for (int i = 0; i <= len; i++) {
265       if (string.regionMatches(i, sb.string, 0, sb.length()))
266     return ESBoolean.TRUE;
267     }
268
269     return ESBoolean.FALSE;
270   }
271
272   ESBoolean startsWith(ESBase b) throws Throwable JavaDoc
273   {
274     ESString sb = b.toStr();
275
276     return ESBoolean.create(string.startsWith(sb.string));
277   }
278
279   ESBoolean endsWith(ESBase b) throws Throwable JavaDoc
280   {
281     ESString sb = b.toStr();
282
283     return ESBoolean.create(string.endsWith(sb.string));
284   }
285
286   public boolean toBoolean()
287   {
288     return string.length() != 0;
289   }
290
291   static boolean isWhitespace(int ch)
292   {
293     switch (ch) {
294     case ' ': case '\t': case '\n': case '\r': case 0x0b: case '\f':
295       return true;
296
297     default:
298       return false;
299     }
300   }
301
302   static double checkTail(double value, ESString string, int i)
303   {
304     for (; i < string.length(); i++) {
305       if (! isWhitespace(string.charAt(i))) {
306     return 0.0/0.0;
307       }
308     }
309
310     return value;
311   }
312
313   static double parseFloat(ESString string, boolean hexOkay)
314   {
315     int len = string.length();
316
317     int i = 0;
318     int ch = 0;
319     for (; i < len && isWhitespace(string.charAt(i)); i++) {
320     }
321
322     if (i >= len)
323       return hexOkay ? 0 : 0.0/0.0;
324
325     int radix = 10;
326     if (hexOkay && i + 1 < len && (ch = string.charAt(i)) == '0' &&
327     ((ch = string.charAt(i + 1)) == 'x' || ch == 'X')) {
328       i += 2;
329       radix = 16;
330     }
331
332     int sign = 1;
333     if (radix == 10 && i < len && (ch = string.charAt(i)) == '+') {
334       i++;
335     } else if (radix == 10 && i < len && ch == '-') {
336       sign = -1;
337       i++;
338     }
339
340     if (radix == 10 && string.regionMatches(i, "Infinity", 0, 8)) {
341       if (hexOkay)
342     return checkTail(sign * (1.0/0.0), string, i + 8);
343       else
344     return sign * (1.0/0.0);
345     }
346     double value = 0.0;
347     boolean hasDigit = false;
348     for (; i < len; i++) {
349       ch = string.charAt(i);
350
351       if ('0' <= ch && ch <= '9') {
352     value = radix * value + string.charAt(i) - '0';
353     hasDigit = true;
354       } else if (radix > 10 && ('a' <= ch && ch <= 'a' + radix - 11)) {
355     value = radix * value + string.charAt(i) - 'a' + 10;
356     hasDigit = true;
357       } else if (radix > 10 && ('A' <= ch && ch <= 'A' + radix - 11)) {
358     value = radix * value + string.charAt(i) - 'A' + 10;
359     hasDigit = true;
360       } else
361     break;
362     }
363
364     if (radix == 16 && ! hasDigit)
365       return 0.0/0.0;
366     else if (radix == 16)
367       return checkTail(value, string, i);
368
369     int expt = 0;
370     if (i < len && string.charAt(i) == '.') {
371       i++;
372
373       int power = 1;
374       for (; i < len && (ch = string.charAt(i)) >= '0' && ch <= '9'; i++) {
375     if (ch == '0')
376       power++;
377     else {
378       value = value * Math.pow(10, power) + ch - '0';
379       expt -= power;
380       power = 1;
381     }
382     hasDigit = true;
383       }
384     }
385
386     if (! hasDigit)
387       return 0.0/0.0;
388
389     if (i < len && ((ch = string.charAt(i)) == 'e' || ch == 'E')) {
390       i++;
391       int exptSign = 1;
392       if (i < len && (ch = string.charAt(i)) == '+')
393     i++;
394       else if (i < len && ch == '-') {
395     exptSign = -1;
396     i++;
397       }
398
399       hasDigit = false;
400
401       int newExpt = 0;
402       for (; i < len && (ch = string.charAt(i)) >= '0' && ch <= '9'; i++) {
403     newExpt = 10 * newExpt + ch - '0';
404     hasDigit = true;
405       }
406
407       if (! hasDigit)
408     return 0.0/0.0;
409
410       expt += exptSign * newExpt;
411     }
412
413     if (expt < 0)
414       value = sign * value / Math.pow(10.0, -expt);
415     else
416       value = sign * value * Math.pow(10.0, expt);
417
418     if (hexOkay)
419       return checkTail(value, string, i);
420     else
421       return value;
422   }
423
424   static double parseFloat(ESString string)
425   {
426     return parseFloat(string, false);
427   }
428
429   /**
430    * Returns this as a string.
431    */

432   public String JavaDoc toString()
433   {
434     return string;
435   }
436 }
437
Popular Tags