From 38efe73154f30200fafb2631b17106bc6935ae05 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 2 Sep 2012 19:38:37 +0000 Subject: Added writing support to cByteBuffer (will be used by ProtoProxy) git-svn-id: http://mc-server.googlecode.com/svn/trunk@825 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ByteBuffer.cpp | 140 ++++++++++++++++++++++++++++++++++++++++++++++++-- source/ByteBuffer.h | 23 +++++++-- 2 files changed, 157 insertions(+), 6 deletions(-) diff --git a/source/ByteBuffer.cpp b/source/ByteBuffer.cpp index af7151260..0f360a104 100644 --- a/source/ByteBuffer.cpp +++ b/source/ByteBuffer.cpp @@ -12,7 +12,8 @@ -#define NEEDBYTES(Num) if (!CanReadBytes(Num)) return false; +#define NEEDBYTES(Num) if (!CanReadBytes(Num)) return false; +#define PUTBYTES(Num) if (!CanWriteBytes(Num)) return false; @@ -121,10 +122,19 @@ bool cByteBuffer::CanReadBytes(int a_Count) const +bool cByteBuffer::CanWriteBytes(int a_Count) const +{ + return (a_Count <= GetFreeSpace()); +} + + + + + bool cByteBuffer::ReadChar(char & a_Value) { NEEDBYTES(1); - a_Value = m_Buffer[m_ReadPos++]; + ReadBuf(&a_Value, 1); return true; } @@ -135,7 +145,7 @@ bool cByteBuffer::ReadChar(char & a_Value) bool cByteBuffer::ReadByte(unsigned char & a_Value) { NEEDBYTES(1); - a_Value = (unsigned char)(m_Buffer[m_ReadPos++]); + ReadBuf(&a_Value, 1); return true; } @@ -228,6 +238,106 @@ bool cByteBuffer::ReadBEUTF16String16(AString & a_Value) +bool cByteBuffer::WriteChar(char a_Value) +{ + PUTBYTES(1); + return WriteBuf(&a_Value, 1); +} + + + + + +bool cByteBuffer::WriteByte(unsigned char a_Value) +{ + PUTBYTES(1); + return WriteBuf(&a_Value, 1); +} + + + + + +bool cByteBuffer::WriteBEShort(short a_Value) +{ + PUTBYTES(2); + short Converted = htons(a_Value); + return WriteBuf(&Converted, 2); +} + + + + + +bool cByteBuffer::WriteBEInt(int a_Value) +{ + PUTBYTES(4); + int Converted = HostToNetwork4(&a_Value); + return WriteBuf(&Converted, 4); +} + + + + + +bool cByteBuffer::WriteBEInt64(Int64 a_Value) +{ + PUTBYTES(8); + Int64 Converted = HostToNetwork8(&a_Value); + return WriteBuf(&Converted, 8); +} + + + + + +bool cByteBuffer::WriteBEFloat(float a_Value) +{ + PUTBYTES(4); + int Converted = HostToNetwork4(&a_Value); + return WriteBuf(&Converted, 4); +} + + + + + +bool cByteBuffer::WriteBEDouble(double a_Value) +{ + PUTBYTES(8); + Int64 Converted = HostToNetwork8(&a_Value); + return WriteBuf(&Converted, 8); +} + + + + + + +bool cByteBuffer::WriteBool(bool a_Value) +{ + return WriteChar(a_Value ? 1 : 0); +} + + + + + +bool cByteBuffer::WriteBEUTF16String16(const AString & a_Value) +{ + PUTBYTES(2); + AString UTF16BE; + UTF8ToRawBEUTF16(a_Value.data(), a_Value.size(), UTF16BE); + WriteBEShort((short)(UTF16BE.size() / 2)); + PUTBYTES(UTF16BE.size()); + WriteBuf(UTF16BE.data(), UTF16BE.size()); + return true; +} + + + + + bool cByteBuffer::ReadBuf(void * a_Buffer, int a_Count) { NEEDBYTES(a_Count); @@ -252,6 +362,30 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, int a_Count) +bool cByteBuffer::WriteBuf(const void * a_Buffer, int a_Count) +{ + PUTBYTES(a_Count); + char * Src = (char *)a_Buffer; // So that we can do byte math + int BytesToEndOfBuffer = m_BufferSize - m_WritePos; + if (BytesToEndOfBuffer < a_Count) + { + // Reading across the ringbuffer end, read the first part and adjust parameters: + memcpy(m_Buffer + m_WritePos, Src, BytesToEndOfBuffer); + Src += BytesToEndOfBuffer; + a_Count -= BytesToEndOfBuffer; + m_WritePos = 0; + } + + // Read the rest of the bytes in a single read (guaranteed to fit): + memcpy(m_Buffer + m_WritePos, Src, a_Count); + m_WritePos += a_Count; + return true; +} + + + + + bool cByteBuffer::ReadString(AString & a_String, int a_Count) { NEEDBYTES(a_Count); diff --git a/source/ByteBuffer.h b/source/ByteBuffer.h index 68dc48cd9..c0ffed43c 100644 --- a/source/ByteBuffer.h +++ b/source/ByteBuffer.h @@ -45,6 +45,9 @@ public: /// Returns true if the specified amount of bytes are available for reading bool CanReadBytes(int a_Count) const; + /// Returns true if the specified amount of bytes are available for writing + bool CanWriteBytes(int a_Count) const; + // Read the specified datatype and advance the read pointer; return true if successfully read: bool ReadChar (char & a_Value); bool ReadByte (unsigned char & a_Value); @@ -56,13 +59,27 @@ public: bool ReadBool (bool & a_Value); bool ReadBEUTF16String16(AString & a_Value); - /// Reads a_Count bytes into a_Buffer; return true if successful + // Write the specified datatype; return true if successfully written + bool WriteChar (char a_Value); + bool WriteByte (unsigned char a_Value); + bool WriteBEShort (short a_Value); + bool WriteBEInt (int a_Value); + bool WriteBEInt64 (Int64 a_Value); + bool WriteBEFloat (float a_Value); + bool WriteBEDouble (double a_Value); + bool WriteBool (bool a_Value); + bool WriteBEUTF16String16(const AString & a_Value); + + /// Reads a_Count bytes into a_Buffer; returns true if successful bool ReadBuf(void * a_Buffer, int a_Count); - /// Reads a_Count bytes into a_String; return true if successful + /// Writes a_Count bytes into a_Buffer; returns true if successful + bool WriteBuf(const void * a_Buffer, int a_Count); + + /// Reads a_Count bytes into a_String; returns true if successful bool ReadString(AString & a_String, int a_Count); - /// Reads 2 * a_NumChars bytes and interprets it as a UTF16 string, converting it into UTF8 string a_String + /// Reads 2 * a_NumChars bytes and interprets it as a UTF16-BE string, converting it into UTF8 string a_String bool ReadUTF16String(AString & a_String, int a_NumChars); /// Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer -- cgit v1.2.3