matthiasblaesing commented on code in PR #6157:
URL: https://github.com/apache/netbeans/pull/6157#discussion_r1254905049


##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -472,4 +656,20 @@ private static class StringValueInfo {
             this.shortValueRef = new WeakReference<String>(shortenedValue);
         }
     }
+    private enum Utf16State{

Review Comment:
   ```suggestion
       private enum InternalStringEncoding {
   ```



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -472,4 +656,20 @@ private static class StringValueInfo {
             this.shortValueRef = new WeakReference<String>(shortenedValue);
         }
     }
+    private enum Utf16State{
+        /**
+         * The string is backed by an array of chars
+         */
+        Chars,

Review Comment:
   ```suggestion
           CHAR_ARRAY,
   ```



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -472,4 +656,20 @@ private static class StringValueInfo {
             this.shortValueRef = new WeakReference<String>(shortenedValue);
         }
     }
+    private enum Utf16State{
+        /**
+         * The string is backed by an array of chars
+         */
+        Chars,
+        /**
+         * The string is backed by an array of bytes with one byte per char
+         */
+        Latin1,

Review Comment:
   ```suggestion
           BYTE_ARRAY_LATIN1,
   ```



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -422,31 +606,31 @@ public String getFullString() {
 
         public Reader getContent() {
             return new Reader() {
-
                 int pos = 0;
-
                 @Override
                 public int read(char[] cbuf, int off, int len) throws 
IOException {
                     if (pos + len > length) {
                         len = length - pos;
                     }
-                    List<Value> values;
+                    if (len == 0){
+                        return -1;
+                    }
+//                    List<Value> values;
+//                    int grabCount = backingState == Utf16State.Utf16 ? len * 
2 :
+//                            len;

Review Comment:
   Please remove



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -472,4 +656,20 @@ private static class StringValueInfo {
             this.shortValueRef = new WeakReference<String>(shortenedValue);
         }
     }
+    private enum Utf16State{
+        /**
+         * The string is backed by an array of chars
+         */
+        Chars,
+        /**
+         * The string is backed by an array of bytes with one byte per char
+         */
+        Latin1,
+        /**
+         * The string is backed by an array of bytes with two bytes per char.
+         * Use {@link #isLittleEndian(com.sun.jdi.VirtualMachine)} to determine
+         * the byte order
+         */
+        Utf16

Review Comment:
   ```suggestion
           BYTE_ARRAY_UTF16
   ```



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -204,6 +209,9 @@ static String getStringWithLengthControl(StringReference 
sr) throws
         }
         String string = null;
         boolean isShort = true;
+        Utf16State backingState = Utf16State.Chars;
+        //I think we are going with 'true' by default
+        boolean isLittleEndian;// = true;

Review Comment:
   Please move declaration of `isLittleEndian` to initialisation site in 307. I 
would suggest to make it a `Boolean`, so that it is clear, that it might 
contain bogus data/is not valid. I thing asking the VM once for endianess 
should not be to big an issue (there is cache tied to the target machine), but 
ok.



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -262,6 +270,8 @@ else if (valuesField.type() instanceof ArrayType &&
                                 isUTF16 = true;
                             }
                         }
+                        backingState = isUTF16 ? Utf16State.Utf16 :

Review Comment:
   ```suggestion
                           backingEncoding = isUTF16 ? Utf16State.Utf16 :
   ```



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -385,19 +348,240 @@ else if (valuesField.type() instanceof ArrayType &&
         }
         return string;
     }
+    //would return char, but exceptions are expensive and so is boxing into
+    //a Character
+    /**
+     * (Currently untested) Grab the char at the given index in the array.
+     * Returns -1 on an error
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param index
+     * @param backing
+     * @param isLittleEndian
+     * @return
+     */
+    private static int charAt(ArrayReference sourceArray, int index,
+            Utf16State backing, boolean isLittleEndian) throws
+            InternalExceptionWrapper, ObjectCollectedExceptionWrapper,
+            VMDisconnectedExceptionWrapper{
+        if (backing == Utf16State.Chars){
+            //that was easy
+            Value v = ArrayReferenceWrapper.getValue(sourceArray, index);
+            if (!(v instanceof CharValue)){
+                return -1;
+            }
+            return ((CharValue)v).charValue();
+        }
+        if (backing == Utf16State.Latin1){
+            //that was also easy
+            Value v = ArrayReferenceWrapper.getValue(sourceArray, index);
+            if (!(v instanceof ByteValue)){
+                return -1;
+            }
+            char c = (char)((ByteValue)v).byteValue();
+            //strip off the sign value
+            c &= 0xff;
+            return c;
+        }
+        //uft16 it is
+        int hiByteShift, lowByteShift;
+        if (isLittleEndian){
+            hiByteShift = 0;
+            lowByteShift = 8;
+        }
+        else{
+            hiByteShift = 8;
+            lowByteShift = 0;
+        }
+        List<Value> vals = ArrayReferenceWrapper.getValues(sourceArray,
+                index * 2, 2);
+        Value left = vals.get(0);
+        Value right = vals.get(1);
+        if (!(left instanceof ByteValue && right instanceof ByteValue)){
+            return -1;
+        }
+        return utf16Combine(((ByteValue)left).byteValue(),
+                ((ByteValue)right).value(), hiByteShift, lowByteShift);
+    }
+    /**
+     * (Currently untested) Grab the char at the given index in the array.
+     * Returns -1 on an error
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param index
+     * @param backing
+     * @param isLittleEndian
+     * @return
+     */
+    private static int charAt(List<Value> sourceArray, int index,
+            Utf16State backing, boolean isLittleEndian){
+        if (backing == Utf16State.Chars){
+            //that was easy
+            Value v = sourceArray.get(index);
+            if (!(v instanceof CharValue)){
+                return -1;
+            }
+            return ((CharValue)v).charValue();
+        }
+        if (backing == Utf16State.Latin1){
+            //that was also easy
+            Value v = sourceArray.get(index);
+            if (!(v instanceof ByteValue)){
+                return -1;
+            }
+            char c = (char)((ByteValue)v).byteValue();
+            //strip off the sign value
+            c &= 0xff;
+            return c;
+        }
+        //uft16 it is
+        int hiByteShift, lowByteShift;
+        if (isLittleEndian){
+            hiByteShift = 0;
+            lowByteShift = 8;
+        }
+        else{
+            hiByteShift = 8;
+            lowByteShift = 0;
+        }
+        Value left = sourceArray.get(index * 2);
+        Value right = sourceArray.get((index * 2) + 1);
+        if (!(left instanceof ByteValue && right instanceof ByteValue)){
+            return -1;
+        }
+        return utf16Combine(((ByteValue)left).byteValue(),
+                ((ByteValue)right).value(), hiByteShift, lowByteShift);
+    }
+    /**
+     * Copy the input to the destination array as if by {@link 
System#arrayCopy}
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param backing
+     * @param isLittleEndian
+     * @param start
+     * @param length
+     * @param dest
+     * @return Null on success, otherwise an error message
+     */
+    private static String copyToCharArray(ArrayReference sourceArray,
+            int srcPos, char[] dest, int destPos, int length,
+            Utf16State backing, boolean isLittleEndian) throws
+            ObjectCollectedExceptionWrapper, VMDisconnectedExceptionWrapper,
+            InternalExceptionWrapper{
+        //grab applicable values
+        int realStart = srcPos;
+        int realLength = length;
+        if (backing == Utf16State.Utf16){
+            realStart *= 2;
+            realLength *= 2;
+        }
+        List<Value> values = ArrayReferenceWrapper.getValues(sourceArray,
+                realStart, realLength);
+        //copy them
+        return copyToCharArray(values, 0, dest, destPos, length, backing,
+                isLittleEndian);
+    }
+    /**
+     * Copy the input to the destination array as if by {@link 
System#arrayCopy}
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param backing
+     * @param isLittleEndian
+     * @param start
+     * @param length
+     * @param dest
+     * @return Null on success, otherwise an error message

Review Comment:
   From my POV this makes no sense. The call sites already have exception 
handling in place and unless we expect this to fail oftern, I would not add 
optimization prematurely. To this looks like a place to throw an IOException, 
which for the "read full string" does not even need to be caught (calling code 
already has to deal with it).



##########
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java:
##########
@@ -385,19 +348,240 @@ else if (valuesField.type() instanceof ArrayType &&
         }
         return string;
     }
+    //would return char, but exceptions are expensive and so is boxing into
+    //a Character
+    /**
+     * (Currently untested) Grab the char at the given index in the array.
+     * Returns -1 on an error
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param index
+     * @param backing
+     * @param isLittleEndian
+     * @return
+     */
+    private static int charAt(ArrayReference sourceArray, int index,
+            Utf16State backing, boolean isLittleEndian) throws
+            InternalExceptionWrapper, ObjectCollectedExceptionWrapper,
+            VMDisconnectedExceptionWrapper{
+        if (backing == Utf16State.Chars){
+            //that was easy
+            Value v = ArrayReferenceWrapper.getValue(sourceArray, index);
+            if (!(v instanceof CharValue)){
+                return -1;
+            }
+            return ((CharValue)v).charValue();
+        }
+        if (backing == Utf16State.Latin1){
+            //that was also easy
+            Value v = ArrayReferenceWrapper.getValue(sourceArray, index);
+            if (!(v instanceof ByteValue)){
+                return -1;
+            }
+            char c = (char)((ByteValue)v).byteValue();
+            //strip off the sign value
+            c &= 0xff;
+            return c;
+        }
+        //uft16 it is
+        int hiByteShift, lowByteShift;
+        if (isLittleEndian){
+            hiByteShift = 0;
+            lowByteShift = 8;
+        }
+        else{
+            hiByteShift = 8;
+            lowByteShift = 0;
+        }
+        List<Value> vals = ArrayReferenceWrapper.getValues(sourceArray,
+                index * 2, 2);
+        Value left = vals.get(0);
+        Value right = vals.get(1);
+        if (!(left instanceof ByteValue && right instanceof ByteValue)){
+            return -1;
+        }
+        return utf16Combine(((ByteValue)left).byteValue(),
+                ((ByteValue)right).value(), hiByteShift, lowByteShift);
+    }
+    /**
+     * (Currently untested) Grab the char at the given index in the array.
+     * Returns -1 on an error
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param index
+     * @param backing
+     * @param isLittleEndian
+     * @return
+     */
+    private static int charAt(List<Value> sourceArray, int index,
+            Utf16State backing, boolean isLittleEndian){
+        if (backing == Utf16State.Chars){
+            //that was easy
+            Value v = sourceArray.get(index);
+            if (!(v instanceof CharValue)){
+                return -1;
+            }
+            return ((CharValue)v).charValue();
+        }
+        if (backing == Utf16State.Latin1){
+            //that was also easy
+            Value v = sourceArray.get(index);
+            if (!(v instanceof ByteValue)){
+                return -1;
+            }
+            char c = (char)((ByteValue)v).byteValue();
+            //strip off the sign value
+            c &= 0xff;
+            return c;
+        }
+        //uft16 it is
+        int hiByteShift, lowByteShift;
+        if (isLittleEndian){
+            hiByteShift = 0;
+            lowByteShift = 8;
+        }
+        else{
+            hiByteShift = 8;
+            lowByteShift = 0;
+        }
+        Value left = sourceArray.get(index * 2);
+        Value right = sourceArray.get((index * 2) + 1);
+        if (!(left instanceof ByteValue && right instanceof ByteValue)){
+            return -1;
+        }
+        return utf16Combine(((ByteValue)left).byteValue(),
+                ((ByteValue)right).value(), hiByteShift, lowByteShift);
+    }
+    /**
+     * Copy the input to the destination array as if by {@link 
System#arrayCopy}
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param backing
+     * @param isLittleEndian
+     * @param start
+     * @param length
+     * @param dest
+     * @return Null on success, otherwise an error message
+     */
+    private static String copyToCharArray(ArrayReference sourceArray,
+            int srcPos, char[] dest, int destPos, int length,
+            Utf16State backing, boolean isLittleEndian) throws
+            ObjectCollectedExceptionWrapper, VMDisconnectedExceptionWrapper,
+            InternalExceptionWrapper{
+        //grab applicable values
+        int realStart = srcPos;
+        int realLength = length;
+        if (backing == Utf16State.Utf16){
+            realStart *= 2;
+            realLength *= 2;
+        }
+        List<Value> values = ArrayReferenceWrapper.getValues(sourceArray,
+                realStart, realLength);
+        //copy them
+        return copyToCharArray(values, 0, dest, destPos, length, backing,
+                isLittleEndian);
+    }
+    /**
+     * Copy the input to the destination array as if by {@link 
System#arrayCopy}
+     * @param sourceArray Backing array reference. May be a byte or char array
+     * @param backing
+     * @param isLittleEndian
+     * @param start
+     * @param length
+     * @param dest
+     * @return Null on success, otherwise an error message
+     */
+    private static String copyToCharArray(List<Value> sourceArray, int srcPos,
+            char[] dest, int destPos, int length, Utf16State backing,
+            boolean isLittleEndian){
+        if (backing == Utf16State.Chars){
+            //that was easy
+            for (int i = 0; i < length; i++) {
+                Value v = sourceArray.get(i + srcPos);
+                if (!(v instanceof CharValue)){
+                    return MessageFormat.format("Char at {0} is not a 
character: {1}", srcPos + i, v);
+                }
+                dest[destPos + i] = ((CharValue)v).charValue();
+            }
+            return null;
+        }
+        if (backing == Utf16State.Latin1){
+            //that was also easy
+            for (int i = 0; i < length; i++) {
+                Value v = sourceArray.get(i + srcPos);
+                if (!(v instanceof ByteValue)){
+                    return MessageFormat.format("Char at {0} is not a byte: 
{1}", srcPos + i, v);
+                }
+                char c = (char)((ByteValue)v).byteValue();
+                //strip off the sign value
+                c &= 0xff;
+                dest[destPos + i] = c;
+            }
+            return null;
+        }
+        //uft16 it is
+        assert backing == Utf16State.Utf16;
+        int hiByteShift, lowByteShift;
+        if (isLittleEndian){
+            hiByteShift = 0;
+            lowByteShift = 8;
+        }
+        else{
+            hiByteShift = 8;
+            lowByteShift = 0;
+        }
+        for (int i = 0; i < length; i++) {
+            Value left = sourceArray.get(i * 2);
+            Value right = sourceArray.get((i * 2) + 1);
+            if (!(left instanceof ByteValue && right instanceof ByteValue)){
+                return MessageFormat.format("Char at {0} is not a byte pair: "
+                        + "{1},{2}", srcPos + i, left, right);
+            }
+            dest[destPos + i] = utf16Combine(((ByteValue)left).byteValue(),
+                    ((ByteValue)right).byteValue(), hiByteShift, lowByteShift);
+        }
+        return null;
+    }
+    private static char utf16Combine(byte left, byte right, int hiByteShift,

Review Comment:
   `hiByteShift` and `lowByteShift` should be moved into `utf18Combine` and 
that method gets the `isLittleEndian` information. Then the logic is in one 
place.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@netbeans.apache.org
For additional commands, e-mail: notifications-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to