Uploaded image for project: 'QuickFIX/J'
  1. QuickFIX/J
  2. QFJ-382

Foreign Language Support - Multibyte Characters - Chinese

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Default
    • Resolution: Fixed
    • Affects Version/s: 1.3.3
    • Fix Version/s: 1.6.0
    • Component/s: Engine
    • Labels:
    • 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

        Unknown macro: {+ 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
        Unknown macro: {+ // "test data" in Chinese+ String input = "u6D4Bu9A8Cu6570u636E";+ + 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>

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                amichair amichair
                Reporter:
                jaubrey Jason Aubrey
              • Votes:
                3 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: