00001 // Filename: datagram.cxx 00002 // Created by: drose (06Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 #include "datagram.h" 00021 00022 #include <notify.h> 00023 00024 // for sprintf(). 00025 #include <stdio.h> 00026 00027 TypeHandle Datagram::_type_handle; 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: Datagram::Destructor 00031 // Access: Public, Virtual 00032 // Description: 00033 //////////////////////////////////////////////////////////////////// 00034 Datagram:: 00035 ~Datagram() { 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function: Datagram::clear 00040 // Access: Public, Virtual 00041 // Description: Resets the datagram to empty, in preparation for 00042 // building up a new datagram. 00043 //////////////////////////////////////////////////////////////////// 00044 void Datagram:: 00045 clear() { 00046 _data.clear(); 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: Datagram::dump_hex 00051 // Access: Public 00052 // Description: Writes a representation of the entire datagram 00053 // contents, as a sequence of hex (and ASCII) values. 00054 //////////////////////////////////////////////////////////////////// 00055 void Datagram:: 00056 dump_hex(ostream &out) const { 00057 const char *message = (const char *)get_data(); 00058 size_t num_bytes = get_length(); 00059 for (size_t line = 0; line < num_bytes; line += 16) { 00060 char hex[12]; 00061 sprintf(hex, "%04x ", line); 00062 out << hex; 00063 00064 size_t p; 00065 for (p = line; p < line + 16; p++) { 00066 if (p < num_bytes) { 00067 char hex[12]; 00068 sprintf(hex, " %02x", ((unsigned int)message[p]) & 0xff); 00069 out << hex; 00070 } else { 00071 out << " "; 00072 } 00073 } 00074 out << " "; 00075 for (p = line; p < line + 16 && p < num_bytes; p++) { 00076 // must cast to (unsigned char) to avoid conversion to large negative integers outside of 0xFF range 00077 if (isgraph((unsigned char)message[p]) || message[p] == ' ') { 00078 out << (char)message[p]; 00079 } else { 00080 out << "."; 00081 } 00082 } 00083 out << "\n"; 00084 } 00085 } 00086 00087 00088 //////////////////////////////////////////////////////////////////// 00089 // Function: Datagram::pad_bytes 00090 // Access: Public 00091 // Description: Adds the indicated number of zero bytes to the 00092 // datagram. 00093 //////////////////////////////////////////////////////////////////// 00094 void Datagram:: 00095 pad_bytes(size_t size) { 00096 nassertv((int)size >= 0); 00097 00098 if (_data == (uchar *)NULL) { 00099 // Create a new array. 00100 // _data = PTA_uchar(0); 00101 _data = PTA_uchar::empty_array(0); 00102 00103 } else if (_data.get_ref_count() == 1) { 00104 // Copy on write. 00105 PTA_uchar new_data = PTA_uchar::empty_array(0); 00106 new_data.v() = _data.v(); 00107 _data = new_data; 00108 } 00109 00110 // Now append the data. 00111 00112 // It is very important that we *don't* do this reserve() operation. 00113 // See the further comments in append_data(), below. 00114 // _data.reserve(_data.size() + size); 00115 00116 while (size > 0) { 00117 _data.push_back('\0'); 00118 size--; 00119 } 00120 } 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function: Datagram::append_data 00124 // Access: Public 00125 // Description: Appends some more raw data to the end of the 00126 // datagram. 00127 //////////////////////////////////////////////////////////////////// 00128 void Datagram:: 00129 append_data(const void *data, size_t size) { 00130 nassertv((int)size >= 0); 00131 00132 if (_data == (uchar *)NULL) { 00133 // Create a new array. 00134 _data = PTA_uchar::empty_array(0); 00135 00136 } else if (_data.get_ref_count() != 1) { 00137 // Copy on write. 00138 PTA_uchar new_data = PTA_uchar::empty_array(0); 00139 new_data.v() = _data.v(); 00140 _data = new_data; 00141 } 00142 00143 // Now append the data. 00144 00145 // It is very important that we *don't* do this reserve() operation. 00146 // This actually slows it down on Windows, which takes the reserve() 00147 // request as a fixed size the array should be set to (!) instead of 00148 // as a minimum size to guarantee. This forces the array to 00149 // reallocate itself with *every* call to append_data! 00150 // _data.reserve(_data.size() + size); 00151 00152 const uchar *source = (const uchar *)data; 00153 for (size_t i = 0; i < size; i++) { 00154 _data.v().push_back(source[i]); 00155 } 00156 }