mp3decoder passes the loop termination analysis.
[IRC.git] / Robust / src / ClassLibrary / SSJava / String.java
1 import Vector;
2
3 @LATTICE("V<C, V<O,V*")
4 @METHODDEFAULT("O<V,V<C,C<IN,C*,THISLOC=O,RETURNLOC=O")
5 public class String {
6
7   @LOC("V")
8   char value[];
9
10   @LOC("C")
11   int count;
12
13   @LOC("O")
14   int offset;
15
16   @LOC("V")
17   private int cachedHashcode;
18
19   private String() {
20   }
21
22   public String(char c) {
23     char[] str = new char[1];
24     str[0] = c;
25     String(str);
26   }
27
28   public String(char str[]) {
29     char charstr[] = new char[str.length];
30     for (int i = 0; i < str.length; i++)
31       charstr[i] = str[i];
32     this.value = charstr;
33     this.count = str.length;
34     this.offset = 0;
35   }
36
37   public String(byte str[]) {
38     char charstr[] = new char[str.length];
39     for (int i = 0; i < str.length; i++)
40       charstr[i] = (char) str[i];
41     this.value = charstr;
42     this.count = str.length;
43     this.offset = 0;
44   }
45
46   public String(byte str[], int offset, int length) {
47     if (length > (str.length - offset))
48       length = str.length - offset;
49     char charstr[] = new char[length];
50     for (int i = 0; i < length; i++)
51       charstr[i] = (char) str[i + offset];
52     this.value = charstr;
53     this.count = length;
54     this.offset = 0;
55   }
56
57   public String(byte str[], String encoding) {
58     int length = this.count;
59     if (length > (str.length))
60       length = str.length;
61     char charstr[] = new char[length];
62     for (int i = 0; i < length; i++)
63       charstr[i] = (char) str[i];
64     this.value = charstr;
65     this.count = length;
66     this.offset = 0;
67   }
68
69   public String(char str[], int offset, int length) {
70     if (length > (str.length - offset))
71       length = str.length - offset;
72     char charstr[] = new char[length];
73     for (int i = 0; i < length; i++)
74       charstr[i] = str[i + offset];
75     this.value = charstr;
76     this.count = length;
77     this.offset = 0;
78   }
79
80   public String(String str) {
81     this.value = str.value;
82     this.count = str.count;
83     this.offset = str.offset;
84   }
85
86   public String(StringBuffer strbuf) {
87     value = new char[strbuf.length()];
88     count = strbuf.length();
89     offset = 0;
90     for (int i = 0; i < count; i++)
91       value[i] = strbuf.value[i];
92   }
93
94   public boolean endsWith(String suffix) {
95     return regionMatches(count - suffix.count, suffix, 0, suffix.count);
96   }
97
98   public String substring(int beginIndex) {
99     return substring(beginIndex, this.count);
100   }
101
102   public String subString(int beginIndex, int endIndex) {
103     return substring(beginIndex, endIndex);
104   }
105
106   public String substring(int beginIndex, int endIndex) {
107     String str = new String();
108     if (beginIndex > this.count || endIndex > this.count || beginIndex > endIndex) {
109       // FIXME
110       System.printString("Index error: " + beginIndex + " " + endIndex + " " + count + "\n" + this);
111     }
112     str.value = this.value;
113     str.count = endIndex - beginIndex;
114     str.offset = this.offset + beginIndex;
115     return str;
116   }
117
118   public String subString(int beginIndex) {
119     return this.subString(beginIndex, this.count);
120   }
121
122   public int lastindexOf(int ch) {
123     return this.lastindexOf(ch, count - 1);
124   }
125
126   public int lastIndexOf(char ch) {
127     return this.lastindexOf((int) ch, count - 1);
128   }
129
130   public static String concat2(String s1, String s2) {
131     if (s1 == null)
132       return "null".concat(s2);
133     else
134       return s1.concat(s2);
135   }
136
137   public String concat(String str) {
138     String newstr = new String();
139     newstr.count = this.count + str.count;
140     char charstr[] = new char[newstr.count];
141     newstr.offset = 0;
142     for (int i = 0; i < count; i++) {
143       charstr[i] = value[i + offset];
144     }
145     for (int i = 0; i < str.count; i++) {
146       charstr[i + count] = str.value[i + str.offset];
147     }
148     newstr.value = charstr;
149     return newstr;
150   }
151
152   public int lastindexOf(int ch, int fromIndex) {
153     for (int i = fromIndex; i > 0; i--)
154       if (this.charAt(i) == ch)
155         return i;
156     return -1;
157   }
158
159   public String replace(char oldch, char newch) {
160     char[] buffer = new char[count];
161     for (int i = 0; i < count; i++) {
162       char x = charAt(i);
163       if (x == oldch)
164         x = newch;
165       buffer[i] = x;
166     }
167     return new String(buffer);
168   }
169
170   public String toUpperCase() {
171     char[] buffer = new char[count];
172     for (int i = 0; i < count; i++) {
173       char x = charAt(i);
174       if (x >= 'a' && x <= 'z') {
175         x = (char) ((x - 'a') + 'A');
176       }
177       buffer[i] = x;
178     }
179     return new String(buffer);
180   }
181
182   public String toLowerCase() {
183     char[] buffer = new char[count];
184     for (int i = 0; i < count; i++) {
185       char x = charAt(i);
186       if (x >= 'A' && x <= 'Z') {
187         x = (char) ((x - 'A') + 'a');
188       }
189       buffer[i] = x;
190     }
191     return new String(buffer);
192   }
193
194   public int indexOf(int ch) {
195     return this.indexOf(ch, 0);
196   }
197
198   public int indexOf(int ch, int fromIndex) {
199     for (int i = fromIndex; i < count; i++)
200       if (this.charAt(i) == ch)
201         return i;
202     return -1;
203   }
204
205   public int indexOf(String str) {
206     return this.indexOf(str, 0);
207   }
208
209   public int indexOf(String str, int fromIndex) {
210     if (fromIndex < 0)
211       fromIndex = 0;
212     for (int i = fromIndex; i <= (count - str.count); i++)
213       if (regionMatches(i, str, 0, str.count))
214         return i;
215     return -1;
216   }
217
218   public int indexOfIgnoreCase(String str, int fromIndex) {
219     if (fromIndex < 0)
220       fromIndex = 0;
221   }
222
223   public int lastIndexOf(String str, int fromIndex) {
224     int k = count - str.count;
225     if (k > fromIndex)
226       k = fromIndex;
227     for (; k >= 0; k--) {
228       if (regionMatches(k, str, 0, str.count))
229         return k;
230     }
231     return -1;
232   }
233
234   public int lastIndexOf(String str) {
235     return lastIndexOf(str, count - str.count);
236   }
237
238   public boolean startsWith(String str) {
239     return regionMatches(0, str, 0, str.count);
240   }
241
242   public boolean startsWith(String str, int toffset) {
243     return regionMatches(toffset, str, 0, str.count);
244   }
245
246   public boolean regionMatches(int toffset, String other, int ooffset, int len) {
247     if (toffset < 0 || ooffset < 0 || (toffset + len) > count || (ooffset + len) > other.count)
248       return false;
249     for (int i = 0; i < len; i++)
250       if (other.value[i + other.offset + ooffset] != this.value[i + this.offset + toffset])
251         return false;
252     return true;
253   }
254
255   public char[] toCharArray() {
256     char str[] = new char[count];
257     for (int i = 0; i < count; i++)
258       str[i] = value[i + offset];
259     return str;
260   }
261
262   public byte[] getBytes() {
263     byte str[] = new byte[count];
264     for (int i = 0; i < count; i++)
265       str[i] = (byte) value[i + offset];
266     return str;
267   }
268
269   public void getChars(char dst[], int dstBegin) {
270     getChars(0, count, dst, dstBegin);
271   }
272
273   public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
274     if ((srcBegin < 0) || (srcEnd > count) || (srcBegin > srcEnd)) {
275       // FIXME
276       System.printString("Index error: " + srcBegin + " " + srcEnd + " " + count + "\n" + this);
277       System.exit(-1);
278     }
279     int len = srcEnd - srcBegin;
280     int j = dstBegin;
281     for (int i = srcBegin; i < srcEnd; i++)
282       dst[j++] = value[i + offset];
283     return;
284   }
285
286   public int length() {
287     return count;
288   }
289
290   public char charAt(int i) {
291     return value[i + offset];
292   }
293
294   public String toString() {
295     return this;
296   }
297
298   @LATTICE("OUT<THIS,THIS<IN,THISLOC=THIS,RETURNLOC=OUT")
299   public static String valueOf(@LOC("THIS") Object o) {
300     if (o == null)
301       return "null";
302     else
303       return o.toString();
304   }
305
306   public static String valueOf(boolean b) {
307     if (b)
308       return new String("true");
309     else
310       return new String("false");
311   }
312
313   public static String valueOf(@LOC("IN") char c) {
314     @LOC("C") char ar[] = new char[1];
315     ar[0] = c;
316     return new String(ar);
317   }
318
319   public static String valueOf(@LOC("C") int x) {
320     @LOC("C") int length = 0;
321     @LOC("C") int tmp;
322     if (x < 0)
323       tmp = -x;
324     else
325       tmp = x;
326     TERMINATE:
327     do {
328       tmp = tmp / 10;
329       length = length + 1;
330     } while (tmp != 0);
331
332     @LOC("C") char chararray[];
333     if (x < 0)
334       chararray = new char[length + 1];
335     else
336       chararray = new char[length];
337     @LOC("C") int voffset;
338     if (x < 0) {
339       chararray[0] = '-';
340       voffset = 1;
341       x = -x;
342     } else
343       voffset = 0;
344
345     TERMINATE:
346     do {
347       chararray[--length + voffset] = (char) (x % 10 + '0');
348       x = x / 10;
349     } while (length != 0);
350     return new String(chararray);
351   }
352
353   public static String valueOf(double val) {
354     char[] chararray = new char[20];
355     String s = new String();
356     s.offset = 0;
357     s.count = convertdoubletochar(val, chararray);
358     s.value = chararray;
359     return s;
360   }
361
362   public static native int convertdoubletochar(double val, char[] chararray);
363
364   public static String valueOf(@LOC("C") long x) {
365     @LOC("C") int length = 0;
366     @LOC("C") long tmp;
367     if (x < 0)
368       tmp = -x;
369     else
370       tmp = x;
371     
372     TERMINATE:
373     do {
374       tmp = tmp / 10;
375       length = length + 1;
376     } while (tmp != 0);
377
378     @LOC("C") char chararray[];
379     if (x < 0)
380       chararray = new char[length + 1];
381     else
382       chararray = new char[length];
383     @LOC("C") int voffset;
384     if (x < 0) {
385       chararray[0] = '-';
386       voffset = 1;
387       x = -x;
388     } else
389       voffset = 0;
390
391     TERMINATE:
392     do {
393       chararray[--length + voffset] = (char) (x % 10 + '0');
394       x = x / 10;
395     } while (length != 0);
396     return new String(chararray);
397   }
398
399   public int compareTo(String s) {
400     int smallerlength = count < s.count ? count : s.count;
401
402     for (int i = 0; i < smallerlength; i++) {
403       int valDiff = this.charAt(i) - s.charAt(i);
404       if (valDiff != 0) {
405         return valDiff;
406       }
407     }
408     return count - s.count;
409   }
410
411   @LATTICE("OUT<THIS,THIS<C,C*,THISLOC=THIS")
412   @RETURNLOC("OUT")
413   public int hashCode() {
414     if (cachedHashcode != 0)
415       return cachedHashcode;
416     @LOC("THIS,String.V") int hashcode = 0;
417     for (@LOC("THIS,String.V") int i = 0; i < count; i++)
418       hashcode = hashcode * 31 + value[i + offset];
419     cachedHashcode = hashcode;
420     return hashcode;
421   }
422
423   public boolean equals(Object o) {
424     if (o.getType() != getType())
425       return false;
426     String s = (String) o;
427     if (s.count != count)
428       return false;
429     for (int i = 0; i < count; i++) {
430       if (s.value[i + s.offset] != value[i + offset])
431         return false;
432     }
433     return true;
434   }
435
436   public boolean equalsIgnoreCase(String s) {
437     if (s.count != count)
438       return false;
439     for (int i = 0; i < count; i++) {
440       char l = s.value[i + s.offset];
441       char r = value[i + offset];
442       if (l >= 'a' && l <= 'z')
443         l = (char) ((l - 'a') + 'A');
444       if (r >= 'a' && r <= 'z')
445         r = (char) ((r - 'a') + 'A');
446       if (l != r)
447         return false;
448     }
449     return true;
450   }
451
452   public Vector split() {
453     Vector splitted = new Vector();
454     int i;
455     int cnt = 0;
456
457     // skip first spaces
458     for (i = 0; i < count; i++) {
459       if (value[i + offset] != '\n' && value[i + offset] != '\t' && value[i + offset] != ' ')
460         break;
461     }
462
463     int oldi = i;
464
465     while (i < count) {
466       if (value[i + offset] == '\n' || value[i + offset] == '\t' || value[i + offset] == ' ') {
467         String t = new String();
468         t.value = value;
469         t.offset = oldi;
470         t.count = i - oldi;
471         splitted.addElement(t);
472
473         // skip extra spaces
474         while (i < count
475             && (value[i + offset] == '\n' || value[i + offset] == '\t' || value[i + offset] == ' ')) {
476           i++;
477         }
478         oldi = i;
479       } else {
480         i++;
481       }
482     }
483
484     if (i != oldi) {
485       String t = new String();
486       t.value = value;
487       t.offset = oldi;
488       t.count = i - oldi;
489       splitted.addElement(t);
490     }
491
492     return splitted;
493   }
494
495   public boolean contains(String str) {
496     int i, j;
497     char[] strChar = str.toCharArray();
498     int cnt;
499
500     for (i = 0; i < count; i++) {
501       if (value[i] == strChar[0]) {
502         cnt = 0;
503         for (j = 0; j < str.length() && i + j < count; j++) {
504           if (value[i + j] == strChar[j])
505             cnt++;
506         }
507         if (cnt == str.length())
508           return true;
509       }
510     }
511
512     return false;
513
514   }
515
516   public String trim() {
517     int len = count;
518     int st = 0;
519     int off = offset; /* avoid getfield opcode */
520     char[] val = value; /* avoid getfield opcode */
521
522     while ((st < len) && (val[off + st] <= ' ')) {
523       st++;
524     }
525     while ((st < len) && (val[off + len - 1] <= ' ')) {
526       len--;
527     }
528     return ((st > 0) || (len < count)) ? substring(st, len) : this;
529   }
530
531   public boolean matches(String regex) {
532     System.println("String.matches() is not fully supported");
533     return this.equals(regex);
534   }
535 }