SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DS_ByteQueue.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #include "slikenet/DS_ByteQueue.h"
17 #include <string.h> // Memmove
18 #include <stdlib.h> // realloc
19 #include <stdio.h>
20
21
22 using namespace DataStructures;
23
24 ByteQueue::ByteQueue()
25 {
26 readOffset=writeOffset=lengthAllocated=0;
27 data=0;
28 }
29 ByteQueue::~ByteQueue()
30 {
31 Clear(_FILE_AND_LINE_);
32
33
34 }
35 void ByteQueue::WriteBytes(const char *in, unsigned length, const char *file, unsigned int line)
36 {
37 unsigned bytesWritten;
38 bytesWritten=GetBytesWritten();
39 if (lengthAllocated==0 || length > lengthAllocated-bytesWritten-1)
40 {
41 unsigned oldLengthAllocated=lengthAllocated;
42 // Always need to waste 1 byte for the math to work, else writeoffset==readoffset
43 unsigned newAmountToAllocate=length+oldLengthAllocated+1;
44 if (newAmountToAllocate<256)
45 newAmountToAllocate=256;
46 lengthAllocated=lengthAllocated + newAmountToAllocate;
47 data=(char*)rakRealloc_Ex(data, lengthAllocated, file, line);
48 if (writeOffset < readOffset)
49 {
50 if (writeOffset <= newAmountToAllocate)
51 {
52 memcpy(data + oldLengthAllocated, data, writeOffset);
53 writeOffset=readOffset+bytesWritten;
54 }
55 else
56 {
57 memcpy(data + oldLengthAllocated, data, newAmountToAllocate);
58 memmove(data, data+newAmountToAllocate, writeOffset-newAmountToAllocate);
59 writeOffset-=newAmountToAllocate;
60 }
61 }
62 }
63
64 if (length <= lengthAllocated-writeOffset)
65 memcpy(data+writeOffset, in, length);
66 else
67 {
68 // Wrap
69 memcpy(data+writeOffset, in, lengthAllocated-writeOffset);
70 memcpy(data, in+(lengthAllocated-writeOffset), length-(lengthAllocated-writeOffset));
71 }
72 writeOffset=(writeOffset+length) % lengthAllocated;
73 }
74 bool ByteQueue::ReadBytes(char *out, unsigned maxLengthToRead, bool peek)
75 {
76 unsigned bytesWritten = GetBytesWritten();
77 unsigned bytesToRead = bytesWritten < maxLengthToRead ? bytesWritten : maxLengthToRead;
78 if (bytesToRead==0)
79 return false;
80 if (writeOffset>=readOffset)
81 {
82 memcpy(out, data+readOffset, bytesToRead);
83 }
84 else
85 {
86 unsigned availableUntilWrap = lengthAllocated-readOffset;
87 if (bytesToRead <= availableUntilWrap)
88 {
89 memcpy(out, data+readOffset, bytesToRead);
90 }
91 else
92 {
93 memcpy(out, data+readOffset, availableUntilWrap);
94 memcpy(out+availableUntilWrap, data, bytesToRead-availableUntilWrap);
95 }
96 }
97
98 if (peek==false)
99 IncrementReadOffset(bytesToRead);
100
101 return true;
102 }
103 char* ByteQueue::PeekContiguousBytes(unsigned int *outLength) const
104 {
105 if (writeOffset>=readOffset)
106 *outLength=writeOffset-readOffset;
107 else
108 *outLength=lengthAllocated-readOffset;
109 return data+readOffset;
110 }
111 void ByteQueue::Clear(const char *file, unsigned int line)
112 {
113 if (lengthAllocated)
114 rakFree_Ex(data, file, line );
115 readOffset=writeOffset=lengthAllocated=0;
116 data=0;
117 }
118 unsigned ByteQueue::GetBytesWritten(void) const
119 {
120 if (writeOffset>=readOffset)
121 return writeOffset-readOffset;
122 else
123 return writeOffset+(lengthAllocated-readOffset);
124 }
125 void ByteQueue::IncrementReadOffset(unsigned length)
126 {
127 readOffset=(readOffset+length) % lengthAllocated;
128 }
129 void ByteQueue::DecrementReadOffset(unsigned length)
130 {
131 if (length>readOffset)
132 readOffset=lengthAllocated-(length-readOffset);
133 else
134 readOffset-=length;
135 }
136 void ByteQueue::Print(void)
137 {
138 unsigned i;
139 for (i=readOffset; i!=writeOffset; i++)
140 RAKNET_DEBUG_PRINTF("%i ", data[i]);
141 RAKNET_DEBUG_PRINTF("\n");
142 }