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