Author | Message | Time |
---|---|---|
JoeTheOdd | Alright. I make an array list and add stuff to it. When it comes time, I make an array list, add sanity, add the ID, add the length, and add the other array list. Then I want to cast it to a byte array but noooo, VB wants to make it an Object array. When I try casting each Object to a byte, it yells at me. Obviously someone has figured it out but I've failed to find ANY way to do it, so if you'd enlighten me, it'd be appreciated. [code]Public Class clsPacketBuffer Private myBuffer As New ArrayList() Public Sub add_uint8(ByVal uint8 As Byte) myBuffer.Add(uint8) End Sub Private Sub add_uint8array(ByVal uint8() As Byte) Dim b As Byte For Each b In uint8 add_uint8(b) Next End Sub Public Sub add_uint16(ByVal uint16 As Short) add_uint8array(BitConverter.GetBytes(uint16)) End Sub Public Sub add_uint32(ByVal uint32 As Integer) add_uint8array(BitConverter.GetBytes(uint32)) End Sub Public Sub add_cstring(ByVal cstring As String) myBuffer.Add(cstring) add_uint8(0) End Sub Public Sub add_pstring(ByVal pstring As String) add_uint8(CType(Len(pstring), Byte)) myBuffer.Add(pstring) End Sub Public Sub add_void(ByVal void As String) myBuffer.Add(void) End Sub Public Function GetPacket(ByVal PacketID As Byte) As Byte() Dim Packet As New ArrayList Packet.Add(CType(&HFF, Byte)) Packet.Add(CType(PacketID, Byte)) Packet.Add(CType(myBuffer.Count + 4, Short)) Packet.Add(myBuffer) modFunctions.AddChat(Color.Blue, "[DEBUG] " + BitConverter.ToString(ObjectArrayToByteArray(Packet.ToArray))) GetPacket = ObjectArrayToByteArray(Packet.ToArray) myBuffer.Clear() End Function Private Function ObjectArrayToByteArray(ByVal O As Object()) As Byte() Dim B(0 To UBound(O)) As Byte, I As Integer For I = LBound(O) To UBound(O) B(I) = CType(O(I), Byte) Next I ObjectArrayToByteArray = B End Function End Class[/code] | June 29, 2006, 3:57 AM |
Myndfyr | http://www.jinxbot.net/mbncsutil/ See: DataBuffer class. | June 29, 2006, 4:24 AM |
K | Since you're using VB Express, which should be .NET 2.0, you might want to just go ahead and use a List<byte>, or whatever the stupid VB notation is, like List Of Type Byte or whatever. | June 29, 2006, 6:02 PM |
Myndfyr | Eww! List<byte> is SO much more memory-intensive than a MemoryStream (System.IO in mscorlib). | June 29, 2006, 8:48 PM |
JoeTheOdd | I've already (kind of) ported MyndFyre's DataBuffer as well as the GetData from BnetPacket(?). [code]Imports System Imports System.IO Imports System.Text Imports System.Runtime.InteropServices Public Class PacketBuffer Private m_ms As MemoryStream = New MemoryStream Private m_len As Integer = 0 Public Sub Insert_BOOL(ByVal b As Boolean) If b Then Insert_DWORD(1) Else Insert_DWORD(0) End If End Sub Public Sub Insert_BYTE(ByVal b As Byte) m_ms.WriteByte(b) m_len += 1 End Sub Public Sub Insert_WORD(ByVal w As UShort) m_ms.Write(BitConverter.GetBytes(w), 0, 2) m_len += 2 End Sub Public Sub Insert_DWORD(ByVal d As UInteger) m_ms.Write(BitConverter.GetBytes(d), 0, 4) m_len += 4 End Sub Public Sub Insert_QWORD(ByVal q As ULong) m_ms.Write(BitConverter.GetBytes(q), 0, 8) m_len += 8 End Sub Public Sub Insert_CSTR(ByVal s As String) Dim B As Byte For Each B In Encoding.ASCII.GetBytes(s) Insert_BYTE(B) Next Insert_BYTE(0) End Sub Public Sub Insert_PSTR(ByVal s As String) If s.Length < 256 Then Insert_BYTE(s.Length & &HFF) Dim B As Byte For Each B In Encoding.ASCII.GetBytes(s) Insert_BYTE(B) Next End If End Sub Public Sub Insert_PWSTR(ByVal s As String) If s.Length < 65536 Then Insert_WORD(s.Length & &HFFFFFF) Dim B As Byte For Each B In Encoding.ASCII.GetBytes(s) Insert_BYTE(B) Next End If End Sub Public Sub Insert_VOID(ByVal v As String) Dim B As Byte For Each B In Encoding.ASCII.GetBytes(v) Insert_BYTE(B) Next End Sub Public Function GetData(ByVal PacketID As Byte) As Byte() Dim baseData() As Byte = GetData() Dim ret(Count + 3) As Byte ret(0) = &HFF ret(1) = PacketID Dim len() As Byte = BitConverter.GetBytes(CType((Count + 4 & &HFFFF), UShort)) ret(2) = len(0) ret(3) = len(1) Buffer.BlockCopy(baseData, 0, ret, 4, baseData.Length) Return ret End Function Public Function GetData() As Byte() Dim ret(m_len) As Byte Buffer.BlockCopy(m_ms.GetBuffer(), 0, ret, 0, m_len) Return ret End Function Public ReadOnly Property Count() As Integer Get Return m_len End Get End Property End Class[/code] | June 29, 2006, 8:56 PM |
Dyndrilliac | Edit: I feel kind of stupid. Nevermind. I realize now I had a "::" operator where a "->" operator should have been. I'm converting the above code to C++.NET, and I'm having a bit of trouble with the Insert_CSTR method. I'm using the following namespaces:[code]using namespace System; using namespace System::Data; using namespace System::IO; using namespace System::Text; using namespace System::Runtime::InteropServices;[/code]Here's my code:[code]Void __inline Insert_CSTR(String^ cstring) { array<Byte>^ByteArray = Encoding::ASCII->GetBytes(cstring); for (UInt16 i = 0; i < ByteArray->GetLength(); i++) { Insert_BYTE(ByteArray[i]); } Insert_BYTE(0); }[/code]Here's the error:[code]f:\backup\public\source code\c++.net\personal projects\dyslexicchat v2\clsPacketBuffer.h(59) : error C2039: 'GetBytes' : is not a member of 'System::Text::Encoding::ASCII' f:\backup\public\source code\c++.net\personal projects\dyslexicchat v2\clsPacketBuffer.h(59) : see declaration of 'System::Text::Encoding::ASCII' f:\backup\public\source code\c++.net\personal projects\dyslexicchat v2\clsPacketBuffer.h(59) : error C3861: 'GetBytes': identifier not found[/code]I'm wondering where the GetBytes() method that the code shows is located; I'm using the .NET Framework v2.0. | August 31, 2006, 12:15 AM |
TheMinistered | Uhm, the very first thing I wanted to point out is that you use 'AddVoid'. The identifier void is associated with no data type. I guess you could coin it as a string datatype, but that totally defies the definition of VOID. If you wanted to associate any data type in .NET with void it would have to be OBJECT (my best guess). Although, I personally wouldn't associate any data type in vb with void. Then you implement CString and other weird STRING formats. I don't see the neccesity of this. You should stick with one string format, if possible, and comply to it through out your whole project -- otherwise things get real confusing and messy. just a tip | September 22, 2006, 6:29 PM |
Myndfyr | [quote author=TheMinistered link=topic=15296.msg158691#msg158691 date=1158949746] Uhm, the very first thing I wanted to point out is that you use 'AddVoid'. The identifier void is associated with no data type. I guess you could coin it as a string datatype, but that totally defies the definition of VOID. If you wanted to associate any data type in .NET with void it would have to be OBJECT (my best guess). Although, I personally wouldn't associate any data type in vb with void. Then you implement CString and other weird STRING formats. I don't see the neccesity of this. You should stick with one string format, if possible, and comply to it through out your whole project -- otherwise things get real confusing and messy. just a tip [/quote] I implemented the InsertCString, InsertPascalString, and InsertWidePascalString methods in a generalized packet buffer that I used in a networking project in the past. They're the three most common string formats, and when you include overloads to specify Encoding instances, they become incredibly flexible. | September 22, 2006, 7:28 PM |