Panda3D
Loading...
Searching...
No Matches
datagramBuffer.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file datagramBuffer.cxx
10 * @author rdb
11 * @date 2017-11-07
12 */
13
14#include "datagramBuffer.h"
15
16/**
17 * Writes a sequence of bytes to the beginning of the datagram file. This may
18 * be called any number of times after the file has been opened and before the
19 * first datagram is written. It may not be called once the first datagram is
20 * written.
21 */
23write_header(const std::string &header) {
24 nassertr(!_wrote_first_datagram, false);
25
26 _data.insert(_data.end(), header.begin(), header.end());
27 return true;
28}
29
30/**
31 * Writes the given datagram to the file. Returns true on success, false if
32 * there is an error.
33 */
35put_datagram(const Datagram &data) {
36 _wrote_first_datagram = true;
37
38 // First, write the size of the upcoming datagram.
39 size_t num_bytes = data.get_length();
40 size_t offset = _data.size();
41
42 if (num_bytes == (uint32_t)-1 || num_bytes != (uint32_t)num_bytes) {
43 // Write a large value as a 64-bit size.
44 _data.resize(offset + num_bytes + 4 + sizeof(uint64_t));
45 _data[offset++] = 0xff;
46 _data[offset++] = 0xff;
47 _data[offset++] = 0xff;
48 _data[offset++] = 0xff;
49
50 LittleEndian s(&num_bytes, sizeof(uint64_t));
51 memcpy(&_data[offset], s.get_data(), sizeof(uint64_t));
52 offset += sizeof(uint64_t);
53 } else {
54 // Write a value that fits in 32 bits.
55 _data.resize(offset + num_bytes + sizeof(uint32_t));
56
57 LittleEndian s(&num_bytes, sizeof(uint32_t));
58 memcpy(&_data[offset], s.get_data(), sizeof(uint32_t));
59 offset += sizeof(uint32_t);
60 }
61
62 // Now, write the datagram itself.
63 memcpy(&_data[offset], data.get_data(), data.get_length());
64 return true;
65}
66
67/**
68 * This does absolutely nothing.
69 */
71flush() {
72}
73
74/**
75 * Reads a sequence of bytes from the beginning of the datagram file. This
76 * may be called any number of times after the file has been opened and before
77 * the first datagram is read. It may not be called once the first datagram
78 * has been read.
79 */
81read_header(std::string &header, size_t num_bytes) {
82 nassertr(!_read_first_datagram, false);
83 if (_read_offset + num_bytes > _data.size()) {
84 return false;
85 }
86
87 header = std::string((char *)&_data[_read_offset], num_bytes);
88 _read_offset += num_bytes;
89 return true;
90}
91
92/**
93 * Reads the next datagram from the file. Returns true on success, false if
94 * there is an error or end of file.
95 */
98 _read_first_datagram = true;
99 if (_read_offset + sizeof(uint32_t) > _data.size()) {
100 // Reached the end of the buffer.
101 return false;
102 }
103
104 // First, get the size of the upcoming datagram.
105 uint32_t num_bytes_32;
106 LittleEndian s(&_data[_read_offset], 0, sizeof(uint32_t));
107 s.store_value(&num_bytes_32, sizeof(uint32_t));
108 _read_offset += 4;
109
110 if (num_bytes_32 == 0) {
111 // A special case for a zero-length datagram: no need to try to read any
112 // data.
113 data.clear();
114 return true;
115 }
116
117 size_t num_bytes = (size_t)num_bytes_32;
118 if (num_bytes_32 == (uint32_t)-1) {
119 // Another special case for a value larger than 32 bits.
120 uint64_t num_bytes_64;
121 LittleEndian s(&_data[_read_offset], 0, sizeof(uint64_t));
122 s.store_value(&num_bytes_64, sizeof(uint64_t));
123 _read_offset += 8;
124
125 num_bytes = (size_t)num_bytes_64;
126 nassertr((uint64_t)num_bytes == num_bytes_64, false);
127 }
128
129 // Make sure we have this much data to read.
130 nassertr_always(_read_offset + num_bytes <= _data.size(), false);
131
132 data = Datagram(&_data[_read_offset], num_bytes);
133 _read_offset += num_bytes;
134 return true;
135}
136
137/**
138 * Returns true if the buffer has reached the end-of-buffer. This test may
139 * only be made after a call to read_header() or get_datagram() has failed.
140 */
142is_eof() {
143 return (_read_offset + sizeof(uint32_t)) > _data.size();
144}
145
146/**
147 * Returns true if the buffer has reached an error condition.
148 */
150is_error() {
151 return false;
152}
virtual bool is_error() override
Returns true if the buffer has reached an error condition.
bool read_header(std::string &header, size_t num_bytes)
Reads a sequence of bytes from the beginning of the datagram file.
virtual bool put_datagram(const Datagram &data) override
Writes the given datagram to the file.
virtual bool get_datagram(Datagram &data) override
Reads the next datagram from the file.
virtual void flush() override
This does absolutely nothing.
bool write_header(const std::string &header)
Writes a sequence of bytes to the beginning of the datagram file.
virtual bool is_eof() override
Returns true if the buffer has reached the end-of-buffer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
NativeNumericData and ReversedNumericData work together to provide a sneaky interface for automatical...
const void * get_data() const
Returns the pointer to the first byte of the data, either reversed or nonreversed,...
void store_value(void *dest, size_t length) const
Copies the data, with byte reversal if appropriate, into the indicated numeric variable,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.