Go to the documentation of this file.00001 #include "DS_ByteQueue.h"
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005
00006
00007 using namespace DataStructures;
00008
00009 ByteQueue::ByteQueue()
00010 {
00011 readOffset=writeOffset=lengthAllocated=0;
00012 data=0;
00013 }
00014 ByteQueue::~ByteQueue()
00015 {
00016 Clear(__FILE__, __LINE__);
00017
00018
00019 }
00020 void ByteQueue::WriteBytes(const char *in, unsigned length, const char *file, unsigned int line)
00021 {
00022 unsigned bytesWritten;
00023 bytesWritten=GetBytesWritten();
00024 if (lengthAllocated==0 || length > lengthAllocated-bytesWritten-1)
00025 {
00026 unsigned oldLengthAllocated=lengthAllocated;
00027
00028 unsigned newAmountToAllocate=length+oldLengthAllocated+1;
00029 if (newAmountToAllocate<256)
00030 newAmountToAllocate=256;
00031 lengthAllocated=lengthAllocated + newAmountToAllocate;
00032 data=(char*)rakRealloc_Ex(data, lengthAllocated, file, line);
00033 if (writeOffset < readOffset)
00034 {
00035 if (writeOffset <= newAmountToAllocate)
00036 {
00037 memcpy(data + oldLengthAllocated, data, writeOffset);
00038 writeOffset=readOffset+bytesWritten;
00039 }
00040 else
00041 {
00042 memcpy(data + oldLengthAllocated, data, newAmountToAllocate);
00043 memmove(data, data+newAmountToAllocate, writeOffset-newAmountToAllocate);
00044 writeOffset-=newAmountToAllocate;
00045 }
00046 }
00047 }
00048
00049 if (length <= lengthAllocated-writeOffset)
00050 memcpy(data+writeOffset, in, length);
00051 else
00052 {
00053
00054 memcpy(data+writeOffset, in, lengthAllocated-writeOffset);
00055 memcpy(data, in+(lengthAllocated-writeOffset), length-(lengthAllocated-writeOffset));
00056 }
00057 writeOffset=(writeOffset+length) % lengthAllocated;
00058 }
00059 bool ByteQueue::ReadBytes(char *out, unsigned maxLengthToRead, bool peek)
00060 {
00061 unsigned bytesWritten = GetBytesWritten();
00062 unsigned bytesToRead = bytesWritten < maxLengthToRead ? bytesWritten : maxLengthToRead;
00063 if (bytesToRead==0)
00064 return false;
00065 if (writeOffset>=readOffset)
00066 {
00067 memcpy(out, data+readOffset, bytesToRead);
00068 }
00069 else
00070 {
00071 unsigned availableUntilWrap = lengthAllocated-readOffset;
00072 if (bytesToRead <= availableUntilWrap)
00073 {
00074 memcpy(out, data+readOffset, bytesToRead);
00075 }
00076 else
00077 {
00078 memcpy(out, data+readOffset, availableUntilWrap);
00079 memcpy(out+availableUntilWrap, data, bytesToRead-availableUntilWrap);
00080 }
00081 }
00082
00083 if (peek==false)
00084 IncrementReadOffset(bytesToRead);
00085
00086 return true;
00087 }
00088 char* ByteQueue::PeekContiguousBytes(unsigned int *outLength) const
00089 {
00090 if (writeOffset>=readOffset)
00091 *outLength=writeOffset-readOffset;
00092 else
00093 *outLength=lengthAllocated-readOffset;
00094 return data+readOffset;
00095 }
00096 void ByteQueue::Clear(const char *file, unsigned int line)
00097 {
00098 if (lengthAllocated)
00099 rakFree_Ex(data, file, line );
00100 readOffset=writeOffset=lengthAllocated=0;
00101 data=0;
00102 }
00103 unsigned ByteQueue::GetBytesWritten(void) const
00104 {
00105 if (writeOffset>=readOffset)
00106 return writeOffset-readOffset;
00107 else
00108 return writeOffset+(lengthAllocated-readOffset);
00109 }
00110 void ByteQueue::IncrementReadOffset(unsigned length)
00111 {
00112 readOffset=(readOffset+length) % lengthAllocated;
00113 }
00114 void ByteQueue::DecrementReadOffset(unsigned length)
00115 {
00116 if (length>readOffset)
00117 readOffset=lengthAllocated-(length-readOffset);
00118 else
00119 readOffset-=length;
00120 }
00121 void ByteQueue::Print(void)
00122 {
00123 unsigned i;
00124 for (i=readOffset; i!=writeOffset; i++)
00125 RAKNET_DEBUG_PRINTF("%i ", data[i]);
00126 RAKNET_DEBUG_PRINTF("\n");
00127 }