summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--java/io/DataOutputStream.java104
2 files changed, 77 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 688bf069d..8a2c28fa1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2006-04-11 Bryce McKinlay <mckinlay@redhat.com>
+
+ * java/io/DataOutputStream.java (writeUTF): Re-use fixed length byte
+ buffer. Loop only once to determine Utf8 length when possible. Make
+ the inner loop bounded by buf.length.
+ (getUTFlength): New private method.
+ (buf): New private field.
+
2006-04-11 Lillian Angel <langel@redhat.com>
* gnu/xml/dom/DomNodeIterator.java
diff --git a/java/io/DataOutputStream.java b/java/io/DataOutputStream.java
index 25178160d..fcaa97eec 100644
--- a/java/io/DataOutputStream.java
+++ b/java/io/DataOutputStream.java
@@ -63,6 +63,11 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput
protected int written;
/**
+ * Utf8 byte buffer, used by writeUTF()
+ */
+ private byte[] buf;
+
+ /**
* This method initializes an instance of <code>DataOutputStream</code> to
* write its data to the specified underlying <code>OutputStream</code>
*
@@ -373,6 +378,37 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput
}
/**
+ * Calculate the length, in bytes, of a <code>String</code> in Utf8 format.
+ *
+ * @param value The <code>String</code> to measure
+ * @param start String index at which to begin count
+ * @param sum Starting Utf8 byte count
+ *
+ * @throws UTFDataFormatException if result would exceed 65535
+ */
+ private int getUTFlength(String value, int start, int sum)
+ throws IOException
+ {
+ int len = value.length();
+
+ for (int i = start; i < len && sum <= 65535; ++i)
+ {
+ char c = value.charAt(i);
+ if (c >= '\u0001' && c <= '\u007f')
+ sum += 1;
+ else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
+ sum += 2;
+ else
+ sum += 3;
+ }
+
+ if (sum > 65535)
+ throw new UTFDataFormatException ();
+
+ return sum;
+ }
+
+ /**
* This method writes a Java <code>String</code> to the stream in a modified
* UTF-8 format. First, two bytes are written to the stream indicating the
* number of bytes to follow. Note that this is the number of bytes in the
@@ -407,48 +443,46 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput
public final synchronized void writeUTF(String value) throws IOException
{
int len = value.length();
- int sum = 0;
-
- for (int i = 0; i < len && sum <= 65535; ++i)
- {
- char c = value.charAt(i);
- if (c >= '\u0001' && c <= '\u007f')
- sum += 1;
- else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
- sum += 2;
- else
- sum += 3;
- }
-
- if (sum > 65535)
- throw new UTFDataFormatException ();
-
+ int i = 0;
int pos = 0;
- byte[] buf = new byte[sum];
+ boolean lengthWritten = false;
- for (int i = 0; i < len; ++i)
+ if (buf == null)
+ buf = new byte[512];
+
+ while (i < len)
{
- char c = value.charAt(i);
- if (c >= '\u0001' && c <= '\u007f')
- buf[pos++] = (byte) c;
- else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
+ while (i < len && pos < buf.length - 3)
{
- buf[pos++] = (byte) (0xc0 | (0x1f & (c >> 6)));
- buf[pos++] = (byte) (0x80 | (0x3f & c));
+ char c = value.charAt(i++);
+ if (c >= '\u0001' && c <= '\u007f')
+ buf[pos++] = (byte) c;
+ else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
+ {
+ buf[pos++] = (byte) (0xc0 | (0x1f & (c >> 6)));
+ buf[pos++] = (byte) (0x80 | (0x3f & c));
+ }
+ else
+ {
+ // JSL says the first byte should be or'd with 0xc0, but
+ // that is a typo. Unicode says 0xe0, and that is what is
+ // consistent with DataInputStream.
+ buf[pos++] = (byte) (0xe0 | (0x0f & (c >> 12)));
+ buf[pos++] = (byte) (0x80 | (0x3f & (c >> 6)));
+ buf[pos++] = (byte) (0x80 | (0x3f & c));
+ }
}
- else
+ if (! lengthWritten)
{
- // JSL says the first byte should be or'd with 0xc0, but
- // that is a typo. Unicode says 0xe0, and that is what is
- // consistent with DataInputStream.
- buf[pos++] = (byte) (0xe0 | (0x0f & (c >> 12)));
- buf[pos++] = (byte) (0x80 | (0x3f & (c >> 6)));
- buf[pos++] = (byte) (0x80 | (0x3f & c));
+ if (i == len)
+ writeShort(pos);
+ else
+ writeShort(getUTFlength(value, i, pos));
+ lengthWritten = true;
}
- }
-
- writeShort (sum);
- write(buf, 0, sum);
+ write(buf, 0, pos);
+ pos = 0;
+ }
}
} // class DataOutputStream