KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > jrexx > set > CharSet


1 /*
2 * 01/07/2003 - 15:19:32
3 *
4 * CharSet.java -
5 * Copyright (C) 2003 Buero fuer Softwarearchitektur GbR
6 * ralf.meyer@karneim.com
7 * http://jrexx.sf.net
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program 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. See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */

23 package com.tc.jrexx.set;
24
25 import java.util.NoSuchElementException JavaDoc;
26
27 public class CharSet implements ISet_char {
28
29   interface IAbstract extends java.io.Serializable JavaDoc {
30     abstract int size();
31     abstract boolean isEmpty();
32     abstract void complement();
33     abstract boolean contains(char ch);
34     abstract boolean add(char ch);
35     abstract boolean remove(char ch);
36     abstract void addAll(IAbstract set);
37     abstract void removeAll(IAbstract set);
38     abstract void retainAll(IAbstract set);
39     abstract ISet_char.Iterator iterator();
40     abstract void addAll(String JavaDoc chars,int offset,int length);
41     abstract void addAll(char[] chars,int offset,int length);
42     abstract boolean equals(Object JavaDoc obj);
43   }
44
45 /*
46   final class Empty extends Abstract {
47     int size() {return 0;}
48     boolean isEmpty() {return true;}
49     void complement() {CharSet.this.set = new CharSet.Full();}
50     boolean contains(char ch) {return false;}
51     boolean add(char ch) {
52       CharSet.this.set = new CharSet.Char(ch);
53       CharSet.this.modifiedFlag = true;
54       return true;
55     }
56     int addAll(char[] chars,int offset,int length) {
57       CharSet.this.set = new CharSet.Char(chars[offset]);
58       CharSet.this.modifiedFlag = true;
59
60       return 1+CharSet.this.set.addAll(chars,++offset,--length);
61     }
62     int addAll(String chars,int offset,int length) {
63       CharSet.this.set = new CharSet.Char(chars.charAt(offset));
64       CharSet.this.modifiedFlag = true;
65
66       return 1+CharSet.this.set.addAll(chars,++offset,--length);
67     }
68
69     int addAll(Abstract set) {
70       if (set instanceof Char) CharSet.this.set = new Char( (Char)set );
71       else
72       if (set instanceof LongMap) CharSet.this.set = new LongMap( (LongMap)set );
73       else
74       if (set instanceof CharComplement) CharSet.this.set = new CharComplement( (CharComplement)set );
75       else
76       if (set instanceof LongMapComplement) CharSet.this.set = new LongMapComplement( (LongMapComplement)set );
77       else
78       if (set instanceof Full) CharSet.this.set = new Full();
79
80       return set.size();
81     }
82
83     boolean remove(char ch) {return false;}
84     int removeAll(Abstract set) {return 0;}
85
86     boolean retain(char ch) {return false;}
87     int retainAll(Abstract set) {return 0;}
88
89     ISet_char.Iterator iterator() {
90       return new ISet_char.Iterator() {
91         public boolean hasNext() {
92           if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
93           return false;
94         }
95         public char next() {
96           throw new NoSuchElementException();
97         }
98       };
99     }
100   }
101
102   final class Full extends Abstract {
103     int size() {return 65535;}
104     boolean isEmpty() {return false;}
105     void complement() {CharSet.this.set = new CharSet.Empty();}
106     boolean contains(char ch) {return true;}
107     boolean add(char ch) {return false;}
108     int addAll(String chars,int offset,int length) {return 0;}
109     int addAll(char[] chars,int offset,int length) {return 0;}
110     int addAll(Abstract set) {return 0;}
111     boolean remove(char ch) {
112       CharSet.this.set = new CharSet.CharComplement(ch);
113       CharSet.this.modifiedFlag = true;
114       return true;
115     }
116     int removeAll(Abstract set) {
117       if (set instanceof Char) CharSet.this.set = new CharComplement( (Char)set );
118       else
119       if (set instanceof LongMap) CharSet.this.set = new LongMapComplement( (LongMap)set );
120       else
121       if (set instanceof CharComplement) CharSet.this.set = new Char( (CharComplement)set );
122       else
123       if (set instanceof LongMapComplement) CharSet.this.set = new LongMap( (LongMapComplement)set );
124       else
125       if (set instanceof Full) CharSet.this.set = new Empty();
126
127       return set.size();
128     }
129     boolean retain(char ch) {
130       CharSet.this.set = new CharSet.Char(ch);
131       return true;
132     }
133     int retainAll(Abstract set) {
134       if (set instanceof Char) CharSet.this.set = new Char( (Char)set );
135       else
136       if (set instanceof LongMap) CharSet.this.set = new LongMap( (LongMap)set );
137       else
138       if (set instanceof CharComplement) CharSet.this.set = new CharComplement( (CharComplement)set );
139       else
140       if (set instanceof LongMapComplement) CharSet.this.set = new LongMapComplement( (LongMapComplement)set );
141       else
142       if (set instanceof Empty) CharSet.this.set = new Empty();
143
144       return set.size();
145     }
146     ISet_char.Iterator iterator() {
147       return new ISet_char.Iterator() {
148         int index = 0;
149         public boolean hasNext() {
150           if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
151           return this.index!=65536;
152         }
153         public char next() {
154           if (this.index==65536) throw new NoSuchElementException();
155           if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
156           final char result = (char)this.index;
157           ++this.index;
158           return result;
159         }
160       };
161     }
162   };
163
164   final class Char extends Abstract {
165     final char ch;
166     Char(char ch) {this.ch = ch;}
167     int size() {return 1;}
168     boolean isEmpty() {return false;}
169     boolean contains(char ch) {return this.ch==ch;}
170     void complement() {
171       CharSet.this.set = new CharSet.CharComplement(this.ch);
172     }
173     boolean add(char ch) {
174       if (ch==this.ch) return false;
175       CharSet.this.set = new CharSet.LongMap(this.ch,ch);
176       return true;
177     }
178     int addAll(String chars,int offset,int length) {
179       loop: {
180         for (; length>0; ++offset,--length)
181           if (chars.charAt(offset)!=this.ch) break loop;
182         return 0;
183       }
184
185       CharSet.this.set = new CharSet.LongMap(this.ch,chars.charAt(offset));
186       return 1+CharSet.this.set.addAll(chars,++offset,--length);
187     }
188
189     int addAll(char[] chars,int offset,int length) {
190       loop: {
191         for (; length>0; ++offset,--length)
192           if (chars[offset]!=this.ch) break loop;
193         return 0;
194       }
195
196       CharSet.this.set = new CharSet.LongMap(this.ch,chars[offset]);
197       return 1+CharSet.this.set.addAll(chars,++offset,--length);
198     }
199
200     int addAll(Abstract set) {
201       if (set instanceof Char) {
202         if (this.ch!=((Char)set).ch) CharSet.this.set = new LongMap( this,(Char)set );
203         else {
204           return 0;
205         }
206       } else
207       if (set instanceof LongMap) {
208         if (set.contains(this.ch)==false) CharSet.this.set = new LongMap( this,(LongMap)set );
209         else {
210           CharSet.this.set = new LongMap( (LongMap)set );
211           return set.size()-1;
212         }
213       } else
214       if (set instanceof CharComplement) {
215         if ( ((CharComplement)set).ch==this.ch ) CharSet.this.set = new Full();
216         else {
217           CharSet.this.set = new LongMapComplement( (CharComplement)set );
218           return 65534;
219         }
220       } else
221       if (set instanceof LongMapComplement) {
222         if (set.contains(this.ch)==false) CharSet.this.set = new LongMapComplement( this,(LongMapComplement)set );
223         else {
224           CharSet.this.set = new LongMapComplement( (LongMapComplement)set );
225           return set.size()-1;
226         }
227       }
228
229       return set.size();
230     }
231
232     boolean remove(char ch) {
233       if (this.ch==ch) return false;
234       CharSet.this.set = new CharSet.Empty();
235       CharSet.this.modifiedFlag = true;
236       return true;
237     }
238
239     int removeAll(Abstract set) {
240       if (set.contains(this.ch)==false) return 0;
241       CharSet.this.set = new Empty();
242       return 1;
243     }
244
245     boolean retain(char ch) {
246       if (this.ch==ch) return true;
247       CharSet.this.set = new Empty();
248       return false;
249     }
250
251     int retainAll(Abstract set) {
252       if (set.contains(this.ch)) return 1;
253       CharSet.this.set = new Empty();
254       return false;
255     }
256
257
258     ISet_char.Iterator iterator() {
259       return new ISet_char.Iterator() {
260         boolean hasNext = true;
261         public boolean hasNext() {
262           if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
263           return this.hasNext;
264         }
265         public char next() {
266           if (this.hasNext==false) throw new NoSuchElementException();
267           if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
268           this.hasNext = false;
269           return CharSet.Char.this.ch;
270         }
271       };
272     }
273   }
274
275   final class CharComplement extends Abstract {
276     final char ch;
277     CharComplement(char ch) {this.ch = ch;}
278     int size() {return 65534;}
279     boolean isEmpty() {return false;}
280     void complement() {CharSet.this.set = new CharSet.Char(this.ch);}
281     boolean contains(char ch) {return this.ch!=ch;}
282     boolean add(char ch) {
283       if (ch!=this.ch) return false;
284       CharSet.this.set = new CharSet.Full();
285       return true;
286     }
287     int addAll(String chars,int offset,int length) {
288       for (; length>0; ++offset,--length) {
289         if (chars.charAt(offset)==this.ch) {
290           CharSet.this.set = new CharSet.Full();
291           return 1;
292         }
293       }
294       return 0;
295     }
296     int addAll(char[] chars,int offset,int length) {
297       for (; length>0; ++offset,--length) {
298         if (chars[offset]==this.ch) {
299           CharSet.this.set = new CharSet.Full();
300           return 1;
301         }
302       }
303       return 0;
304     }
305     int addAll(Abstract set) {
306       if (set.contains(this.ch)==false) return 0;
307       else {
308         CharSet.this.set = new Full();
309         return 1;
310       }
311     }
312
313     boolean remove(char ch) {
314       if (ch==this.ch) return false;
315       CharSet.this.set = new LongMapComplement(this.ch,ch);
316       CharSet.this.modifiedFlag = true;
317       return true;
318     }
319
320     int removeAll(Abstract set) {
321       if (set instanceof Char) {
322         if ( set.contains(this.ch) ) return 0;
323         else {
324           CharSet.this.set = new LongMapComplement(this.ch,((Char)set).ch);
325           return 1; // set.size();
326         }
327       } else
328       if (set instanceof LongMap) {
329         if ( set.contains(this.ch) ) {
330           CharSet.this.set = new LongMapComplement((LongMap)map);
331           return set.size()-1;
332         } else {
333           LongMap tmp = new LongMapComplement(this.ch,(LongMap)map);
334           return set.size();
335         }
336       } else
337       if (set instanceof CharComplement) {
338         if ( set.contains(this.ch) ) {
339           CharSet.this.set = new Char(this.ch);
340           return 65534; // set.size()-1
341         } else {
342           CharSet.this.set = new Empty();
343           return 65535;
344         }
345       } else
346       if (set instanceof LongMapComplement) {
347         if (set.contains(this.ch)) {
348           CharSet.this.set = new LongMap(((LongMapComplement)set).);
349           return set.size()-1;
350         }
351       }
352
353     }
354
355     boolean retain(char ch) {
356       if (this.ch==ch) {
357         CharSet.this.set = new Empty();
358         return false;
359       } else {
360         CharSet.this.set = new Char(ch);
361         return true;
362       }
363     }
364
365     int retain(Abstract set) {
366       if (set.contains(this.ch)) {
367         CharSet.this.set = new Empty();
368         return 0;
369       } else {
370         CharSet.this.set = Char((Char)set);
371       }
372
373       return set.size();
374     }
375
376     ISet_char.Iterator iterator() {
377       return new ISet_char.Iterator() {
378         int index = 0;
379         public boolean hasNext() {
380           if (this.index==(int)CharSet.CharComplement.this.ch) ++this.index;
381           return this.index!=65536;
382         }
383         public char next() {
384           if (this.index==(int)CharSet.CharComplement.this.ch) ++this.index;
385           if (this.index==65536) throw new NoSuchElementException();
386           if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
387           final char result = (char)this.index;
388           ++this.index;
389           return result;
390         }
391       };
392     }
393   }
394 */

395
396 // static int wrapperCount = 0;
397

398   static final class Wrapper implements java.io.Serializable JavaDoc {
399     final int offset;
400     long value;
401
402     Wrapper(int offset,long value) {
403       this.offset = offset;
404       this.value = value;
405
406 // ++wrapperCount;
407
// if (wrapperCount>1060000) System.out.println("+"+wrapperCount);
408
}
409
410 // protected void finalize() throws Throwable {
411
// --wrapperCount;
412
// if (wrapperCount>99900 && wrapperCount<100000) System.out.println("-"+wrapperCount);
413
// }
414

415     int size() {
416       int answer = 0;
417       for (long tmp=this.value; tmp!=0; tmp>>>=4) {
418         switch((int)(tmp & 15L)) {
419           case 0 : answer+= 0; break;
420           case 1 : answer+= 1; break;
421           case 2 : answer+= 1; break;
422           case 3 : answer+= 2; break;
423           case 4 : answer+= 1; break;
424           case 5 : answer+= 2; break;
425           case 6 : answer+= 2; break;
426           case 7 : answer+= 3; break;
427           case 8 : answer+= 1; break;
428           case 9 : answer+= 2; break;
429           case 10 : answer+= 2; break;
430           case 11 : answer+= 3; break;
431           case 12 : answer+= 2; break;
432           case 13 : answer+= 3; break;
433           case 14 : answer+= 3; break;
434           case 15 : answer+= 4; break;
435           default : throw new RuntimeException JavaDoc("error: should never happen");
436         }
437       }
438       return answer;
439     }
440   }
441
442   final static int[] PRIMENUMBERS = new int[]{
443     3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
444     101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,
445     193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,
446     293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,
447     409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,
448     521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,
449     641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,
450     757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,
451     881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,
452     1013,1019,1021,1024
453   };
454
455   final static long[] VALUES = new long[64];
456   static{
457     VALUES[0] = 1L;
458     for (int t=0,i=1; i<VALUES.length; ++i,++t) VALUES[i] = VALUES[t]<<1;
459   }
460
461   final class LongMap implements IAbstract {
462
463     Wrapper[] sets = null;
464     int size = 0;
465
466     protected LongMap(LongMap set) {
467       this.sets = new Wrapper[set.sets.length];
468       for (int i=0; i<set.sets.length; ++i)
469         if (set.sets[i]!=null)
470           this.sets[i] = new Wrapper(set.sets[i].offset,set.sets[i].value);
471
472       this.size = set.size;
473     }
474
475     LongMap() {
476       this.sets = new Wrapper[CharSet.PRIMENUMBERS[0]];
477     }
478
479     LongMap(char ch1,char ch2) {
480       this.sets = new Wrapper[CharSet.PRIMENUMBERS[0]];
481       this.add(ch1);
482       this.add(ch2);
483     }
484
485     public boolean isEmpty() {return this.size()==0;}
486     public int size() {
487       if (this.size>=0) return this.size;
488       int answer = 0;
489       for (int i=0; i<this.sets.length; ++i) {
490         if (this.sets[i]!=null) answer+= this.sets[i].size();
491       }
492       this.size = answer;
493       return answer;
494     }
495
496     public boolean contains(char ch) {
497       final int offset = ch/64;
498       final int index = offset % this.sets.length;
499       if (this.sets[index]==null || this.sets[index].offset != offset) return false;
500       return (this.sets[index].value & (VALUES[ch%64]))!=0;
501     }
502
503     public void complement() {
504       this.size = -1;
505       final Wrapper[] tmp = this.sets;
506       this.sets = new Wrapper[CharSet.PRIMENUMBERS[0]];
507       for (int offset=0; offset<CharSet.this.max; ++offset) {
508         int index = offset % tmp.length;
509         long value = -1L;
510         if (tmp[index]!=null && tmp[index].offset==offset) value^= tmp[index].value;
511         if (value!=0) this.addAll(offset,value);
512       }
513     }
514
515     public boolean add(char ch) {
516       if (ch>CharSet.this.maxChar)
517         throw new IllegalArgumentException JavaDoc(
518           "ch > maxChar = "
519           +CharSet.this.maxChar
520           +"("+(int)CharSet.this.maxChar+")"
521         );
522
523       final int offset = ch/64;
524       loop: do {
525         int index = offset % this.sets.length;
526         if (this.sets[index]==null) {
527           this.sets[index] = new Wrapper(offset,1L<<(ch%64));
528           if (this.size>=0) ++this.size;
529           return true;
530         }
531         if (this.sets[index].offset==offset) {
532           long oldValue = this.sets[index].value;
533           this.sets[index].value|= VALUES[ch%64];
534           long newValue = this.sets[index].value;
535
536           if (oldValue==newValue) return false;
537
538           if (this.size>=0) ++this.size;
539           return true;
540         }
541
542         this.expand();
543       } while(true);
544     }
545
546     public void addAll(char[] chars,int offset,int length) {
547       for (; length>0; ++offset,--length) this.add(chars[offset]);
548     }
549
550     public void addAll(String JavaDoc chars,int offset,int length) {
551       for (; length>0; ++offset,--length) this.add(chars.charAt(offset));
552     }
553
554
555     public void addAll(IAbstract set) {
556       this.addAll((LongMap)set);
557     }
558
559     void addAll(LongMap set) {
560       if (this.sets.length>=set.sets.length) {
561         for (int i=0; i<set.sets.length; ++i) {
562           if (set.sets[i]!=null)
563             this.addAll(set.sets[i].offset,set.sets[i].value);
564         }
565       } else {
566         final Wrapper[] tmp = this.sets;
567         this.sets = new Wrapper[set.sets.length];
568         for (int i=0; i<set.sets.length; ++i)
569           this.sets[i] = (set.sets[i]==null) ? null : new Wrapper(set.sets[i].offset,set.sets[i].value);
570         this.size = set.size;
571
572         for (int i=0; i<tmp.length; ++i) {
573           if (tmp[i]!=null) this.addAll(tmp[i]);
574         }
575       }
576     }
577
578     private void addAll(int offset,long value) {
579       this.size = -1;
580       loop: do {
581         int index = offset % this.sets.length;
582         if (this.sets[index]==null) {
583           this.sets[index] = new Wrapper(offset,value);
584           return;
585         }
586         if (this.sets[index].offset==offset) {
587           this.sets[index].value|= value;
588           return;
589         }
590
591         this.expand();
592       } while(true);
593     }
594
595     private void addAll(Wrapper w) {
596       this.size = -1;
597       loop: do {
598         int index = w.offset % this.sets.length;
599         if (this.sets[index]==null) {
600           this.sets[index] = w;
601           return;
602         }
603         if (this.sets[index].offset==w.offset) {
604           this.sets[index].value|= w.value;
605           return;
606         }
607
608         this.expand();
609       } while(true);
610     }
611
612
613     public boolean remove(char ch) {
614       final int offset = ch/64;
615       final int index = offset % this.sets.length;
616       if (this.sets[index]==null) return false;
617       if (this.sets[index].offset!=offset) return false;
618
619       long oldValue = this.sets[index].value;
620       this.sets[index].value&= (-1L)^(VALUES[ch%64]);
621       long newValue = this.sets[index].value;
622
623       if (oldValue==newValue) return false;
624
625       if (this.size>0) --this.size;
626       if (newValue==0) this.sets[index] = null;
627       return true;
628     }
629
630     public void removeAll(IAbstract set) {
631       this.removeAll((LongMap)set);
632     }
633
634     void removeAll(LongMap set) {
635       for (int i=0; i<set.sets.length; ++i) {
636         if (set.sets[i]!=null)
637           this.removeAll(set.sets[i].offset,set.sets[i].value);
638       }
639     }
640
641     private void removeAll(int offset,long value) {
642       final int index = offset % this.sets.length;
643       if (this.sets[index]==null) return;
644       if (this.sets[index].offset!=offset) return;
645
646       this.size = -1;
647       this.sets[index].value&= (-1L)^value;
648       if (this.sets[index].value==0) this.sets[index] = null;
649     }
650
651     public void retainAll(IAbstract set) {
652       this.retainAll((LongMap)set);
653     }
654
655     void retainAll(LongMap set) {
656       this.size = -1;
657       for (int i=0; i<this.sets.length; ++i) {
658         if (this.sets[i]!=null) {
659           Wrapper w1 = this.sets[i];
660           Wrapper w2 = set.sets[w1.offset % set.sets.length];
661           if (w2==null) this.sets[i] = null;
662           else {
663             if (w1.offset!=w2.offset) this.sets[i] = null;
664             else {
665               w1.value&= w2.value;
666               if (this.sets[i].value==0) this.sets[i] = null;
667             }
668           }
669         }
670       }
671     }
672
673     private void expand() {
674       final Wrapper[] values = this.sets;
675       reInit: do {
676         this.sets = new Wrapper[this.nextPrimeNumber()];
677         for (int i=0; i<values.length; ++i) {
678           if (values[i]!=null) {
679             int index = values[i].offset % this.sets.length;
680             if (this.sets[index]!=null) continue reInit;
681             this.sets[index] = values[i];
682           }
683         }
684         return;
685       } while(true);
686     }
687
688     private int nextPrimeNumber() {
689       final int currentPrimeNumber = this.sets.length;
690       int i = 0;
691       while (CharSet.PRIMENUMBERS[i]!=currentPrimeNumber) ++i;
692       return CharSet.PRIMENUMBERS[++i];
693     }
694
695     public ISet_char.Iterator iterator() {
696       return new LongMapIterator(CharSet.this, this);
697     }
698
699     public boolean equals(Object JavaDoc obj) {
700       if (this==obj) return true;
701       if (obj==null) return false;
702       if (this.getClass()!=obj.getClass()) return false;
703
704       LongMap set = (LongMap)obj;
705       if (this.size!=set.size) return false;
706
707       for (int i=0; i<this.sets.length; ++i) {
708         if (this.sets[i]!=null) {
709 if (this.sets[i].value==0) throw new Error JavaDoc("this.sets[i].value==0");
710           Wrapper w1 = this.sets[i];
711           Wrapper w2 = set.sets[w1.offset % set.sets.length];
712           if (w2==null) return false;
713           else {
714             if (w1.offset!=w2.offset) return false;
715             else {
716               if (w1.value!=w2.value) return false;
717             }
718           }
719         }
720       }
721
722       return true;
723     }
724   }
725
726
727   private static final class LongMapIterator implements ISet_char.Iterator {
728     int currentOffset = 0;
729
730     long currentValue = 1L;
731
732     char currentChar = '\u0000';
733
734     final int setsLength; // = CharSet.LongMap.this.sets.length;
735

736     private final LongMap longMap;
737
738     private final CharSet charSet;
739
740     public LongMapIterator(CharSet charSet, LongMap longMap) {
741       this.charSet = charSet;
742       this.longMap = longMap;
743       this.setsLength = longMap.sets.length;
744     }
745
746     public boolean hasNext() {
747     
748               do {
749                 if (longMap.contains(this.currentChar)) return true;
750               } while(++this.currentChar!='\u0000');
751               return false;
752     
753     /*
754     // if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
755     
756               for (; this.currentOffset<=1024; ++this.currentOffset) {
757                 Wrapper w = CharSet.LongMap.this.sets[this.currentOffset%setsLength];
758                 if (w==null) this.currentChar+= 64;
759                 else {
760                   if (w.offset==this.currentOffset) {
761                     for (; this.currentValue!=0; this.currentValue<<=1, ++this.currentChar) {
762                       if ((w.value & this.currentValue)!=0) {
763                         return true;
764                       }
765                     }
766                     this.currentValue = 1L;
767                   }
768                 }
769               }
770               return false;
771     */

772             }
773
774     public char next() {
775               do {
776                 if (longMap.contains(this.currentChar)) return this.currentChar++;
777               } while(++this.currentChar!='\u0000');
778     
779               throw new NoSuchElementException JavaDoc(charSet.toString());
780     
781     /*
782     // if (CharSet.this.modifiedFlag) throw new ConcurrentModificationException();
783     
784               for (; this.currentOffset<=1024; ++this.currentOffset) {
785                 Wrapper w = CharSet.LongMap.this.sets[this.currentOffset%setsLength];
786                 if (w==null) this.currentChar+= 64;
787                 else {
788                   if (w.offset==this.currentOffset) {
789                     for (; this.currentValue!=0; this.currentValue<<=1, ++this.currentChar) {
790                       if ((w.value & this.currentValue)!=0) {
791                         final char result = this.currentChar;
792                         this.currentValue<<=1;
793                         if (this.currentValue!=0) ++this.currentChar;
794                         return result;
795                       }
796                     }
797                     this.currentValue = 1L;
798                   }
799                 }
800               }
801               throw new NoSuchElementException(this.currentChar+" \""+CharSet.this.toString()+"\" "+CharSet.this.size());
802     */

803             }
804   }
805   
806
807 // CharSet.Abstract set = new Empty();
808
// transient boolean modifiedFlag = false;
809

810   static final int max = 4;
811   static final char maxChar = (char)(64*max-1);
812
813   protected CharSet.IAbstract set;
814
815   protected CharSet(IAbstract set) {
816     this.set = set;
817   }
818
819   public CharSet() {
820     this.set = new LongMap();
821   }
822
823   public CharSet(char ch) {
824     this();
825     this.set.add(ch);
826   }
827
828   public CharSet(String JavaDoc s) {
829     this();
830     this.set.addAll(s,0,s.length());
831   }
832
833   public void complement() {
834     this.set.complement();
835   }
836
837   public boolean contains(char ch) {
838     return this.set.contains(ch);
839   }
840
841   public boolean isEmpty() {
842     return this.set.isEmpty();
843   }
844
845   public int size() {
846     return this.set.size();
847   }
848
849   public ISet_char.Iterator iterator() {
850     return this.set.iterator();
851   }
852
853   public void clear() {
854 // this.set = new CharSet.Empty();
855
this.set = new LongMap();
856   }
857
858   public boolean add(char ch) {
859
860     return this.set.add(ch);
861   }
862
863   public boolean remove(char ch) {
864     return this.set.remove(ch);
865   }
866
867   public void addAll(String JavaDoc chars) {
868     this.addAll(chars,0,chars.length());
869   }
870   public void addAll(String JavaDoc chars,int offset) {
871     this.addAll(chars,offset,chars.length()-offset);
872   }
873
874   public void addAll(String JavaDoc chars,int offset,int length) {
875     if (length==0) return;
876     this.set.addAll(chars,offset,length);
877   }
878
879   public void addAll(char[] chars) {
880     this.addAll(chars,0,chars.length);
881   }
882   public void addAll(char[] chars,int offset) {
883     this.addAll(chars,offset,chars.length-offset);
884   }
885
886   public void addAll(char[] chars,int offset,int length) {
887     if (length==0) return;
888     this.set.addAll(chars,offset,length);
889   }
890
891   /**
892    * adds all chars from set to this ISet_char without adding doublicates.
893    * returns the number of chars added to this ISet_char.
894    */

895   public void addAll(ISet_char set) {
896     if (set instanceof CharSet) this.set.addAll(((CharSet)set).set);
897     else {
898       final ISet_char.Iterator it = set.iterator();
899       for (int i=set.size(); i>0; --i) this.set.add(it.next());
900     }
901   }
902
903   /**
904    * Removes from this set all of its elements that are contained in the specified set (optional operation).
905    * returns the number of chars that were removed.
906    */

907   public void removeAll(ISet_char set) {
908     if (set instanceof CharSet) this.set.removeAll(((CharSet)set).set);
909     else {
910       final ISet_char.Iterator it = set.iterator();
911       for (int i=set.size(); i>0; --i) this.set.remove(it.next());
912     }
913   }
914
915   public void retainAll(ISet_char set) {
916     if (set instanceof CharSet) this.set.retainAll(((CharSet)set).set);
917     else {
918       final CharSet charSet = new CharSet();
919       final ISet_char.Iterator it = set.iterator();
920       for (int i=set.size(); i>0; --i) charSet.add(it.next());
921       this.set.retainAll(charSet.set);
922     }
923   }
924
925   public boolean equals(Object JavaDoc obj) {
926     if (this==obj) return true;
927     if (obj==null) return false;
928     if (this.getClass()!=obj.getClass()) return false;
929     return this.set.equals(((CharSet)obj).set);
930   }
931
932   public int hashCode() {
933     return this.set.size();
934   }
935
936   protected IAbstract cloneAbstract(IAbstract set) {
937     if (set instanceof LongMap) return new LongMap((LongMap)set);
938     throw new Error JavaDoc("");
939   }
940
941   public Object JavaDoc clone() {
942     try {
943       CharSet clone = (CharSet)super.clone();
944       clone.set = clone.cloneAbstract(set);
945       return clone;
946     } catch(CloneNotSupportedException JavaDoc e) {
947       throw new Error JavaDoc("CloneNotSupportedException:\n"+e);
948     }
949   }
950
951   public String JavaDoc toString() {
952     StringBuffer JavaDoc answer = new StringBuffer JavaDoc();
953
954     int from = -1;
955     char ch = '\u0000';
956     do {
957       if (this.contains(ch)) {
958         if (from==-1) from = ch;
959       } else {
960         if (from!=-1) {
961           char to = ch; --to;
962           if (from==to) {
963             if (to=='[' || to==']' || to=='\\' || to=='-') answer.append('\\');
964             answer.append(to);
965           } else {
966             char char_from = (char)from;
967             if (char_from=='[' || char_from==']' || char_from=='\\' || char_from=='-') answer.append('\\');
968             answer.append((char)from);
969             if (to!=++from) answer.append("-");
970             if (to=='[' || to==']' || to=='\\' || to=='-') answer.append('\\');
971             answer.append(to);
972           }
973
974           from = -1;
975         }
976       }
977     } while (++ch!='\u0000');
978
979     if (from!=-1) {
980       char char_from = (char)from;
981       if (char_from=='[' || char_from==']' || char_from=='\\' || char_from=='-') answer.append('\\');
982       answer.append((char)from);
983       if (from!='\ufffe') answer.append('-');
984       answer.append('\uffff');
985     }
986
987     for (int i=answer.length()-1; i>=0; --i) {
988       if (answer.charAt(i)>'\u00ff') answer.setCharAt(i,'.');
989     }
990
991     return answer.toString();
992   }
993
994 }
Popular Tags