Index: src/org/netbeans/mdr/persistence/btreeimpl/btreeindex/StringInfo.java =================================================================== RCS file: /cvs/mdr/src/org/netbeans/mdr/persistence/btreeimpl/btreeindex/StringInfo.java,v retrieving revision 1.1 diff -u -r1.1 StringInfo.java --- src/org/netbeans/mdr/persistence/btreeimpl/btreeindex/StringInfo.java 11 Jan 2002 16:28:06 -0000 1.1 +++ src/org/netbeans/mdr/persistence/btreeimpl/btreeindex/StringInfo.java 22 Feb 2002 16:16:23 -0000 @@ -20,7 +20,6 @@ */ public class StringInfo extends EntryTypeInfo { - public String typeName() { return new String("String"); @@ -31,25 +30,80 @@ if (!(object instanceof String)) { return null; } else { - String s = (String) object; - return s.getBytes(); + String s = (String)object; + int l = s.length(); + char[] arr = new char[l]; + int utflen = 0; + char c; + + s.getChars(0, l, arr, 0); + for (int i = 0; i < l; i++) { + c = arr[i]; + if (c < 0x7f) { + utflen++; + } else if (c > 0x7ff) { + utflen += 3; + } else { + utflen += 2; + } + } + byte[] encoded = new byte[utflen]; + int offset = 0; + for (int i = 0; i < l; i++) { + c = arr[i]; + if (c < 0x007f) { + encoded[offset++] = (byte)c; + } else if (c > 0x07ff) { + encoded[offset++] = (byte)(0xe0 | ((c >> 12) & 0x0f)); + encoded[offset++] = (byte)(0x80 | ((c >> 6) & 0x3f)); + encoded[offset++] = (byte)(0x80 | (c & 0x3f)); + } else { + encoded[offset++] = (byte)(0xc0 | ((c >> 6) & 0x1f)); + encoded[offset++] = (byte)(0x80 | (c & 0x3f)); + } + } + return encoded; } } + + static int fromBufferCount = 0; public Object fromBuffer(byte[] buffer) { - return new String(buffer); + int length = buffer.length; + int offset = 0; + StringBuffer sb = new StringBuffer(length); + do { + int b = buffer[offset++] & 0xff; + if (b >= 0xe0) { + b = (b & 0x0f) << 12; + b |= (buffer[offset++] & 0x3f) << 6; + b |= buffer[offset++] & 0x3f; + } else if (b >= 0xc0) { + b = (b & 0x1f) << 6; + b |= buffer[offset++] & 0x3f; + } + sb.append((char)b); + } while (--length > 0); + return new String(sb); + } + + final int compareImpl(byte[] key1buffer, byte[] key2buffer, int offset, int length) { + int key1len = key1buffer.length; + byte c1, c2; + int key1offset = 0; + + int n = Math.min(key1len, length); + while (n-- > 0) { + c1 = key1buffer[key1offset++]; + c2 = key2buffer[offset++]; + if (c1 != c2) + return c1 - c2; + } + return key1len - length; } public byte compare(byte[] key1buffer, byte[] key2buffer, int offset, int length) { - - String key1, key2; - int result; - - key1 = new String(key1buffer); - key2 = new String(key2buffer, offset, length); - - result = key1.compareTo(key2); - + int result = compareImpl(key1buffer, key2buffer, offset, length); if (result < 0) { return LESS; } else if (result > 0) { Index: src/org/netbeans/mdr/util/IOUtils.java =================================================================== RCS file: /cvs/mdr/src/org/netbeans/mdr/util/IOUtils.java,v retrieving revision 1.2 diff -u -r1.2 IOUtils.java --- src/org/netbeans/mdr/util/IOUtils.java 13 Feb 2002 15:47:35 -0000 1.2 +++ src/org/netbeans/mdr/util/IOUtils.java 22 Feb 2002 16:16:23 -0000 @@ -59,35 +59,49 @@ write(outputStream, object, null); } + public static void writeInt(OutputStream outputStream, int val) throws IOException { + if ((int) ((byte) val & 0xFF) == val) { + outputStream.write(T_BYTE); + outputStream.write((byte)val); + } else if ((int) ((byte) (val >> 8) & 0xFF) == val >> 8) { + outputStream.write(T_SHORT); + outputStream.write((byte)(val & 0xff)); + outputStream.write((byte)((val & 0xff00) >> 8)); + } else { + outputStream.write(T_INTEGER); + outputStream.write((byte)(val & 0xff)); + outputStream.write((byte)((val & 0xff00) >> 8)); + outputStream.write((byte)((val & 0xff0000) >> 16)); + val = (val >> 24) & 0xff; + outputStream.write((byte)val); + } + } + public static void write(OutputStream outputStream, Object object, MdrStorage storage) throws IOException { if (object == null) { outputStream.write(T_NULL); } else if (object instanceof String) { + String val = (String)object; outputStream.write(T_STRING); - byte val[] = ((String) object).getBytes("UTF-8"); - write(outputStream, new Integer(val.length)); - outputStream.write(val); - - } else if (object instanceof Integer) { - int val = ((Integer) object).intValue(); - int size; - if ((int) ((byte) val & 0xFF) == val) { - outputStream.write(T_BYTE); - size = 1; - } else if ((int) ((byte) (val >> 8) & 0xFF) == val >> 8) { - outputStream.write(T_SHORT); - size = 2; - } else { - outputStream.write(T_INTEGER); - size = 4; - } - byte res[] = new byte[size]; - for (int i = 0; i < size; i++) { - res[i] = (byte) ((val >> (i * 8)) & 0xFF); + int len = val.length(); + writeInt(outputStream, len); + for (int i = 0; i < len; i++) { + char ch = val.charAt(i); + if (ch <= 0x7f) { + outputStream.write((byte)ch); + } else if (ch <= 0x7ff) { + outputStream.write((byte)(0xc0 | (ch >> 6))); + outputStream.write((byte)(0x80 | (ch & 0x3f))); + } else { + outputStream.write((byte)(0xe0 | (ch >> 12))); + outputStream.write((byte)(0x80 | ((ch >> 6) & 0x3f))); + outputStream.write((byte)(0x80 | (ch & 0x3f))); + } } - outputStream.write(res); - + } else if (object instanceof Integer) { + int val = ((Integer)object).intValue(); + writeInt(outputStream, val); } else if (object instanceof Boolean) { outputStream.write(T_BOOLEAN); outputStream.write(((Boolean) object).booleanValue() ? 1 : 0); @@ -174,38 +188,72 @@ return read(inputStream, storable, null); } + public static int readInt(InputStream is) throws IOException { + return readInt(is, is.read()); + } + + public static int readInt(InputStream inputStream, int type) throws IOException { + switch (type) { + case T_BYTE: { + int ch = inputStream.read(); + if (ch < 0) + throw new IOException("EOF"); + return ch; + } + case T_SHORT: { + int ch1, ch2; + ch1 = inputStream.read(); + ch2 = inputStream.read(); + if ((ch1 | ch2) < 0) { + throw new IOException("EOF"); + } + return (ch2 << 8) | ch1; + } + case T_INTEGER: { + int ch1, ch2, ch3, ch4; + ch1 = inputStream.read(); + ch2 = inputStream.read(); + ch3 = inputStream.read(); + ch4 = inputStream.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) { + throw new IOException("EOF"); + } + return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + ch1; + } + default: + throw new IOException("Unknown int format: " + type); + } + } + public static Object read(InputStream inputStream, StorableBaseObject storable, String className) throws IOException { int type; switch (type = inputStream.read()) { case T_NULL: { return null; } case T_STRING: { - int length = ((Integer) read(inputStream, storable)).intValue(); - byte val[] = new byte[length]; - inputStream.read(val); - return new String(val, "UTF-8"); - } case T_INTEGER: - case T_BYTE: - case T_SHORT: { - int size; - if (type == T_BYTE) { - size = 1; - } else if (type == T_SHORT) { - size = 2; - } else { - size = 4; - } - byte val[] = new byte[size]; - inputStream.read(val); - int res = 0; -// System.out.println("length:"); - for (int i = 0; i < size; i++) { -// System.out.println("" + ((256 + val[i]) % 256)); - res |= ((256 + val[i]) % 256) << (i * 8); - } -// System.out.println("" + res); - return new Integer(res); - } case T_BOOLEAN: { + int length = readInt(inputStream); + if (length == 0) + return ""; + StringBuffer sb = new StringBuffer(length); + do { + int b = inputStream.read() & 0xff; + if (b >= 0xe0) { + b = (b & 0x0f) << 12; + b |= (inputStream.read() & 0x3f) << 6; + b |= inputStream.read() & 0x3f; + } else if (b >= 0xc0) { + b = (b & 0x1f) << 6; + b |= inputStream.read() & 0x3f; + } + sb.append((char)b); + } while (--length > 0); + return new String(sb); + } + case T_BYTE: + case T_SHORT: + case T_INTEGER: + return new Integer(readInt(inputStream, type)); + case T_BOOLEAN: { return new Boolean(inputStream.read() == 1); } case T_MAP: { //if (storable == null) Thread.dumpStack();