Author Topic: Read string using BitStream at c#  (Read 19646 times)

NeptuneX

  • Guest
Read string using BitStream at c#
« on: April 25, 2012, 04:03:40 AM »
I have a C++ exe run as raknet server, a C# exe run as client.
C++ exe send a string to C# exe.
a very important feature is that the string was utf8 encoded
Code: [Select]
bool XMain::SetStringByID(int controlID, const char *str_utf8)
{
BitStream stream;
stream.Write((MessageID)ID_USER_PACKET_ENUM);
stream.Write((int)CmdU_SetStringByID);
stream.Write(controlID);
stream.Write(str_utf8);
return m_sink->SendStream(stream,mGuid);
}
I wrote below at c# side:
Code: [Select]
 
  string msg;
  rakStream4Recv.Read(out msg);   
  msg = utf8.GetString(System.Text.Encoding.Default.GetBytes(msg));
I think bytes on net was  treated as local ASCII,and implicit convert from default=>unicode .this convertion is obviously WRONG!
so I'd like to use default encoding to decode msg ,  restore them to the original utf8 string,
at last encode them from utf8 to unicode.
The PROBLEM is sometimes,the implicit convertion made some character lose,"System.Text.Encoding.Default.GetBytes" can't restore original utf8 byte[].
-
now,I'll change my mind.I should read utf8 byte[] from BitStream by two separate step:
Code: [Select]
   
                            UInt16 bytelen;
                            byte[] readbyte;
                            string msg;
                            rakStream4Recv.Read(out bytelen);  // ???
                            rakStream4Recv.Read(readbyte,bytelen);
                            msg = utf8.GetString(readbyte)
new PROBLEM is HOW to Read a short integer by C# BitStream

NeptuneX

  • Guest
Re: Read string using BitStream at c#
« Reply #1 on: April 25, 2012, 04:50:06 AM »
I certify that implicit convertion should be avoid.
Code: [Select]
                            string str;
                            UInt16 sstrlen;
                            byte[] outlenb = new byte[2];
                            byte[] outmsg;
                            UTF8Encoding utf8 = new UTF8Encoding();
                            rakStream4Recv.Read(outlenb, 2);
                            sstrlen = outlenb[0];            //endian swap.
                            outlenb[0] = outlenb[1];
                            outlenb[1] = (byte)sstrlen; 
                            sstrlen = BitConverter.ToUInt16(outlenb, 0);
                            outmsg = new byte[sstrlen];
                            rakStream4Recv.Read(outmsg, sstrlen);
                            str = utf8.GetString(outmsg);
Micro C# look wise :(

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: Read string using BitStream at c#
« Reply #2 on: April 25, 2012, 09:36:03 AM »
Eh, I don't follow you. Why don't you just use RakWString, or use BitStream::WriteBytes()? If you want to read 16 bits, what is wrong with UInt16? Isn't that 16 bits?

NeptuneX

  • Guest
Re: Read string using BitStream at c#
« Reply #3 on: April 25, 2012, 11:31:47 AM »
read uint16 is invalid because their was no uint16 implement of BitStream.Read . (only char,int,float,long,string,rakstring,byte[]...)
I'll try RakWString, I will come back if it works..

NeptuneX

  • Guest
Re: Read string using BitStream at c#
« Reply #4 on: April 25, 2012, 11:50:50 AM »
TestMain.cs(102,21): 错误 CS1502: 与“RakNet.BitStream.Read(out string)”最匹配的重载方法具有一些无效参数
TestMain.cs(102,47): 错误 CS1503: 参数“1”: 无法从“out ushort”转换为“out string”

these error show that there was no matched function to call.
Maybe I/you can write some swig script as "bitstream.i" and expose "bool BitStream.Read(out UInt16)"?

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: Read string using BitStream at c#
« Reply #5 on: April 25, 2012, 01:07:12 PM »
If you replace DependentExtensions\Swig\SwigInterfaceFiles\RakNetCSharpTemplateDefines.i with the attached and rebuild SWIG, does that help?

NeptuneX

  • Guest
Re: Read string using BitStream at c#
« Reply #6 on: April 25, 2012, 10:40:10 PM »
Yes it works! add this
Code: [Select]
%template(Read) RakNet::BitStream::Read <unsigned short>;
%template(Write) RakNet::BitStream::Write <unsigned short>;
%template(ReadDelta) RakNet::BitStream::ReadDelta <unsigned short>;
....any more if you need.   <File:RakNetCSharpTemplateDefines.i>
and this
Code: [Select]
//For the read functions, out vars
%apply unsigned short &OUTPUT {unsigned short &outTemplateVar};
//Inouts for serialize and such
%apply unsigned short &INOUT {unsigned short &inOutTemplateVar};

%apply unsigned short &INOUT {unsigned short &inOutCurrentValue};
... <File:RakNetCSharpTypeMaps.i>
If you replace DependentExtensions\Swig\SwigInterfaceFiles\RakNetCSharpTemplateDefines.i with the attached and rebuild SWIG, does that help?

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: Read string using BitStream at c#
« Reply #7 on: April 26, 2012, 09:18:26 AM »
If you have short, is it necessary to add unsigned short too?

NeptuneX

  • Guest
Re: Read string using BitStream at c#
« Reply #8 on: April 26, 2012, 09:56:02 AM »
we can explicit convert it to unsigned short. :)
C# is strongly-typed language,add both of them should be more good :D     anyway,I'm lazy.