| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "DS_ByteQueue.h"
- #include <string.h> // Memmove
- #include <stdlib.h> // realloc
- #include <stdio.h>
- using namespace DataStructures;
- ByteQueue::ByteQueue()
- {
- readOffset=writeOffset=lengthAllocated=0;
- data=0;
- }
- ByteQueue::~ByteQueue()
- {
- Clear(_FILE_AND_LINE_);
-
- }
- void ByteQueue::WriteBytes(const char *in, unsigned length, const char *file, unsigned int line)
- {
- unsigned bytesWritten;
- bytesWritten=GetBytesWritten();
- if (lengthAllocated==0 || length > lengthAllocated-bytesWritten-1)
- {
- unsigned oldLengthAllocated=lengthAllocated;
- // Always need to waste 1 byte for the math to work, else writeoffset==readoffset
- unsigned newAmountToAllocate=length+oldLengthAllocated+1;
- if (newAmountToAllocate<256)
- newAmountToAllocate=256;
- lengthAllocated=lengthAllocated + newAmountToAllocate;
- data=(char*)rakRealloc_Ex(data, lengthAllocated, file, line);
- if (writeOffset < readOffset)
- {
- if (writeOffset <= newAmountToAllocate)
- {
- memcpy(data + oldLengthAllocated, data, writeOffset);
- writeOffset=readOffset+bytesWritten;
- }
- else
- {
- memcpy(data + oldLengthAllocated, data, newAmountToAllocate);
- memmove(data, data+newAmountToAllocate, writeOffset-newAmountToAllocate);
- writeOffset-=newAmountToAllocate;
- }
- }
- }
- if (length <= lengthAllocated-writeOffset)
- memcpy(data+writeOffset, in, length);
- else
- {
- // Wrap
- memcpy(data+writeOffset, in, lengthAllocated-writeOffset);
- memcpy(data, in+(lengthAllocated-writeOffset), length-(lengthAllocated-writeOffset));
- }
- writeOffset=(writeOffset+length) % lengthAllocated;
- }
- bool ByteQueue::ReadBytes(char *out, unsigned maxLengthToRead, bool peek)
- {
- unsigned bytesWritten = GetBytesWritten();
- unsigned bytesToRead = bytesWritten < maxLengthToRead ? bytesWritten : maxLengthToRead;
- if (bytesToRead==0)
- return false;
- if (writeOffset>=readOffset)
- {
- memcpy(out, data+readOffset, bytesToRead);
- }
- else
- {
- unsigned availableUntilWrap = lengthAllocated-readOffset;
- if (bytesToRead <= availableUntilWrap)
- {
- memcpy(out, data+readOffset, bytesToRead);
- }
- else
- {
- memcpy(out, data+readOffset, availableUntilWrap);
- memcpy(out+availableUntilWrap, data, bytesToRead-availableUntilWrap);
- }
- }
- if (peek==false)
- IncrementReadOffset(bytesToRead);
-
- return true;
- }
- char* ByteQueue::PeekContiguousBytes(unsigned int *outLength) const
- {
- if (writeOffset>=readOffset)
- *outLength=writeOffset-readOffset;
- else
- *outLength=lengthAllocated-readOffset;
- return data+readOffset;
- }
- void ByteQueue::Clear(const char *file, unsigned int line)
- {
- if (lengthAllocated)
- rakFree_Ex(data, file, line );
- readOffset=writeOffset=lengthAllocated=0;
- data=0;
- }
- unsigned ByteQueue::GetBytesWritten(void) const
- {
- if (writeOffset>=readOffset)
- return writeOffset-readOffset;
- else
- return writeOffset+(lengthAllocated-readOffset);
- }
- void ByteQueue::IncrementReadOffset(unsigned length)
- {
- readOffset=(readOffset+length) % lengthAllocated;
- }
- void ByteQueue::DecrementReadOffset(unsigned length)
- {
- if (length>readOffset)
- readOffset=lengthAllocated-(length-readOffset);
- else
- readOffset-=length;
- }
- void ByteQueue::Print(void)
- {
- unsigned i;
- for (i=readOffset; i!=writeOffset; i++)
- RAKNET_DEBUG_PRINTF("%i ", data[i]);
- RAKNET_DEBUG_PRINTF("\n");
- }
|