Cuberite
A lightweight, fast and extensible game server for Minecraft
ByteBuffer.cpp
Go to the documentation of this file.
1 
2 // ByteBuffer.cpp
3 
4 // Implements the cByteBuffer class representing a ringbuffer of bytes
5 
6 #include "Globals.h"
7 
8 #include "ByteBuffer.h"
9 #include "Endianness.h"
10 #include "UUID.h"
11 #include "OSSupport/IsThread.h"
12 
13 
14 
15 
16 
20 // #define DEBUG_SINGLE_THREAD_ACCESS
21 
22 
23 
24 
25 
26 // If a string sent over the protocol is larger than this, a warning is emitted to the console
27 #define MAX_STRING_SIZE (512 KiB)
28 
29 #define NEEDBYTES(Num) if (!CanReadBytes(Num)) return false // Check if at least Num bytes can be read from the buffer, return false if not
30 #define PUTBYTES(Num) if (!CanWriteBytes(Num)) return false // Check if at least Num bytes can be written to the buffer, return false if not
31 
32 
33 
34 
35 
36 #ifdef DEBUG_SINGLE_THREAD_ACCESS
37 
41  class cSingleThreadAccessChecker
42  {
43  public:
44  cSingleThreadAccessChecker(std::thread::id * a_ThreadID) :
45  m_ThreadID(a_ThreadID)
46  {
47  ASSERT(
48  (*a_ThreadID == std::this_thread::get_id()) || // Either the object is used by current thread...
49  (*a_ThreadID == m_EmptyThreadID) // ... or by no thread at all
50  );
51 
52  // Mark as being used by this thread:
53  *m_ThreadID = std::this_thread::get_id();
54  }
55 
56  ~cSingleThreadAccessChecker()
57  {
58  // Mark as not being used by any thread:
59  *m_ThreadID = std::thread::id();
60  }
61 
62  protected:
64  std::thread::id * m_ThreadID;
65 
67  static std::thread::id m_EmptyThreadID;
68  };
69 
70  std::thread::id cSingleThreadAccessChecker::m_EmptyThreadID;
71 
72  #define CHECK_THREAD cSingleThreadAccessChecker Checker(&m_ThreadID);
73 
74 #else
75  #define CHECK_THREAD
76 #endif
77 
78 
79 
80 
81 
83 // cByteBuffer:
84 
85 cByteBuffer::cByteBuffer(size_t a_BufferSize) :
86  m_Buffer(new char[a_BufferSize + 1]),
87  m_BufferSize(a_BufferSize + 1),
88  m_DataStart(0),
89  m_WritePos(0),
90  m_ReadPos(0)
91 {
92  // Allocating one byte more than the buffer size requested, so that we can distinguish between
93  // completely-full and completely-empty states
94 }
95 
96 
97 
98 
99 
101 {
102  CheckValid();
103  delete[] m_Buffer;
104  m_Buffer = nullptr;
105 }
106 
107 
108 
109 
110 
111 bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count)
112 {
114  CheckValid();
115 
116  // Store the current free space for a check after writing:
117  size_t CurFreeSpace = GetFreeSpace();
118  #ifdef _DEBUG
119  size_t CurReadableSpace = GetReadableSpace();
120  #endif
121  size_t WrittenBytes = 0;
122 
123  if (CurFreeSpace < a_Count)
124  {
125  return false;
126  }
128  size_t TillEnd = m_BufferSize - m_WritePos;
129  const char * Bytes = static_cast<const char *>(a_Bytes);
130  if (TillEnd <= a_Count)
131  {
132  // Need to wrap around the ringbuffer end
133  if (TillEnd > 0)
134  {
135  memcpy(m_Buffer + m_WritePos, Bytes, TillEnd);
136  Bytes += TillEnd;
137  a_Count -= TillEnd;
138  WrittenBytes = TillEnd;
139  }
140  m_WritePos = 0;
141  }
142 
143  // We're guaranteed that we'll fit in a single write op
144  if (a_Count > 0)
145  {
146  memcpy(m_Buffer + m_WritePos, Bytes, a_Count);
147  m_WritePos += a_Count;
148  WrittenBytes += a_Count;
149  }
150 
151  ASSERT(GetFreeSpace() == CurFreeSpace - WrittenBytes);
152  ASSERT(GetReadableSpace() == CurReadableSpace + WrittenBytes);
153  return true;
154 }
155 
156 
157 
158 
159 
160 size_t cByteBuffer::GetFreeSpace(void) const
161 {
163  CheckValid();
164  if (m_WritePos >= m_DataStart)
165  {
166  // Wrap around the buffer end:
169  return m_BufferSize - m_WritePos + m_DataStart - 1;
170  }
171  // Single free space partition:
174  return m_DataStart - m_WritePos - 1;
175 }
176 
177 
178 
179 
180 
181 size_t cByteBuffer::GetUsedSpace(void) const
182 {
184  CheckValid();
186  ASSERT((m_BufferSize - GetFreeSpace()) >= 1);
187  return m_BufferSize - GetFreeSpace() - 1;
188 }
189 
190 
191 
192 
193 
195 {
197  CheckValid();
198  if (m_ReadPos > m_WritePos)
199  {
200  // Wrap around the buffer end:
202  return m_BufferSize - m_ReadPos + m_WritePos;
203  }
204  // Single readable space partition:
206  return m_WritePos - m_ReadPos;
207 }
208 
209 
210 
211 
212 
213 bool cByteBuffer::CanReadBytes(size_t a_Count) const
214 {
216  CheckValid();
217  return (a_Count <= GetReadableSpace());
218 }
219 
220 
221 
222 
223 
224 bool cByteBuffer::CanWriteBytes(size_t a_Count) const
225 {
227  CheckValid();
228  return (a_Count <= GetFreeSpace());
229 }
230 
231 
232 
233 
234 
236 {
238  CheckValid();
239  NEEDBYTES(1);
240  ReadBuf(&a_Value, 1);
241  return true;
242 }
243 
244 
245 
246 
247 
249 {
251  CheckValid();
252  NEEDBYTES(1);
253  ReadBuf(&a_Value, 1);
254  return true;
255 }
256 
257 
258 
259 
260 
262 {
264  CheckValid();
265  NEEDBYTES(2);
266  UInt16 val;
267  ReadBuf(&val, 2);
268  val = ntohs(val);
269  memcpy(&a_Value, &val, 2);
270  return true;
271 }
272 
273 
274 
275 
276 
278 {
280  CheckValid();
281  NEEDBYTES(2);
282  ReadBuf(&a_Value, 2);
283  a_Value = ntohs(a_Value);
284  return true;
285 }
286 
287 
288 
289 
290 
292 {
294  CheckValid();
295  NEEDBYTES(4);
296  UInt32 val;
297  ReadBuf(&val, 4);
298  val = ntohl(val);
299  memcpy(&a_Value, &val, 4);
300  return true;
301 }
302 
303 
304 
305 
306 
308 {
310  CheckValid();
311  NEEDBYTES(4);
312  ReadBuf(&a_Value, 4);
313  a_Value = ntohl(a_Value);
314  return true;
315 }
316 
317 
318 
319 
320 
322 {
324  CheckValid();
325  NEEDBYTES(8);
326  ReadBuf(&a_Value, 8);
327  a_Value = NetworkToHostLong8(&a_Value);
328  return true;
329 }
330 
331 
332 
333 
334 
336 {
338  CheckValid();
339  NEEDBYTES(8);
340  ReadBuf(&a_Value, 8);
341  a_Value = NetworkToHostULong8(&a_Value);
342  return true;
343 }
344 
345 
346 
347 
348 
349 bool cByteBuffer::ReadBEFloat(float & a_Value)
350 {
352  CheckValid();
353  NEEDBYTES(4);
354  ReadBuf(&a_Value, 4);
355  a_Value = NetworkToHostFloat4(&a_Value);
356  return true;
357 }
358 
359 
360 
361 
362 
363 bool cByteBuffer::ReadBEDouble(double & a_Value)
364 {
366  CheckValid();
367  NEEDBYTES(8);
368  ReadBuf(&a_Value, 8);
369  a_Value = NetworkToHostDouble8(&a_Value);
370  return true;
371 }
372 
373 
374 
375 
376 
377 bool cByteBuffer::ReadBool(bool & a_Value)
378 {
380  CheckValid();
381  NEEDBYTES(1);
382  UInt8 Value = 0;
383  ReadBuf(&Value, 1);
384  a_Value = (Value != 0);
385  return true;
386 }
387 
388 
389 
390 
391 
393 {
395  CheckValid();
396  UInt32 Value = 0;
397  int Shift = 0;
398  unsigned char b = 0;
399  do
400  {
401  NEEDBYTES(1);
402  ReadBuf(&b, 1);
403  Value = Value | ((static_cast<UInt32>(b & 0x7f)) << Shift);
404  Shift += 7;
405  } while ((b & 0x80) != 0);
406  a_Value = Value;
407  return true;
408 }
409 
410 
411 
412 
413 
415 {
417  CheckValid();
418  UInt64 Value = 0;
419  int Shift = 0;
420  unsigned char b = 0;
421  do
422  {
423  NEEDBYTES(1);
424  ReadBuf(&b, 1);
425  Value = Value | ((static_cast<UInt64>(b & 0x7f)) << Shift);
426  Shift += 7;
427  } while ((b & 0x80) != 0);
428  a_Value = Value;
429  return true;
430 }
431 
432 
433 
434 
435 
437 {
439  CheckValid();
440  UInt32 Size = 0;
441  if (!ReadVarInt(Size))
442  {
443  return false;
444  }
445  if (Size > MAX_STRING_SIZE)
446  {
447  LOGWARNING("%s: String too large: %u (%u KiB)", __FUNCTION__, Size, Size / 1024);
448  }
449  return ReadString(a_Value, static_cast<size_t>(Size));
450 }
451 
452 
453 
454 
455 
456 bool cByteBuffer::ReadLEInt(int & a_Value)
457 {
459  CheckValid();
460  NEEDBYTES(4);
461  ReadBuf(&a_Value, 4);
462 
463  #ifdef IS_BIG_ENDIAN
464  // Convert:
465  a_Value = ((a_Value >> 24) & 0xff) | ((a_Value >> 16) & 0xff00) | ((a_Value >> 8) & 0xff0000) | (a_Value & 0xff000000);
466  #endif
467 
468  return true;
469 }
470 
471 
472 
473 
474 
475 bool cByteBuffer::ReadPosition64(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
476 {
478  Int64 Value;
479  if (!ReadBEInt64(Value))
480  {
481  return false;
482  }
483 
484  // Convert the 64 received bits into 3 coords:
485  UInt32 BlockXRaw = (Value >> 38) & 0x03ffffff; // Top 26 bits
486  UInt32 BlockYRaw = (Value >> 26) & 0x0fff; // Middle 12 bits
487  UInt32 BlockZRaw = (Value & 0x03ffffff); // Bottom 26 bits
488 
489  // If the highest bit in the number's range is set, convert the number into negative:
490  a_BlockX = ((BlockXRaw & 0x02000000) == 0) ? static_cast<int>(BlockXRaw) : -(0x04000000 - static_cast<int>(BlockXRaw));
491  a_BlockY = ((BlockYRaw & 0x0800) == 0) ? static_cast<int>(BlockYRaw) : -(0x0800 - static_cast<int>(BlockYRaw));
492  a_BlockZ = ((BlockZRaw & 0x02000000) == 0) ? static_cast<int>(BlockZRaw) : -(0x04000000 - static_cast<int>(BlockZRaw));
493  return true;
494 }
495 
496 
497 
498 
499 
501 {
503 
504  std::array<Byte, 16> UUIDBuf;
505  if (!ReadBuf(UUIDBuf.data(), UUIDBuf.size()))
506  {
507  return false;
508  }
509 
510  a_Value.FromRaw(UUIDBuf);
511  return true;
512 }
513 
514 
515 
516 
517 
519 {
521  CheckValid();
522  PUTBYTES(1);
523  return WriteBuf(&a_Value, 1);
524 }
525 
526 
527 
528 
529 
531 {
533  CheckValid();
534  PUTBYTES(1);
535  return WriteBuf(&a_Value, 1);
536 }
537 
538 
539 
540 
541 
543 {
545  CheckValid();
546  PUTBYTES(2);
547  UInt16 val;
548  memcpy(&val, &a_Value, 2);
549  val = htons(val);
550  return WriteBuf(&val, 2);
551 }
552 
553 
554 
555 
556 
558 {
560  CheckValid();
561  PUTBYTES(2);
562  a_Value = htons(a_Value);
563  return WriteBuf(&a_Value, 2);
564 }
565 
566 
567 
568 
569 
571 {
573  CheckValid();
574  PUTBYTES(4);
575  UInt32 Converted = HostToNetwork4(&a_Value);
576  return WriteBuf(&Converted, 4);
577 }
578 
579 
580 
581 
582 
584 {
586  CheckValid();
587  PUTBYTES(4);
588  UInt32 Converted = HostToNetwork4(&a_Value);
589  return WriteBuf(&Converted, 4);
590 }
591 
592 
593 
594 
595 
597 {
599  CheckValid();
600  PUTBYTES(8);
601  UInt64 Converted = HostToNetwork8(&a_Value);
602  return WriteBuf(&Converted, 8);
603 }
604 
605 
606 
607 
608 
610 {
612  CheckValid();
613  PUTBYTES(8);
614  UInt64 Converted = HostToNetwork8(&a_Value);
615  return WriteBuf(&Converted, 8);
616 }
617 
618 
619 
620 
621 
622 bool cByteBuffer::WriteBEFloat(float a_Value)
623 {
625  CheckValid();
626  PUTBYTES(4);
627  UInt32 Converted = HostToNetwork4(&a_Value);
628  return WriteBuf(&Converted, 4);
629 }
630 
631 
632 
633 
634 
635 bool cByteBuffer::WriteBEDouble(double a_Value)
636 {
638  CheckValid();
639  PUTBYTES(8);
640  UInt64 Converted = HostToNetwork8(&a_Value);
641  return WriteBuf(&Converted, 8);
642 }
643 
644 
645 
646 
647 
648 bool cByteBuffer::WriteBool(bool a_Value)
649 {
651  CheckValid();
652  UInt8 val = a_Value ? 1 : 0;
653  return Write(&val, 1);
654 }
655 
656 
657 
658 
659 
661 {
663  CheckValid();
664 
665  // A 32-bit integer can be encoded by at most 5 bytes:
666  unsigned char b[5];
667  size_t idx = 0;
668  do
669  {
670  b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00);
671  a_Value = a_Value >> 7;
672  idx++;
673  } while (a_Value > 0);
674 
675  return WriteBuf(b, idx);
676 }
677 
678 
679 
680 
681 
683 {
685  CheckValid();
686 
687  // A 64-bit integer can be encoded by at most 10 bytes:
688  unsigned char b[10];
689  size_t idx = 0;
690  do
691  {
692  b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00);
693  a_Value = a_Value >> 7;
694  idx++;
695  } while (a_Value > 0);
696 
697  return WriteBuf(b, idx);
698 }
699 
700 
701 
702 
703 
705 {
707  CheckValid();
708  PUTBYTES(a_Value.size() + 1); // This is a lower-bound on the bytes that will be actually written. Fail early.
709  bool res = WriteVarInt32(static_cast<UInt32>(a_Value.size()));
710  if (!res)
711  {
712  return false;
713  }
714  return WriteBuf(a_Value.data(), a_Value.size());
715 }
716 
717 
718 
719 
720 
721 bool cByteBuffer::WritePosition64(Int32 a_BlockX, Int32 a_BlockY, Int32 a_BlockZ)
722 {
724  CheckValid();
725  return WriteBEInt64(
726  (static_cast<Int64>(a_BlockX & 0x3FFFFFF) << 38) |
727  (static_cast<Int64>(a_BlockY & 0xFFF) << 26) |
728  (static_cast<Int64>(a_BlockZ & 0x3FFFFFF))
729  );
730 }
731 
732 
733 
734 
735 
736 bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count)
737 {
739  CheckValid();
740  NEEDBYTES(a_Count);
741  char * Dst = static_cast<char *>(a_Buffer); // So that we can do byte math
743  size_t BytesToEndOfBuffer = m_BufferSize - m_ReadPos;
744  if (BytesToEndOfBuffer <= a_Count)
745  {
746  // Reading across the ringbuffer end, read the first part and adjust parameters:
747  if (BytesToEndOfBuffer > 0)
748  {
749  memcpy(Dst, m_Buffer + m_ReadPos, BytesToEndOfBuffer);
750  Dst += BytesToEndOfBuffer;
751  a_Count -= BytesToEndOfBuffer;
752  }
753  m_ReadPos = 0;
754  }
755 
756  // Read the rest of the bytes in a single read (guaranteed to fit):
757  if (a_Count > 0)
758  {
759  memcpy(Dst, m_Buffer + m_ReadPos, a_Count);
760  m_ReadPos += a_Count;
761  }
762  return true;
763 }
764 
765 
766 
767 
768 
769 bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count)
770 {
772  CheckValid();
773  PUTBYTES(a_Count);
774  const char * Src = static_cast<const char *>(a_Buffer); // So that we can do byte math
776  size_t BytesToEndOfBuffer = m_BufferSize - m_WritePos;
777  if (BytesToEndOfBuffer <= a_Count)
778  {
779  // Reading across the ringbuffer end, read the first part and adjust parameters:
780  memcpy(m_Buffer + m_WritePos, Src, BytesToEndOfBuffer);
781  Src += BytesToEndOfBuffer;
782  a_Count -= BytesToEndOfBuffer;
783  m_WritePos = 0;
784  }
785 
786  // Read the rest of the bytes in a single read (guaranteed to fit):
787  if (a_Count > 0)
788  {
789  memcpy(m_Buffer + m_WritePos, Src, a_Count);
790  m_WritePos += a_Count;
791  }
792  return true;
793 }
794 
795 
796 
797 
798 
799 bool cByteBuffer::ReadString(AString & a_String, size_t a_Count)
800 {
802  CheckValid();
803  NEEDBYTES(a_Count);
804  a_String.clear();
805  a_String.reserve(a_Count);
807  size_t BytesToEndOfBuffer = m_BufferSize - m_ReadPos;
808  if (BytesToEndOfBuffer <= a_Count)
809  {
810  // Reading across the ringbuffer end, read the first part and adjust parameters:
811  if (BytesToEndOfBuffer > 0)
812  {
813  a_String.assign(m_Buffer + m_ReadPos, BytesToEndOfBuffer);
814  ASSERT(a_Count >= BytesToEndOfBuffer);
815  a_Count -= BytesToEndOfBuffer;
816  }
817  m_ReadPos = 0;
818  }
819 
820  // Read the rest of the bytes in a single read (guaranteed to fit):
821  if (a_Count > 0)
822  {
823  a_String.append(m_Buffer + m_ReadPos, a_Count);
824  m_ReadPos += a_Count;
825  }
826  return true;
827 }
828 
829 
830 
831 
832 
833 bool cByteBuffer::SkipRead(size_t a_Count)
834 {
836  CheckValid();
837  if (!CanReadBytes(a_Count))
838  {
839  return false;
840  }
841  AdvanceReadPos(a_Count);
842  return true;
843 }
844 
845 
846 
847 
848 
850 {
852  CheckValid();
853  ReadString(a_Data, GetReadableSpace());
854 }
855 
856 
857 
858 
859 
860 bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes)
861 {
863  if (!a_Dst.CanWriteBytes(a_NumBytes) || !CanReadBytes(a_NumBytes))
864  {
865  // There's not enough source bytes or space in the dest BB
866  return false;
867  }
868  char buf[1024];
869  // > 0 without generating warnings about unsigned comparisons where size_t is unsigned
870  while (a_NumBytes != 0)
871  {
872  size_t num = (a_NumBytes > sizeof(buf)) ? sizeof(buf) : a_NumBytes;
873  VERIFY(ReadBuf(buf, num));
874  VERIFY(a_Dst.Write(buf, num));
875  ASSERT(a_NumBytes >= num);
876  a_NumBytes -= num;
877  }
878  return true;
879 }
880 
881 
882 
883 
884 
886 {
888  CheckValid();
890 }
891 
892 
893 
894 
895 
897 {
899  CheckValid();
901 }
902 
903 
904 
905 
906 
908 {
909  // Return the data between m_DataStart and m_ReadPos (the data that has been read but not committed)
910  // Used by ProtoProxy to repeat communication twice, once for parsing and the other time for the remote party
912  CheckValid();
913  size_t DataStart = m_DataStart;
914  if (m_ReadPos < m_DataStart)
915  {
916  // Across the ringbuffer end, read the first part and adjust next part's start:
918  a_Out.append(m_Buffer + m_DataStart, m_BufferSize - m_DataStart);
919  DataStart = 0;
920  }
921  ASSERT(m_ReadPos >= DataStart);
922  a_Out.append(m_Buffer + DataStart, m_ReadPos - DataStart);
923 }
924 
925 
926 
927 
928 
929 void cByteBuffer::AdvanceReadPos(size_t a_Count)
930 {
932  CheckValid();
933  m_ReadPos += a_Count;
934  if (m_ReadPos >= m_BufferSize)
935  {
937  }
938 }
939 
940 
941 
942 
943 
944 void cByteBuffer::CheckValid(void) const
945 {
948 }
949 
950 
951 
952 
953 
955 {
956  size_t Count = 0;
957 
958  do
959  {
960  // If the value cannot be expressed in 7 bits, it needs to take up another byte
961  Count++;
962  a_Value >>= 7;
963  } while (a_Value != 0);
964 
965  return Count;
966 }
967 
968 
969 
970 
971 
Int64 NetworkToHostLong8(const void *a_Value)
Definition: Endianness.h:50
UInt64 HostToNetwork8(const void *a_Value)
Definition: Endianness.h:12
bool WriteVarInt32(UInt32 a_Value)
Definition: ByteBuffer.cpp:660
void ReadAll(AString &a_Data)
Reads all available data into a_Data.
Definition: ByteBuffer.cpp:849
void AdvanceReadPos(size_t a_Count)
Advances the m_ReadPos by a_Count bytes.
Definition: ByteBuffer.cpp:929
size_t GetReadableSpace(void) const
Returns the number of bytes that are currently available for reading (may be less than UsedSpace due ...
Definition: ByteBuffer.cpp:194
bool ReadBEDouble(double &a_Value)
Definition: ByteBuffer.cpp:363
cByteBuffer(size_t a_BufferSize)
Definition: ByteBuffer.cpp:85
bool WriteBEDouble(double a_Value)
Definition: ByteBuffer.cpp:635
#define VERIFY(x)
Definition: Globals.h:339
signed char Int8
Definition: Globals.h:110
signed short Int16
Definition: Globals.h:109
bool ReadVarUTF8String(AString &a_Value)
Definition: ByteBuffer.cpp:436
size_t m_WritePos
Definition: ByteBuffer.h:143
float NetworkToHostFloat4(const void *a_Value)
Definition: Endianness.h:74
bool WriteVarUTF8String(const AString &a_Value)
Definition: ByteBuffer.cpp:704
bool ReadString(AString &a_String, size_t a_Count)
Reads a_Count bytes into a_String; returns true if successful.
Definition: ByteBuffer.cpp:799
bool ReadUUID(cUUID &a_Value)
Definition: ByteBuffer.cpp:500
bool ReadBEInt8(Int8 &a_Value)
Definition: ByteBuffer.cpp:235
UInt64 NetworkToHostULong8(const void *a_Value)
Definition: Endianness.h:62
double NetworkToHostDouble8(const void *a_Value)
Definition: Endianness.h:36
bool WriteBEInt16(Int16 a_Value)
Definition: ByteBuffer.cpp:542
bool WritePosition64(Int32 a_BlockX, Int32 a_BlockY, Int32 a_BlockZ)
Definition: ByteBuffer.cpp:721
bool ReadBEUInt16(UInt16 &a_Value)
Definition: ByteBuffer.cpp:277
bool ReadBEUInt64(UInt64 &a_Value)
Definition: ByteBuffer.cpp:335
bool ReadBEUInt8(UInt8 &a_Value)
Definition: ByteBuffer.cpp:248
char * m_Buffer
Definition: ByteBuffer.h:139
bool Write(const void *a_Bytes, size_t a_Count)
Writes the bytes specified to the ringbuffer.
Definition: ByteBuffer.cpp:111
static size_t GetVarIntSize(UInt32 a_Value)
Gets the number of bytes that are needed to represent the given VarInt.
Definition: ByteBuffer.cpp:954
bool ReadLEInt(int &a_Value)
Definition: ByteBuffer.cpp:456
bool ReadBEUInt32(UInt32 &a_Value)
Definition: ByteBuffer.cpp:307
Definition: UUID.h:10
bool WriteVarInt64(UInt64 a_Value)
Definition: ByteBuffer.cpp:682
void CommitRead(void)
Removes the bytes that have been read from the ringbuffer.
Definition: ByteBuffer.cpp:885
bool WriteBEUInt64(UInt64 a_Value)
Definition: ByteBuffer.cpp:609
size_t m_ReadPos
Definition: ByteBuffer.h:144
bool ReadBool(bool &a_Value)
Definition: ByteBuffer.cpp:377
bool ReadToByteBuffer(cByteBuffer &a_Dst, size_t a_NumBytes)
Reads the specified number of bytes and writes it into the destinatio bytebuffer. ...
Definition: ByteBuffer.cpp:860
unsigned long long UInt64
Definition: Globals.h:112
bool CanReadBytes(size_t a_Count) const
Returns true if the specified amount of bytes are available for reading.
Definition: ByteBuffer.cpp:213
size_t m_DataStart
Definition: ByteBuffer.h:142
#define ASSERT(x)
Definition: Globals.h:335
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
Definition: Logger.cpp:174
void ResetRead(void)
Restarts next reading operation at the start of the ringbuffer.
Definition: ByteBuffer.cpp:896
An object that can store incoming bytes and lets its clients read the bytes sequentially The bytes ar...
Definition: ByteBuffer.h:29
bool ReadVarInt32(UInt32 &a_Value)
Definition: ByteBuffer.cpp:392
bool WriteBEInt64(Int64 a_Value)
Definition: ByteBuffer.cpp:596
#define PUTBYTES(Num)
Definition: ByteBuffer.cpp:30
bool ReadBEInt16(Int16 &a_Value)
Definition: ByteBuffer.cpp:261
bool SkipRead(size_t a_Count)
Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer.
Definition: ByteBuffer.cpp:833
void ReadAgain(AString &a_Out)
Re-reads the data that has been read since the last commit to the current readpos.
Definition: ByteBuffer.cpp:907
bool ReadVarInt(T &a_Value)
Reads VarInt, assigns it to anything that can be assigned from an UInt64 (unsigned short...
Definition: ByteBuffer.h:76
bool WriteBEUInt8(UInt8 a_Value)
Definition: ByteBuffer.cpp:530
#define MAX_STRING_SIZE
When defined, each access to a cByteBuffer object is checked whether it&#39;s done in the same thread...
Definition: ByteBuffer.cpp:27
void FromRaw(const std::array< Byte, 16 > &a_Raw)
Assigns from raw memory representation, respecting UUID variant.
Definition: UUID.cpp:238
unsigned short UInt16
Definition: Globals.h:114
unsigned char UInt8
Definition: Globals.h:115
size_t m_BufferSize
Definition: ByteBuffer.h:140
std::string AString
Definition: StringUtils.h:13
size_t GetUsedSpace(void) const
Returns the number of bytes that are currently in the ringbuffer.
Definition: ByteBuffer.cpp:181
bool WriteBEInt8(Int8 a_Value)
Definition: ByteBuffer.cpp:518
#define NEEDBYTES(Num)
Definition: ByteBuffer.cpp:29
bool WriteBEFloat(float a_Value)
Definition: ByteBuffer.cpp:622
bool WriteBEInt32(Int32 a_Value)
Definition: ByteBuffer.cpp:570
size_t GetFreeSpace(void) const
Returns the number of bytes that can be successfully written to the ringbuffer.
Definition: ByteBuffer.cpp:160
bool WriteBuf(const void *a_Buffer, size_t a_Count)
Writes a_Count bytes into a_Buffer; returns true if successful.
Definition: ByteBuffer.cpp:769
signed int Int32
Definition: Globals.h:108
bool ReadBuf(void *a_Buffer, size_t a_Count)
Reads a_Count bytes into a_Buffer; returns true if successful.
Definition: ByteBuffer.cpp:736
unsigned int UInt32
Definition: Globals.h:113
bool ReadBEInt32(Int32 &a_Value)
Definition: ByteBuffer.cpp:291
bool ReadBEInt64(Int64 &a_Value)
Definition: ByteBuffer.cpp:321
bool WriteBEUInt32(UInt32 a_Value)
Definition: ByteBuffer.cpp:583
bool ReadBEFloat(float &a_Value)
Definition: ByteBuffer.cpp:349
void CheckValid(void) const
Checks if the internal state is valid (read and write positions in the correct bounds) using ASSERTs...
Definition: ByteBuffer.cpp:944
bool WriteBool(bool a_Value)
Definition: ByteBuffer.cpp:648
bool ReadPosition64(int &a_BlockX, int &a_BlockY, int &a_BlockZ)
Definition: ByteBuffer.cpp:475
bool ReadVarInt64(UInt64 &a_Value)
Definition: ByteBuffer.cpp:414
UInt32 HostToNetwork4(const void *a_Value)
Definition: Endianness.h:24
bool CanWriteBytes(size_t a_Count) const
Returns true if the specified amount of bytes are available for writing.
Definition: ByteBuffer.cpp:224
signed long long Int64
Definition: Globals.h:107
bool WriteBEUInt16(UInt16 a_Value)
Definition: ByteBuffer.cpp:557
#define CHECK_THREAD
Definition: ByteBuffer.cpp:75