Details
-
Type:
Improvement
-
Status:
Open
-
Priority:
Default
-
Resolution: Unresolved
-
Affects Version/s: 1.3.3
-
Fix Version/s: Future Releases
-
Component/s: Message Generation
-
Labels:None
-
Environment:All
Description
I need QFJ to support Chinese characters. So I modified my working copy to add this functionality/tests. I could simply commit the changes but I don't have write access to the repository. I'll just post the relevant changes here for now. It'd be nice if I could simply add all the diffs as attachments to this message.
Message.java
<pre>
public String toString() {
- header.setField(new BodyLength(bodyLength()));
+ try {
+ header.setField(new BodyLength(bodyLength()));
+ } catch(UnsupportedEncodingException e) {
+ LoggerFactory.getLogger(getClass()).error("toString failed, unsupported encoding", e);
+ return "";
+ }
trailer.setField(new CheckSum(checkSum()));
StringBuffer sb = new StringBuffer();
@@ -138,7 +145,7 @@
return sb.toString();
}
- public int bodyLength() {
+ public int bodyLength() throws UnsupportedEncodingException {
return header.calculateLength() + calculateLength() + trailer.calculateLength();
}
</pre>
Field.java
<pre>
- /*package*/ int getLength() {
+ /*package*/ int getLength() throws UnsupportedEncodingException {
calculate();
- return data.length()+1;
+ return data.getBytes(CharsetSupport.getCharset()).length+1;
}
</pre>
FieldTest.java
<pre>
- public void testFieldCalculations() {
+ public void testFieldCalculationsEnglish() throws Exception {
Field<String> object = new Field<String>(12, "VALUE");
object.setObject("VALUE");
assertEquals("12=VALUE", object.toString());
@@ -63,6 +65,22 @@
assertEquals(544, object.getTotal());
assertEquals(9, object.getLength());
}
+
+ public void testFieldCalculationsChinese() throws Exception {
+ try {
+ CharsetSupport.setCharset("UTF-8");
+ int tag = 13;
+ String value = "\u6D4B\u9A8C\u6570\u636E";
+ Field<String> object = new Field<String>(tag, value);
+ assertEquals(tag + "=" + value, object.toString());
+ assertEquals(119127, object.getTotal());
+ assertEquals(16, object.getLength());
+ } catch(Exception e) {
+ throw e;
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ }
</pre>
FIXMessageEncoder.java
<pre>
- public void testFieldCalculations() {
+ public void testFieldCalculationsEnglish() throws Exception {
Field<String> object = new Field<String>(12, "VALUE");
object.setObject("VALUE");
assertEquals("12=VALUE", object.toString());
@@ -63,6 +65,22 @@
assertEquals(544, object.getTotal());
assertEquals(9, object.getLength());
}
+
+ public void testFieldCalculationsChinese() throws Exception {
+ try {
+ CharsetSupport.setCharset("UTF-8");
+ int tag = 13;
+ String value = "\u6D4B\u9A8C\u6570\u636E";
+ Field<String> object = new Field<String>(tag, value);
+ assertEquals(tag + "=" + value, object.toString());
+ assertEquals(119127, object.getTotal());
+ assertEquals(16, object.getLength());
+ } catch(Exception e) {
+ throw e;
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ }
</pre>
FIXMessageEncoderTest.java
<pre>
public void testWesternEuropeanEncoding() throws Exception {
- // Default encoding, should work
- doEncodingTest();
-
- try {
- // This will break because of European characters
- CharsetSupport.setCharset("US-ASCII");
- doEncodingTest();
- } catch (ComparisonFailure e) {
- // expected
- } finally {
- CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
- }
+ // äbcfödçé
+ String input = "\u00E4bcf\u00F6d\u00E7\u00E9";
+
+ // Default encoding, should work
+ doEncodingTest(input);
+
+ try {
+ // This will break because of European characters
+ CharsetSupport.setCharset("US-ASCII");
+ doEncodingTest(input);
+ } catch (ComparisonFailure e) {
+ // expected
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
}
- private void doEncodingTest() throws ProtocolCodecException, UnsupportedEncodingException {
- // äbcfödçé
- String headline = "\u00E4bcf\u00F6d\u00E7\u00E9";
+ public void testChineseEncoding() throws Exception {
+ // "test data" in Chinese
+ String input = "\u6D4B\u9A8C\u6570\u636E";
+
+ try {
+ // This will break because the characters cannot be represented properly
+ doEncodingTest(input);
+ } catch (ComparisonFailure e) {
+ // expected
+ }
+
+ try {
+ // This should work
+ CharsetSupport.setCharset("UTF-8");
+ doEncodingTest(input);
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ }
+
+ private void doEncodingTest(String input) throws ProtocolCodecException, UnsupportedEncodingException {
News news = new News();
- news.set(new Headline(headline));
+ news.set(new Headline(input));
FIXMessageEncoder encoder = new FIXMessageEncoder();
ProtocolEncoderOutputForTest encoderOut = new ProtocolEncoderOutputForTest();
encoder.encode(null, news, encoderOut);
@@ -84,11 +105,24 @@
}
}
- public void testEncodingString() throws Exception {
+ public void testEncodingStringEnglish() throws Exception {
FIXMessageEncoder encoder = new FIXMessageEncoder();
ProtocolEncoderOutputForTest protocolEncoderOutputForTest = new ProtocolEncoderOutputForTest();
encoder.encode(null, "abcd", protocolEncoderOutputForTest);
assertEquals(4, protocolEncoderOutputForTest.buffer.limit());
}
+
+ public void testEncodingStringChinese() throws Exception {
+ FIXMessageEncoder encoder = new FIXMessageEncoder();
+ ProtocolEncoderOutputForTest protocolEncoderOutputForTest = new ProtocolEncoderOutputForTest();
+
+ try {
+ CharsetSupport.setCharset("UTF-8");
+ encoder.encode(null, "\u6D4B\u9A8C\u6570\u636E", protocolEncoderOutputForTest);
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ assertEquals(12, protocolEncoderOutputForTest.buffer.limit());
+ }
}
</pre>
Message.java
<pre>
public String toString() {
- header.setField(new BodyLength(bodyLength()));
+ try {
+ header.setField(new BodyLength(bodyLength()));
+ } catch(UnsupportedEncodingException e) {
+ LoggerFactory.getLogger(getClass()).error("toString failed, unsupported encoding", e);
+ return "";
+ }
trailer.setField(new CheckSum(checkSum()));
StringBuffer sb = new StringBuffer();
@@ -138,7 +145,7 @@
return sb.toString();
}
- public int bodyLength() {
+ public int bodyLength() throws UnsupportedEncodingException {
return header.calculateLength() + calculateLength() + trailer.calculateLength();
}
</pre>
Field.java
<pre>
- /*package*/ int getLength() {
+ /*package*/ int getLength() throws UnsupportedEncodingException {
calculate();
- return data.length()+1;
+ return data.getBytes(CharsetSupport.getCharset()).length+1;
}
</pre>
FieldTest.java
<pre>
- public void testFieldCalculations() {
+ public void testFieldCalculationsEnglish() throws Exception {
Field<String> object = new Field<String>(12, "VALUE");
object.setObject("VALUE");
assertEquals("12=VALUE", object.toString());
@@ -63,6 +65,22 @@
assertEquals(544, object.getTotal());
assertEquals(9, object.getLength());
}
+
+ public void testFieldCalculationsChinese() throws Exception {
+ try {
+ CharsetSupport.setCharset("UTF-8");
+ int tag = 13;
+ String value = "\u6D4B\u9A8C\u6570\u636E";
+ Field<String> object = new Field<String>(tag, value);
+ assertEquals(tag + "=" + value, object.toString());
+ assertEquals(119127, object.getTotal());
+ assertEquals(16, object.getLength());
+ } catch(Exception e) {
+ throw e;
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ }
</pre>
FIXMessageEncoder.java
<pre>
- public void testFieldCalculations() {
+ public void testFieldCalculationsEnglish() throws Exception {
Field<String> object = new Field<String>(12, "VALUE");
object.setObject("VALUE");
assertEquals("12=VALUE", object.toString());
@@ -63,6 +65,22 @@
assertEquals(544, object.getTotal());
assertEquals(9, object.getLength());
}
+
+ public void testFieldCalculationsChinese() throws Exception {
+ try {
+ CharsetSupport.setCharset("UTF-8");
+ int tag = 13;
+ String value = "\u6D4B\u9A8C\u6570\u636E";
+ Field<String> object = new Field<String>(tag, value);
+ assertEquals(tag + "=" + value, object.toString());
+ assertEquals(119127, object.getTotal());
+ assertEquals(16, object.getLength());
+ } catch(Exception e) {
+ throw e;
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ }
</pre>
FIXMessageEncoderTest.java
<pre>
public void testWesternEuropeanEncoding() throws Exception {
- // Default encoding, should work
- doEncodingTest();
-
- try {
- // This will break because of European characters
- CharsetSupport.setCharset("US-ASCII");
- doEncodingTest();
- } catch (ComparisonFailure e) {
- // expected
- } finally {
- CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
- }
+ // äbcfödçé
+ String input = "\u00E4bcf\u00F6d\u00E7\u00E9";
+
+ // Default encoding, should work
+ doEncodingTest(input);
+
+ try {
+ // This will break because of European characters
+ CharsetSupport.setCharset("US-ASCII");
+ doEncodingTest(input);
+ } catch (ComparisonFailure e) {
+ // expected
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
}
- private void doEncodingTest() throws ProtocolCodecException, UnsupportedEncodingException {
- // äbcfödçé
- String headline = "\u00E4bcf\u00F6d\u00E7\u00E9";
+ public void testChineseEncoding() throws Exception {
+ // "test data" in Chinese
+ String input = "\u6D4B\u9A8C\u6570\u636E";
+
+ try {
+ // This will break because the characters cannot be represented properly
+ doEncodingTest(input);
+ } catch (ComparisonFailure e) {
+ // expected
+ }
+
+ try {
+ // This should work
+ CharsetSupport.setCharset("UTF-8");
+ doEncodingTest(input);
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ }
+
+ private void doEncodingTest(String input) throws ProtocolCodecException, UnsupportedEncodingException {
News news = new News();
- news.set(new Headline(headline));
+ news.set(new Headline(input));
FIXMessageEncoder encoder = new FIXMessageEncoder();
ProtocolEncoderOutputForTest encoderOut = new ProtocolEncoderOutputForTest();
encoder.encode(null, news, encoderOut);
@@ -84,11 +105,24 @@
}
}
- public void testEncodingString() throws Exception {
+ public void testEncodingStringEnglish() throws Exception {
FIXMessageEncoder encoder = new FIXMessageEncoder();
ProtocolEncoderOutputForTest protocolEncoderOutputForTest = new ProtocolEncoderOutputForTest();
encoder.encode(null, "abcd", protocolEncoderOutputForTest);
assertEquals(4, protocolEncoderOutputForTest.buffer.limit());
}
+
+ public void testEncodingStringChinese() throws Exception {
+ FIXMessageEncoder encoder = new FIXMessageEncoder();
+ ProtocolEncoderOutputForTest protocolEncoderOutputForTest = new ProtocolEncoderOutputForTest();
+
+ try {
+ CharsetSupport.setCharset("UTF-8");
+ encoder.encode(null, "\u6D4B\u9A8C\u6570\u636E", protocolEncoderOutputForTest);
+ } finally {
+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
+ }
+ assertEquals(12, protocolEncoderOutputForTest.buffer.limit());
+ }
}
</pre>
The revision number of my working copy is 892 (was head revision last week at least).