Merge branch 'master' of https://source.jalview.org/git/jalviewjs.git
[jalviewjs.git] / site / j2s / java / lang / String.js
1 Clazz.load (["java.lang.CharSequence", "$.Comparable", "java.io.Serializable", "java.util.Comparator"], "java.lang.String", null, function () {
2 if (String.prototype.$replace == null) { // not defined yet! ClazzLoader may try to load this twice!
3 java.lang.String = String;
4 if (Clazz.supportsNativeObject) {
5         for (var i = 0; i < Clazz.extendedObjectMethods.length; i++) {
6                 var p = Clazz.extendedObjectMethods[i];
7                 if ("to$tring" == p || "toString" == p || "equals" == p || "hashCode" == p) {
8                         continue;
9                 }
10                 String.prototype[p] = Clazz._O.prototype[p];
11         }
12 }
13 //Clazz.decorateAsType (String, "String", null, [java.io.Serializable, CharSequence, Comparable]);
14 Clazz.implementOf (String, [java.io.Serializable, CharSequence, Comparable]);
15 //Number.equals = Clazz.innerFunctions.equals;
16 String.getName = Clazz.innerFunctions.getName;
17
18 String.serialVersionUID = String.prototype.serialVersionUID = -6849794470754667710;
19
20 String.prototype.$replace = function (c1, c2) {
21         /*
22         var sp = "\\$.*+{}?^()[]";
23         if (sp.indexOf (c1) != -1) {
24                 c1 = "\\" + c1;
25         }
26         */
27         c1 = c1.replace (/([\\\/\$\.\*\+\{\}\?\^\(\)\[\]])/g, function ($0, $1) {
28                 return "\\" + $1;
29         });
30         var regExp = new RegExp (c1, "gm");
31         return this.replace (regExp, c2);
32 };
33 String.prototype.$generateExpFunction = function (str) {
34         var arr = [];
35         var orders = [];
36         var idx = 0;
37         arr[0] = "";
38         var i = 0;
39         for (; i < str.length; i++) {
40                 var ch = str.charAt (i);
41                 if (i != str.length - 1 && ch == '\\') {
42                         i++;
43                         var c = str.charAt (i);
44                         if (c == '\\') {
45                                 arr[idx] += '\\';
46                         }
47                         arr[idx] += c;
48                 } else if (i != str.length - 1 && ch == '$') {
49                         i++;
50                         orders[idx] = parseInt (str.charAt (i));
51                         idx++;
52                         arr[idx] = "";
53                 } else if (ch == '\r') {
54                         arr[idx] += "\\r";
55                 } else if (ch == '\n') {
56                         arr[idx] += "\\n";
57                 } else if (ch == '\t') {
58                         arr[idx] += "\\t";
59                 } else if (ch == '\"') {
60                         arr[idx] += "\\\"";
61                 } else {
62                         arr[idx] += ch;
63                 }
64         }
65         var funStr = "f = function (";
66         var max = Math.max.apply({},orders);
67         for (i = 0; i <= max; i++) {
68                 funStr += "$" + i;
69                 if (i != max) {
70                         funStr += ", ";
71                 }
72         }
73         funStr += ") { return ";
74         for (i = 0; i < arr.length - 1; i++) {
75                 funStr += "\"" + arr[i] + "\" + $" + orders[i] + " + ";
76         }
77         funStr += "\"" + arr[i] + "\"; }";
78         var f = null;
79         eval (funStr)
80         return f;
81 };
82
83 String.prototype.replaceAll = function (exp, str) {
84         var regExp = new RegExp (exp, "gm");
85         return this.replace (regExp, this.$generateExpFunction (str));
86 };
87 String.prototype.replaceFirst = function (exp, str) {
88         var regExp = new RegExp (exp, "m");
89         return this.replace (regExp, this.$generateExpFunction (str));
90 };
91 String.prototype.matches = function (exp) {
92         if (exp != null) {
93                 exp = "^(" + exp + ")$";
94         }
95         var regExp = new RegExp (exp, "gm");
96         var m = this.match (regExp);
97         return m != null && m.length != 0;
98 };
99 String.prototype.regionMatches = function (ignoreCase, toffset,
100                 other, ooffset, len) {
101         /*
102          * Support different method signatures
103          */
104         if (typeof ignoreCase == "number"
105                         || (ignoreCase != true && ignoreCase != false)) {
106                 len = ooffset;
107                 ooffset = other;
108                 other = toffset;
109                 toffset = ignoreCase;
110                 ignoreCase = false;
111         }
112         var to = toffset;
113         var po = ooffset;
114         // Note: toffset, ooffset, or len might be near -1>>>1.
115         if ((ooffset < 0) || (toffset < 0) || (toffset > this.length - len) ||
116                         (ooffset > other.length - len)) {
117                 return false;
118         }
119         var s1 = this.substring (toffset, toffset + len);
120         var s2 = other.substring (ooffset, ooffset + len);
121         if (ignoreCase) {
122                 s1 = s1.toLowerCase ();
123                 s2 = s2.toLowerCase ();
124         }
125         return s1 == s2;
126 };
127 String.prototype.$plit = function (regex, limit) {
128         /*
129          * Support different method signatures
130          */
131         if (limit != null && limit > 0) {
132                 if (limit == 1) {
133                         return this;
134                 }
135                 var regExp = new RegExp ("(" + regex + ")", "gm");
136                 var count = 1;
137                 var s = this.replace (regExp, function ($0, $1) {
138                         count++;
139                         if (count == limit) {
140                                 return "@@_@@";
141                         } else if (count > limit) {
142                                 return $0;
143                         } else {
144                                 return $0;
145                         }
146                 });
147                 regExp = new RegExp (regex, "gm");
148                 var arr = this.split (regExp);
149                 if (arr.length > limit) {
150                         arr[limit - 1] = s.substring (s.indexOf ("@@_@@") + 5);
151                         arr.length = limit;
152                 }
153                 return arr;
154         } else {
155                 var regExp = new RegExp (regex, "gm");
156                 return this.split (regExp);
157         }
158 };
159
160 String.prototype.trim = function () {
161         var len = this.length;
162         var st = 0;
163
164         while ((st < len) && (this.charAt (st) <= ' ')) {
165             st++;
166         }
167         while ((st < len) && (this.charAt (len - 1) <= ' ')) {
168             len--;
169         }
170         return ((st > 0) || (len < len)) ? this.substring (st, len) : this;
171 };
172
173 String.prototype.trim = function () {
174         return this.replace (/^\s+/g, '').replace (/\s+$/g, '');
175 };
176
177 /* private */
178 String.prototype.startsWith_string_number = function (prefix, toffset) {
179         var to = toffset;
180         var po = 0;
181         var pc = prefix.length;
182         // Note: toffset might be near -1>>>1.
183         if ((toffset < 0) || (toffset > this.length - pc)) {
184             return false;
185         }
186         while (--pc >= 0) {
187             if (this.charAt (to++) != prefix.charAt (po++)) {
188                 return false;
189             }
190         }
191         return true;
192 };
193
194 String.prototype.startsWith = function (prefix) { /* prefix, toffset */
195         if (arguments.length == 1) {
196                 return this.startsWith_string_number (arguments[0], 0);
197         } else if (arguments.length == 2) {
198                 return this.startsWith_string_number (arguments[0], arguments[1]);
199         } else {
200                 return false;
201         }
202 };
203
204 String.prototype.endsWith = function (suffix) {
205         return this.startsWith (suffix, this.length - suffix.length);
206 };
207
208 String.prototype.equals = function (anObject) {
209         return this.valueOf () == anObject;
210 };
211
212 String.prototype.equalsIgnoreCase = function (anotherString) {
213         return (anotherString == null) ? false : (this == anotherString 
214                         || this.toLowerCase () == anotherString.toLowerCase ());
215 };
216
217 /* private */
218 String.prototype.hash = 0;
219
220 String.prototype.hashCode = function () {
221         var h = this.hash;
222         if (h == 0) {
223                 var off = 0;
224                 var len = this.length;
225                 for (var i = 0; i < len; i++) {
226                         h = 31*h + this.charCodeAt (off++);
227                         h &= 0xffffffff;
228                 }
229                 this.hash = h;
230         }
231     return h;
232 };
233
234 String.prototype.getBytes = function () {
235         if (arguments.length == 4) {
236                 return this.getChars (arguments[0], arguments[1], arguments[2], arguments[3]);
237         }
238         var s = this;
239         if (arguments.length == 1) {
240                 var cs = arguments[0].toString().toLowerCase ();
241                 var charset = [
242                         "utf-8", "UTF8", "us-ascii", "iso-8859-1", "8859_1", "gb2312", "gb18030", "gbk"
243                 ];
244                 var existed = false;
245                 for (var i = 0; i < charset.length; i++) {
246                         if (charset[i] == cs) {
247                                 existed = true;
248                                 break;
249                         }
250                 }
251                 if (!existed) {
252                         throw new java.io.UnsupportedEncodingException ();
253                 }
254                 if (cs == "utf-8" || cs == "utf8") {
255                         s = Encoding.convert2UTF8 (this);
256                 }
257         }
258         var arrs = new Array (s.length);
259         var c = 0, ii = 0;
260         for (var i = 0; i < s.length; i++) {
261                 c = s.charCodeAt (i);
262                 if (c > 255) {
263                         arrs[ii] = 0x1a;
264                         arrs[ii + 1] = c & 0xff;
265                         arrs[ii + 2] = (c & 0xff00) >> 8;
266                         ii+=2;
267                 } else {
268                         arrs[ii] = c;
269                 }
270                 ii++;
271         }
272         return arrs;
273 };
274
275 String.prototype.compareTo = function (anotherString) {
276         if (anotherString == null) {
277                 throw new java.lang.NullPointerException ();
278         }
279         var len1 = this.length;
280         var len2 = anotherString.length;
281         var n = Math.min (len1, len2);
282         var k = 0;
283     while (k < n) {
284                 var c1 = this.charCodeAt (k);
285                 var c2 = anotherString.charCodeAt (k);
286                 if (c1 != c2) {
287                         return c1 - c2;
288                 }
289                 k++;
290         }
291         return len1 - len2;
292 };
293
294 String.prototype.toCharArray = function () {
295         var result = new Array (this.length);
296         for (var i = 0; i < this.length; i++) {
297                 result[i] = this.charAt (i);
298         }
299         return result;
300 };
301 String.value0f = String.valueOf;
302 String.valueOf = function (o) {
303         if (o == "undefined") {
304                 return String.value0f ();
305         }
306         if (o instanceof Array) {
307                 if (arguments.length == 1) {
308                         return o.join ('');
309                 } else {
310                         var off = arguments[1];
311                         var len = arguments[2];
312                         var oo = new Array (len);
313                         for (var i = 0; i < len; i++) {
314                                 oo[i] = o[off + i];
315                         }
316                         return oo.join ('');
317                 }
318         }
319         return "" + o;
320 };
321
322 String.prototype.subSequence = function (beginIndex, endIndex) {
323         return this.substring(beginIndex, endIndex);
324 };
325
326 String.prototype.compareToIgnoreCase = function (str) {
327         if (str == null) {
328                 throw new NullPointerException ();
329         }
330         var s1 = this.toUpperCase ();
331         var s2 = str.toUpperCase ();
332         if (s1 == s2) {
333                 return 0;
334         } else {
335                 var s1 = this.toLowerCase ();
336                 var s2 = str.toLowerCase ();
337                 if (s1 == s2) {
338                         return 0;
339                 } else if (s1 > s2) {
340                         return 1;
341                 } else {
342                         return -1;
343                 }
344         }
345 };
346
347 String.prototype.contentEquals = function (sb) {
348         if (this.length != sb.length ()) {
349                 return false;
350         }
351         var v = sb.getValue ();
352         var i = 0;
353         var j = 0;
354         var n = this.length;
355         while (n-- != 0) {
356                 if (this.charCodeAt (i++) != v[j++]) {
357                         return false;
358                 }
359         }
360         return true;
361 };
362
363 String.prototype.getChars = function (srcBegin, srcEnd, dst, dstBegin) {
364         if (srcBegin < 0) {
365                 throw new StringIndexOutOfBoundsException(srcBegin);
366         }
367         if (srcEnd > this.length) {
368                 throw new StringIndexOutOfBoundsException(srcEnd);
369         }
370         if (srcBegin > srcEnd) {
371                 throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
372         }
373         if (dst == null) {
374                 throw new NullPointerException ();
375         }
376         for (var i = 0; i < srcEnd - srcBegin; i++) {
377                 dst[dstBegin + i] = this.charAt (srcBegin + i);
378         }
379 };
380 String.prototype.$concat = String.prototype.concat;
381 String.prototype.concat = function (s) {
382         if (s == null) {
383                 throw new NullPointerException ();
384         }
385         return this.$concat (s);
386 };
387
388 String.prototype.$lastIndexOf = String.prototype.lastIndexOf;
389 String.prototype.lastIndexOf = function (s, last) {
390         if (last != null && last + this.length <= 0) {  
391                 return -1;
392         }
393         if (last != null) {
394                 return this.$lastIndexOf (s, last);
395         } else {
396                 return this.$lastIndexOf (s);
397         }
398 };
399
400 String.prototype.intern = function () {
401         return this.valueOf ();
402 };
403 String.copyValueOf = String.prototype.copyValueOf = function () {
404         if (arguments.length == 1) {
405                 return String.instantialize (arguments[0]);
406         } else {
407                 return String.instantialize (arguments[0], arguments[1], arguments[2]);
408         }
409 };
410 String.indexOf = function (source, sourceOffset, sourceCount,
411                 target, targetOffset, targetCount, fromIndex) {
412         if (fromIndex >= sourceCount) {
413                 return (targetCount == 0 ? sourceCount : -1);
414         }
415         if (fromIndex < 0) {
416                 fromIndex = 0;
417         }
418         if (targetCount == 0) {
419                 return fromIndex;
420         }
421
422         var first  = target[targetOffset];
423         var i = sourceOffset + fromIndex;
424         var max = sourceOffset + (sourceCount - targetCount);
425
426         startSearchForFirstChar:
427         while (true) {
428                 /* Look for first character. */
429                 while (i <= max && source[i] != first) {
430                         i++;
431                 }
432                 if (i > max) {
433                         return -1;
434                 }
435
436                 /* Found first character, now look at the rest of v2 */
437                 var j = i + 1;
438                 var end = j + targetCount - 1;
439                 var k = targetOffset + 1;
440                 while (j < end) {
441                         if (source[j++] != target[k++]) {
442                                 i++;
443                                 /* Look for str's first char again. */
444                                 continue startSearchForFirstChar;
445                         }
446                 }
447                 return i - sourceOffset;        /* Found whole string. */
448         }
449 };
450
451 String.instantialize = function () {
452         if (arguments.length == 0) {
453                 return new String ();
454         } else if (arguments.length == 1) {
455                 var x = arguments[0];
456                 if (typeof x == "string" || x instanceof String) {
457                         return new String (x);
458                 } else if (x instanceof Array || x instanceof Int32Array) {
459                         if (x.length > 0 && typeof x[0] == "number") {
460                                 var arr = new Array (x.length);
461                                 for (var i = 0; i < x.length; i++) {
462                                         arr[i] = String.fromCharCode (x[i] & 0xff);
463                                 }
464                                 return Encoding.readUTF8 (arr.join (''));
465                         }
466                         return x.join ('');
467                 } else if (x.__CLASS_NAME__ == "StringBuffer" 
468                                 || x.__CLASS_NAME__ == "java.lang.StringBuffer") {
469                         var value = x.shareValue();
470                         var length = x.length ();
471                         var valueCopy = new Array (length);
472                         for (var i = 0; i < length; i++) {
473                                 valueCopy[i] = value[i];
474                         }
475                         return valueCopy.join ('')
476                         //return x.value.join ('');
477                 } else {
478                         return "" + x;
479                 }
480         } else if (arguments.length == 2) {
481                 var x = arguments[0];
482                 var hibyte=arguments[1];
483                 if (typeof hibyte == "string") {
484                         return String.instantialize(x,0,x.length, hibyte);
485                 } else {
486                         return String.instantialize(x,hibyte,0,x.length);
487                 }
488         } else if (arguments.length == 3) {
489                 var bytes = arguments[0];
490                 var offset = arguments[1];
491                 var length = arguments[2];
492                 if (arguments[2] instanceof Array) {
493                         bytes = arguments[2];
494                         offset = arguments[0];
495                         length = arguments[1];
496                 }
497                 var arr = new Array (length);
498                 if (offset < 0 || length + offset > bytes.length) {
499                         throw new IndexOutOfBoundsException ();
500                 }
501                 if (length > 0) {
502                         var isChar = (bytes[offset].length != null);
503                         if (isChar) {
504                                 for (var i = 0; i < length; i++) {
505                                         arr[i] = bytes[offset + i];
506                                 }
507                         } else {
508                                 for (var i = 0; i < length; i++) {
509                                         arr[i]=String.fromCharCode (bytes[offset+i]);
510                                 }
511                         }
512                 }
513                 return arr.join ('');
514         } else if (arguments.length == 4) {
515                 var bytes = arguments[0];
516                 var y = arguments[3];
517                 if (typeof y == "string" || y instanceof String) {
518                         var offset = arguments[1];
519                         var length = arguments[2];
520                         var arr = new Array (length);
521                         for (var i = 0; i < length; i++) {
522                                 arr[i] = bytes[offset + i];
523                                 if (typeof arr[i] == "number") {
524                                         arr[i] = String.fromCharCode (arr[i] & 0xff);
525                                 }
526                         }
527                         var cs = y.toLowerCase ();
528                         if (cs == "utf-8" || cs == "utf8") {
529                                 return Encoding.readUTF8 (arr.join (''));
530                         } else {
531                                 return arr.join ('');
532                         }
533                 } else {
534                         var count = arguments[3];
535                         var offset = arguments[2];
536                         var hibyte = arguments[1];
537                         var value = new Array (count);
538                         if (hibyte == 0) {
539                                 for (var i = count ; i-- > 0 ;) {
540                                         value[i] = String.fromCharCode (bytes[i + offset] & 0xff);
541                                 }
542                         } else {
543                                 hibyte <<= 8;
544                                 for (var i = count ; i-- > 0 ;) {
545                                         value[i] = String.fromCharCode (hibyte | (bytes[i + offset] & 0xff));
546                                 }
547                         }
548                         return value.join ('');
549                 }
550         } else {
551                 var s = "";
552                 for (var i = 0; i < arguments.length; i++) {
553                 s += arguments[i];
554                 }
555                 return s;
556         }
557 };
558
559 if (navigator.userAgent.toLowerCase ().indexOf ("chrome") != -1) { // Google Chrome's bug
560         String.prototype.toString = function () {
561                 return this;
562         };
563 }
564
565 } // end of String.prototype.$replace
566 });