Re: [Ikvm-developers] (no subject)
Brought to you by:
jfrijters
|
From: Jonathan P. <jp...@ny...> - 2003-07-23 15:39:14
|
Jeroen, >In IKVM java.lang.String == System.String. Obviously, System.String >doesn't implement CharSequence, so I'm going to have to fake it. I think >I've got pretty much figured out how to do it, but I haven't gotten >around to implement it. This is mostly due to the fact that I've never >encountered code that actually used CharSequence. Can't you just use your StringHelper class to implement it by returning another System.String object, one that has a view of a portion of the original character array. I attached a techtip from Sun that discusses the CharSequence interface and might be helpful to you if you haven't already seen it. The second example shows a CharArrayWrapper class that implements the SubSequence interface. You should be able to do the same thing with your StringHelper class and your map.xml. > http://www.junglecreatures.com/jungle/ClassVersionBug.zip >>This turns out to be caused by one unimplemented feature and one bug in >>my reflection code. I'm glad you were able to identify and fix the problems so quickly. IKVM is working really well for me, even for large converted jars. I'll continue to look for any additional bugs, but it looks like you are very close to a complete bug-free implementation. The tool seems extremely useful and I would expect these bugs to surface much faster once more developers become aware of how useful the technology is and begin testing it. Thanks for doing such a great job in responding so quickly in identifying and fixing bugs that I have been reporting. Approximately how many developers do you currently have on your mailing list? >I'll make a new snapshot tomorrow. BTW, I've not yet checked in the code. Great, Have you considered automating the snapshots from cvs with daily builds like Apache does? It may not be necessary with so few cvs committers. Regards, Jonathan USING THE CHARSEQUENCE INTERFACE Suppose that you're writing a method in the Java programming language. Suppose too that you want to specify one of the method parameters such that a user of the method can pass a string or sequence of characters to the method. An obvious way to do this is to use a String parameter. But what happens if the method caller has a StringBuffer or CharBuffer object instead of a String? Or what happens if the caller wants to pass a character array to your method? In those cases, using a String parameter will not work. Instead, you can use the java.lang.CharSequence interface. This is an interface that supports generalization of character sequences. A class that implements the CharSequence interface must define the following methods: length - returns the number of characters in the sequence charAt - returns a character at a given position subSequence - returns a subsequence of a sequence toString - returns a String containing the sequence characters The String, StringBuffer, and CharBuffer classes implement the CharSequence interface, so passing an object of one of these classes to a method with a CharSequence parameter will work. Let's look at an example: import java.nio.*; public class CSDemo1 { // dump out information about a CharSequence public static void dumpSeq(CharSequence cs) { System.out.println( "length = " + cs.length()); System.out.println( "first char = " + cs.charAt(0)); System.out.println("string = " + cs); System.out.println(); } public static void main(String args[]) { // String String s = "test"; dumpSeq(s); // StringBuffer StringBuffer sb = new StringBuffer("ing"); dumpSeq(sb); // CharBuffer CharBuffer cb = CharBuffer.allocate(3); cb.put("123"); cb.rewind(); dumpSeq(cb); } } In the CSDemo1 program, dumpSeq is a method with a CharSequence parameter. The parameter is passed instances of String, StringBuffer, and CharBuffer. When you run the program, the output is: length = 4 first char = t string = test length = 3 first char = i string = ing length = 3 first char = 1 string = 123 This example makes clear that you can use CharSequence as a generalization of character sequences. It shows that you can write methods that accept objects of any class type that implements the CharSequence interface. Let's look at another example, one that defines a CharArrayWrapper class that implements the CharSequence interface. The class is used to wrap a character array such that the wrapper object can be passed as an argument to a method expecting a CharSequence. Here's what the code looks like: class CharArrayWrapper implements CharSequence { private char vec[]; private int off; private int len; // length of sequence public int length() { return len; } // character at a given index public char charAt(int index) { if (index < 0 || index >= len) { throw new IndexOutOfBoundsException( "invalid index"); } return vec[index + off] ; } // subsequence from start (inclusive) // to end (exclusive) public CharSequence subSequence( int start, int end) { if (start < 0 || end < 0 || end > len || start > end) { throw new IndexOutOfBoundsException( "invalid start/end"); } return new CharArrayWrapper( vec, start + off, end - start); } // convert to string public String toString() { return new String(vec, off, len); } // construct an CharArrayWrapper // from a portion of a char array public CharArrayWrapper( char vec[], int off, int len) { if (vec == null) { throw new NullPointerException( "null vec"); } if (off < 0 || len < 0 || off > vec.length - len) { throw new IllegalArgumentException( "bad off/len"); } this.vec = vec; this.off = off; this.len = len; } // construct a CharArrayWrapper // from a char array public CharArrayWrapper(char vec[]) { this(vec, 0, vec.length); } } public class CSDemo2 { public static void main(String args[]) { // create array and wrap it char vec[] = {'a', 'b', 'c', 'd', 'e'}; CharSequence cs = new CharArrayWrapper(vec); // test the CharArrayWrapper // interface implementation System.out.println("string = " + cs); System.out.println( "length = " + cs.length()); System.out.println("subSequence(2,4) = " + cs.subSequence(2, 4)); System.out.println( "charAt(0) = " + cs.charAt(0)); if (cs.charAt(0) != 'a') System.out.println("*** error ***"); if (cs.subSequence(2, 4).charAt(0) != 'c') System.out.println("*** error ***"); if (cs.subSequence(2, 4).subSequence(0, 1).charAt(0) != 'c') System.out.println("*** error ***"); } } In the CSDemo2 program, the subSequence method is implemented by creating another CharArrayWrapper object, one that has a view of a portion of the original character array. The toString method is implemented by calling a String constructor with the array as its argument. Note that creating a string in this way is fairly expensive, because the array is copied. If instead, you simply provide a CharArrayWrapper for an array, it involves no copying. The CharArrayWrapper class and CharSequence provide a read-only interface. There's no way to modify the character sequence using this interface. If you're familiar with the java.nio.CharBuffer class, you'll notice that using that class to wrap a character array achieves a similar effect to CharArrayWrapper. That's because CharBuffer implements the CharSequence interface. If you run the CSDemo2 program, the results look like this: string = abcde length = 5 subSequence(2,4) = cd charAt(0) = a The CharSequence interface is used in the regular expression package (java.util.regex). You can see an example of its use by examining the BufferDemo7 program in the Programming With Buffers tip that follows this tip. |