• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

DS_ByteQueue.cpp

Go to the documentation of this file.
00001 #include "DS_ByteQueue.h"
00002 #include <string.h> // Memmove
00003 #include <stdlib.h> // realloc
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                 // Always need to waste 1 byte for the math to work, else writeoffset==readoffset
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                 // Wrap
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 }

Generated on Thu Sep 30 2010 01:27:22 for RakNet by  doxygen 1.7.1