Author: rwhitcomb Date: Wed Jun 8 20:16:46 2016 New Revision: 1747449 URL: http://svn.apache.org/viewvc?rev=1747449&view=rev Log: PIVOT-989: Use the correct Charset in StringSerializer.writeObject(). The "getBytes()" call was not specifying any Charset, thus getting the platform default (which on Windows is usually Win-1252), which is usually not the same as the UTF-8 default which is used in this class. So, use the given Charset.
Also, in "trunk", use the StandardCharsets.UTF_8 value, instead of searching by name. Note: this part of the change will not be propagated to "2.0.x" because it still needs to compile under Java 6. Update the StringSerializerTest with a specific test of this, and include a byte dump so we can actually examine the bytes to make sure (the console output, especially on Windows, is not helpful). This is a merge of revision 1747445 from "trunk" to "branches/2.0.x", but with the StandardCharsets stuff changed because it is not supported in Java 6. Modified: pivot/branches/2.0.x/ (props changed) pivot/branches/2.0.x/core/src/org/apache/pivot/serialization/StringSerializer.java pivot/branches/2.0.x/core/test/org/apache/pivot/serialization/test/StringSerializerTest.java Propchange: pivot/branches/2.0.x/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Jun 8 20:16:46 2016 @@ -1 +1 @@ -/pivot/trunk:1346574,1347051,1394847,1394858,1398511,1399331,1401781,1405882,1407585,1409081,1410536,1410555,1417081,1417258,1428056,1428650,1435351,1436707,1438126,1438659,1444260,1444910,1502657,1510821,1516518,1519859,1522078,1523205,1523736,1523776,1525982,1526005,1536829,1537222,1604238,1610563,1611829,1614462,1624381,1675204,1675517,1678238,1678251,1687873-1687874,1688306,1688484,1688523,1691618,1712175,1717360,1727931,1728247,1729480,1729493,1730100,1730108,1740570 +/pivot/trunk:1346574,1347051,1394847,1394858,1398511,1399331,1401781,1405882,1407585,1409081,1410536,1410555,1417081,1417258,1428056,1428650,1435351,1436707,1438126,1438659,1444260,1444910,1502657,1510821,1516518,1519859,1522078,1523205,1523736,1523776,1525982,1526005,1536829,1537222,1604238,1610563,1611829,1614462,1624381,1675204,1675517,1678238,1678251,1687873-1687874,1688306,1688484,1688523,1691618,1712175,1717360,1727931,1728247,1729480,1729493,1730100,1730108,1740570,1747445 Modified: pivot/branches/2.0.x/core/src/org/apache/pivot/serialization/StringSerializer.java URL: http://svn.apache.org/viewvc/pivot/branches/2.0.x/core/src/org/apache/pivot/serialization/StringSerializer.java?rev=1747449&r1=1747448&r2=1747449&view=diff ============================================================================== --- pivot/branches/2.0.x/core/src/org/apache/pivot/serialization/StringSerializer.java (original) +++ pivot/branches/2.0.x/core/src/org/apache/pivot/serialization/StringSerializer.java Wed Jun 8 20:16:46 2016 @@ -25,8 +25,13 @@ import java.io.OutputStream; import java.nio.charset.Charset; /** - * Implementation of the {@link Serializer} interface that reads data from - * and writes data to Java Strings. + * Implementation of the {@link Serializer} interface that reads data from and + * writes data to Java Strings. The text data is interpreted using either the + * default <code>UTF-8</code> {@link Charset} or a <code>Charset</code> supplied + * in the constructor. + * <p> Instances of this class are reusable (and thread-safe) because no mutable + * instance data is used in the {@link #readObject} and {@link #writeObject} + * methods. */ public class StringSerializer implements Serializer<String> { private final Charset charset; @@ -53,13 +58,14 @@ public class StringSerializer implements } /** - * Reads plain text data from an input stream. + * Reads plain text data from an input stream, interpreted by the given {@link Charset}. * * @param inputStream * The input stream from which data will be read. * * @return * An instance of {@link String} containing the text read from the input stream. + * @see #getCharset */ @Override public String readObject(InputStream inputStream) throws IOException, SerializationException { @@ -90,13 +96,14 @@ public class StringSerializer implements } /** - * Writes plain text data to an output stream. + * Writes plain text data to an output stream, encoded in the given {@link Charset}. * * @param text * The text to be written to the output stream. * * @param outputStream * The output stream to which data will be written. + * @see #getCharset */ @Override public void writeObject(String text, OutputStream outputStream) @@ -111,7 +118,7 @@ public class StringSerializer implements try { BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); - bufferedOutputStream.write(text.getBytes()); + bufferedOutputStream.write(text.getBytes(charset)); bufferedOutputStream.flush(); } catch (IOException exception) { throw new SerializationException(exception); Modified: pivot/branches/2.0.x/core/test/org/apache/pivot/serialization/test/StringSerializerTest.java URL: http://svn.apache.org/viewvc/pivot/branches/2.0.x/core/test/org/apache/pivot/serialization/test/StringSerializerTest.java?rev=1747449&r1=1747448&r2=1747449&view=diff ============================================================================== --- pivot/branches/2.0.x/core/test/org/apache/pivot/serialization/test/StringSerializerTest.java (original) +++ pivot/branches/2.0.x/core/test/org/apache/pivot/serialization/test/StringSerializerTest.java Wed Jun 8 20:16:46 2016 @@ -16,6 +16,7 @@ */ package org.apache.pivot.serialization.test; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -23,6 +24,7 @@ import static org.junit.Assert.assertTru import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.nio.charset.Charset; import org.apache.pivot.serialization.SerializationException; import org.apache.pivot.serialization.Serializer; @@ -31,19 +33,38 @@ import org.junit.Test; public class StringSerializerTest { + private static final Charset UTF_8 = Charset.forName("UTF-8"); + // Note: include a real Unicode character to test the UTF-8 encoding public static final String testString = "// \n" + "// Hello from " - + StringSerializerTest.class.getName() + "\n" + "// \n"; - public static final byte[] testBytes = testString.getBytes(); + + StringSerializerTest.class.getSimpleName() + "\n" + "// \u03C0 r square \n" + + "// \n"; + public static final byte[] testBytes = testString.getBytes(UTF_8); public void log(String msg) { System.out.println(msg); } + public void logBytes(String msg, byte[] b) { + StringBuilder buf = new StringBuilder(b.length * 4); + buf.append('['); + for (int i = 0; i < b.length; i++) { + if (i > 0) + buf.append(','); + int ib = ((int)b[i]) & 0xFF; + String hex = Integer.toHexString(ib).toUpperCase(); + if (hex.length() < 2) + buf.append('0'); + buf.append(hex); + } + buf.append(']'); + log(msg + ": " + buf.toString() + "\n"); + } + @Test public void readValues() throws IOException, SerializationException { log("readValues()"); - Serializer<String> serializer = new StringSerializer(); + Serializer<String> serializer = new StringSerializer(UTF_8); ByteArrayInputStream inputStream = new ByteArrayInputStream(testBytes); String result = serializer.readObject(inputStream); @@ -52,8 +73,10 @@ public class StringSerializerTest { // dump content, but useful only for text resources ... String dump = result; - int dumpLength = dump.getBytes().length; + byte[] dumpBytes = dump.getBytes(); + int dumpLength = dumpBytes.length; log("Result: " + dumpLength + " bytes \n" + dump); + logBytes("Result bytes", dumpBytes); assertTrue(dumpLength > 0); } @@ -61,7 +84,8 @@ public class StringSerializerTest { @Test public void writeValues() throws IOException, SerializationException { log("writeValues()"); - +log("test string = \"" + testString + "\""); + // Note: assume the default Charset for StringSerializer is UTF-8, which we are using here Serializer<String> serializer = new StringSerializer(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -70,16 +94,19 @@ public class StringSerializerTest { outputStream.flush(); outputStream.close(); - String result = outputStream.toString(); + String result = outputStream.toString(UTF_8.name()); assertNotNull(result); assertEquals(result, testString); + byte[] resultBytes = outputStream.toByteArray(); + assertArrayEquals(resultBytes, testBytes); + // dump content, but useful only for text resources ... - String dump = result; - int dumpLength = dump.getBytes().length; - log("Result: " + dumpLength + " bytes \n" + dump); + log("Result: " + resultBytes.length + " bytes \n" + result); + logBytes("Result bytes", resultBytes); + logBytes(" Test bytes", testBytes); - assertTrue(dumpLength > 0); + assertTrue(resultBytes.length > 0); } }