Panda3D
datagram.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 datagram.cxx
10  * @author drose
11  * @date 2000-06-06
12  */
13 
14 #include "datagram.h"
15 
16 #include "pnotify.h"
17 
18 // for sprintf().
19 #include <stdio.h>
20 
21 TypeHandle Datagram::_type_handle;
22 
23 /**
24  *
25  */
26 Datagram::
27 ~Datagram() {
28 }
29 
30 /**
31  * Resets the datagram to empty, in preparation for building up a new
32  * datagram.
33  */
34 void Datagram::
35 clear() {
36  _data.clear();
37 }
38 
39 /**
40  * Writes a representation of the entire datagram contents, as a sequence of
41  * hex (and ASCII) values.
42  */
43 void Datagram::
44 dump_hex(std::ostream &out, unsigned int indent) const {
45  const char *message = (const char *)get_data();
46  size_t num_bytes = get_length();
47  for (size_t line = 0; line < num_bytes; line += 16) {
48  char hex[12];
49  sprintf(hex, "%04x ", ((unsigned int )line));
50  for (unsigned int ind = 0; ind < indent; ind++) {
51  out << " ";
52  }
53  out << hex;
54 
55  size_t p;
56  for (p = line; p < line + 16; p++) {
57  if (p < num_bytes) {
58  char hex[12];
59  sprintf(hex, " %02x", ((unsigned int)message[p]) & 0xff);
60  out << hex;
61  } else {
62  out << " ";
63  }
64  }
65  out << " ";
66  for (p = line; p < line + 16 && p < num_bytes; p++) {
67  // must cast to (unsigned char) to avoid conversion to large negative
68  // integers outside of 0xFF range
69  if (isgraph((unsigned char)message[p]) || message[p] == ' ') {
70  out << (char)message[p];
71  } else {
72  out << ".";
73  }
74  }
75  out << "\n";
76  }
77 }
78 
79 /**
80  * Adds a variable-length wstring to the datagram.
81  */
82 void Datagram::
83 add_wstring(const std::wstring &str) {
84  // By convention, wstrings are marked with 32-bit lengths.
85  add_uint32((uint32_t)str.length());
86 
87  // Now append each character in the string. We store each code little-
88  // endian, for no real good reason.
89  std::wstring::const_iterator ci;
90  for (ci = str.begin(); ci != str.end(); ++ci) {
91  add_uint16((uint16_t)*ci);
92  }
93 }
94 
95 /**
96  * Adds the indicated number of zero bytes to the datagram.
97  */
98 void Datagram::
99 pad_bytes(size_t size) {
100  nassertv((int)size >= 0);
101 
102  if (_data == nullptr) {
103  // Create a new array.
104  _data = PTA_uchar::empty_array(0);
105 
106  } else if (_data.get_ref_count() != 1) {
107  // Copy on write.
108  PTA_uchar new_data = PTA_uchar::empty_array(0);
109  new_data.v() = _data.v();
110  _data = new_data;
111  }
112 
113  // Now append the data.
114 
115  // It is very important that we *don't* do this reserve() operation. See
116  // the further comments in append_data(), below. _data.reserve(_data.size()
117  // + size);
118 
119  while (size > 0) {
120  _data.push_back('\0');
121  --size;
122  }
123 }
124 
125 /**
126  * Appends some more raw data to the end of the datagram.
127  */
128 void Datagram::
129 append_data(const void *data, size_t size) {
130  nassertv((int)size >= 0);
131 
132  if (_data == nullptr) {
133  // Create a new array.
134  _data = PTA_uchar::empty_array(0);
135 
136  } else if (_data.get_ref_count() != 1) {
137  // Copy on write.
138  PTA_uchar new_data = PTA_uchar::empty_array(0);
139  new_data.v() = _data.v();
140  _data = new_data;
141  }
142 
143  // Now append the data.
144 
145  // It is very important that we *don't* do this reserve() operation. This
146  // actually slows it down on Windows, which takes the reserve() request as a
147  // fixed size the array should be set to (!) instead of as a minimum size to
148  // guarantee. This forces the array to reallocate itself with *every* call
149  // to append_data! _data.reserve(_data.size() + size);
150 
151  _data.v().insert(_data.v().end(), (const unsigned char *)data,
152  (const unsigned char *)data + size);
153 }
154 
155 /**
156  * Replaces the datagram's data with the indicated block.
157  */
158 void Datagram::
159 assign(const void *data, size_t size) {
160  nassertv((int)size >= 0);
161 
162  _data = PTA_uchar::empty_array(0);
163  _data.v().insert(_data.v().end(), (const unsigned char *)data,
164  (const unsigned char *)data + size);
165 }
166 
167 /**
168  * Write a string representation of this instance to <out>.
169  */
170 void Datagram::
171 output(std::ostream &out) const {
172  #ifndef NDEBUG //[
173  out<<""<<"Datagram";
174  #endif //] NDEBUG
175 }
176 
177 /**
178  * Write a string representation of this instance to <out>.
179  */
180 void Datagram::
181 write(std::ostream &out, unsigned int indent) const {
182  #ifndef NDEBUG //[
183  out.width(indent);
184  out<<""<<"Datagram:\n";
185  dump_hex(out, indent);
186  #endif //] NDEBUG
187 }
void dump_hex(std::ostream &out, unsigned int indent=0) const
Writes a representation of the entire datagram contents, as a sequence of hex (and ASCII) values.
Definition: datagram.cxx:44
void append_data(const void *data, size_t size)
Appends some more raw data to the end of the datagram.
Definition: datagram.cxx:129
void output(std::ostream &out) const
Write a string representation of this instance to <out>.
Definition: datagram.cxx:171
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void clear()
Resets the datagram to empty, in preparation for building up a new datagram.
Definition: datagram.cxx:35
void assign(const void *data, size_t size)
Replaces the datagram's data with the indicated block.
Definition: datagram.cxx:159
void add_wstring(const std::wstring &str)
Adds a variable-length wstring to the datagram.
Definition: datagram.cxx:83
void pad_bytes(size_t size)
Adds the indicated number of zero bytes to the datagram.
Definition: datagram.cxx:99
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:94
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:85
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void write(std::ostream &out, unsigned int indent=0) const
Write a string representation of this instance to <out>.
Definition: datagram.cxx:181
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
size_t get_length() const
Returns the number of bytes in the datagram.
Definition: datagram.I:335
const void * get_data() const
Returns a pointer to the beginning of the datagram's data.
Definition: datagram.I:327