Archived

This forum has been archived. Please start a new discussion on GitHub.

Encoding Problem about Chinese, client compiled by Java, server compiled by C++

a project server compiled by C++ and client compiled by java for display, but a problem comes when Chinese display.
when I compiled client by C++, the Chinese display is normal, but when I compiled client by java, the Chinese display isn't normal, that's disorder.
Now I solved it by update the source, under directory "src/IceInternal".
If there others way solve it, such as update config etc.??

Comments

  • benoit
    benoit Rennes, France
    Hello,

    I'm afraid we can't help you without more information about your problem. Could you post the sample source code that demonstrates the problem? How do you print the strings in the C++ and Java client for instance?

    Also, what did you change in src/IceInternal to get it to work?

    Benoit.
  • my code as follows:

    ice definition:
    #ifndef HELLO_ICE
    #define HELLO_ICE

    module Demo
    {

    interface Hello
    {
    nonmutating void sayHello();
    };

    };

    #endif



    C++ implement server:
    HelloI::sayHello(const Ice::Current&) const
    {
    cout << "Hello World!哈哈哈哈哈哈哈" << endl;
    }

    when java client call 'sayHello' on windows the result is:
    Hello World!?????????


    The source I update is:
    the directory: IceJ-2.1.2/src/IceInternal
    the file :BasicStream.java
    I note the 'UTF8' encode is the main modification.
    the result of differ as follow:
    diff -r IceJ-2.1.2.1/src/IceInternal/BasicStream.java IceJ-2.1.2/src/IceInternal/BasicStream.java
    1038c1038
    < // try
    ---
    > try
    1040,1041c1040
    < //byte[] arr = v.getBytes("UTF8");
    < byte[] arr = v.getBytes();
    ---
    > byte[] arr = v.getBytes("UTF8");
    1046,1049c1045,1048
    < // catch(java.io.UnsupportedEncodingException ex)
    < // {
    < // assert(false);
    < // }
    ---
    > catch(java.io.UnsupportedEncodingException ex)
    > {
    > assert(false);
    > }
    1121,1122c1120
    < //return new String(_stringBytes, 0, len, "UTF8");
    < return new String(_stringBytes, 0, len);
    ---
    > return new String(_stringBytes, 0, len, "UTF8");
    1131c1129
    < /* catch(java.io.UnsupportedEncodingException ex)
    ---
    > catch(java.io.UnsupportedEncodingException ex)
    1136c1134
    < */ catch(java.nio.BufferUnderflowException ex)
    ---
    > catch(java.nio.BufferUnderflowException ex)
  • benoit
    benoit Rennes, France
    Is this really the code you're using? The code you posted doesn't receive a string over the wire, it just prints a string on the standard error output so I don't see how invoking the sayHello() method would print different strings if invoked from a C++ client or Java client.

    It's also not quite clear from the diff output what are the changes you made. Could you just post your BasicStream.java file with your modifications as an attachment?

    Benoit.
  • Because the code I using is much, I didn't paste it. I only want to explain the phenomenon that display the Chinese through the code as above, it isn't the code I using.

    the BasicStream.java I modified as follow:
    public void
    writeString(String v)
    {
    if(v == null)
    {
    writeSize(0);
    }
    else
    {
    final int len = v.length();
    if(len > 0)
    {
    // try
    {
    //byte[] arr = v.getBytes("UTF8");
    byte[] arr = v.getBytes();
    writeSize(arr.length);
    expand(arr.length);
    _buf.put(arr);
    }
    // catch(java.io.UnsupportedEncodingException ex)
    // {
    // assert(false);
    // }
    }
    else
    {
    writeSize(0);
    }
    }
    }

    public void
    writeStringSeq(String[] v)
    {
    if(v == null)
    {
    writeSize(0);
    }
    else
    {
    writeSize(v.length);
    for(int i = 0; i < v.length; i++)
    {
    writeString(v);
    }
    }
    }

    public String
    readString()
    {
    final int len = readSize();

    if(len == 0)
    {
    return "";
    }
    else
    {
    try
    {
    //
    // We reuse the _stringBytes array to avoid creating
    // excessive garbage
    //
    if(_stringBytes == null || len > _stringBytes.length)
    {
    _stringBytes = new byte[len];
    _stringChars = new char[len];
    }
    _buf.get(_stringBytes, 0, len);

    //
    // It's more efficient to construct a string using a
    // character array instead of a byte array, because
    // byte arrays require conversion.
    //
    for(int i = 0; i < len; i++)
    {
    if(_stringBytes < 0)
    {
    //
    // Multi-byte character found - we must use
    // conversion.
    //
    // TODO: If the string contains garbage bytes
    // that won't correctly decode as UTF, the
    // behavior of this constructor is
    // undefined. It would be better to explicitly
    // decode using
    // java.nio.charset.CharsetDecoder and to
    // throw MarshalException if the string won't
    // decode.
    //
    //return new String(_stringBytes, 0, len, "UTF8");
    return new String(_stringBytes, 0, len);
    }
    else
    {
    _stringChars = (char)_stringBytes;
    }
    }
    return new String(_stringChars, 0, len);
    }
    /* catch(java.io.UnsupportedEncodingException ex)
    {
    assert(false);
    return "";
    }
    */ catch(java.nio.BufferUnderflowException ex)
    {
    throw new Ice.UnmarshalOutOfBoundsException();
    }
    }
    }
  • bernard
    bernard Jupiter, FL
    Since the string displayed by your C++ program is not transmitted by Ice, Ice is not involved. And your change to the Ice source code does not help.

    In C++, to display wide-strings, you should use wcout, e.g.:
    wcout << L"Hello World [chinese characters]" << endl;

    Cheers,
    Bernard
  • Re
    bernard wrote:
    Since the string displayed by your C++ program is not transmitted by Ice, Ice is not involved. And your change to the Ice source code does not help.

    In C++, to display wide-strings, you should use wcout, e.g.:
    wcout << L"Hello World [chinese characters]" << endl;

    Cheers,
    Bernard
    In C++ Service you should encoding you local text to UTF-8, then you can receive correct message in java client ,so you can encoding you message text in java with GB2312! good luck!