mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
Use vector_uchar instead of string for binary network/file data
This distinction allows us to better support Python 3, since it will raise exceptions when trying to put arbitrary binary data in a str object. This also adds some convenience functions for efficiently initializing a Datagram or PTA_uchar from a vector_uchar.
This commit is contained in:
parent
fadbcd91e5
commit
e9ae7dcc40
@ -803,8 +803,9 @@ handle_update_field_owner() {
|
||||
Py_DECREF(dclass_this);
|
||||
|
||||
// check if we should forward this update to the owner view
|
||||
vector_uchar data = _di.get_remaining_bytes();
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(_di.get_remaining_bytes());
|
||||
packer.set_unpack_data((const char *)data.data(), data.size(), false);
|
||||
int field_id = packer.raw_unpack_uint16();
|
||||
DCField *field = dclass->get_field_by_index(field_id);
|
||||
if (field->is_ownrecv()) {
|
||||
@ -845,8 +846,9 @@ handle_update_field_owner() {
|
||||
Py_DECREF(dclass_this);
|
||||
|
||||
// check if we should forward this update to the owner view
|
||||
vector_uchar data = _di.get_remaining_bytes();
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(_di.get_remaining_bytes());
|
||||
packer.set_unpack_data((const char *)data.data(), data.size(), false);
|
||||
int field_id = packer.raw_unpack_uint16();
|
||||
DCField *field = dclass->get_field_by_index(field_id);
|
||||
if (true) {//field->is_broadcast()) {
|
||||
|
@ -146,14 +146,15 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
int iv_length = EVP_CIPHER_iv_length(cipher);
|
||||
_read_block_size = EVP_CIPHER_block_size(cipher);
|
||||
|
||||
string iv = sr.extract_bytes(iv_length);
|
||||
unsigned char *iv = (unsigned char *)alloca(iv_length);
|
||||
iv_length = (int)sr.extract_bytes(iv, iv_length);
|
||||
|
||||
_read_ctx = EVP_CIPHER_CTX_new();
|
||||
nassertv(_read_ctx != NULL);
|
||||
|
||||
// Initialize the context
|
||||
int result;
|
||||
result = EVP_DecryptInit(_read_ctx, cipher, NULL, (unsigned char *)iv.data());
|
||||
result = EVP_DecryptInit(_read_ctx, cipher, NULL, (unsigned char *)iv);
|
||||
nassertv(result > 0);
|
||||
|
||||
result = EVP_CIPHER_CTX_set_key_length(_read_ctx, key_length);
|
||||
@ -170,7 +171,7 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
unsigned char *key = (unsigned char *)alloca(key_length);
|
||||
result =
|
||||
PKCS5_PBKDF2_HMAC_SHA1((const char *)password.data(), password.length(),
|
||||
(unsigned char *)iv.data(), iv.length(),
|
||||
iv, iv_length,
|
||||
count * iteration_count_factor + 1,
|
||||
key_length, key);
|
||||
nassertv(result > 0);
|
||||
|
@ -117,16 +117,18 @@ extract_bytes(unsigned char *into, size_t size) {
|
||||
* Extracts the indicated number of bytes in the stream and returns them as a
|
||||
* string. Returns empty string at end-of-file.
|
||||
*/
|
||||
string StreamReader::
|
||||
vector_uchar StreamReader::
|
||||
extract_bytes(size_t size) {
|
||||
vector_uchar buffer;
|
||||
if (_in->eof() || _in->fail()) {
|
||||
return string();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *buffer = (char *)alloca(size);
|
||||
_in->read(buffer, size);
|
||||
buffer.resize(size);
|
||||
_in->read((char *)&buffer[0], size);
|
||||
size_t read_bytes = _in->gcount();
|
||||
return string(buffer, read_bytes);
|
||||
buffer.resize(read_bytes);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "numeric_types.h"
|
||||
#include "littleEndian.h"
|
||||
#include "bigEndian.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
/**
|
||||
* A class to read sequential binary data directly from an istream. Its
|
||||
@ -71,7 +72,7 @@ PUBLISHED:
|
||||
EXTENSION(BLOCKING PyObject *readlines());
|
||||
|
||||
public:
|
||||
BLOCKING string extract_bytes(size_t size);
|
||||
BLOCKING vector_uchar extract_bytes(size_t size);
|
||||
BLOCKING string readline();
|
||||
|
||||
private:
|
||||
|
@ -583,9 +583,7 @@ add_multifile_record(PT(MultifileRecord) mfr) {
|
||||
* Verifies magic number, returns the number of multifiles or -1 if invalid
|
||||
*/
|
||||
int DownloadDb::Db::
|
||||
parse_header(const string &data) {
|
||||
Datagram dg(data);
|
||||
|
||||
parse_header(Datagram dg) {
|
||||
// Make sure we have a good header
|
||||
DatagramIterator di(dg);
|
||||
uint32_t magic_number = di.get_uint32();
|
||||
@ -623,8 +621,7 @@ parse_header(const string &data) {
|
||||
* record
|
||||
*/
|
||||
int DownloadDb::Db::
|
||||
parse_record_header(const string &data) {
|
||||
Datagram dg(data);
|
||||
parse_record_header(Datagram dg) {
|
||||
DatagramIterator di(dg);
|
||||
int32_t record_length = di.get_int32();
|
||||
downloader_cat.spam()
|
||||
@ -639,14 +636,12 @@ parse_record_header(const string &data) {
|
||||
* Parses a multifile record (mfr) and returns one
|
||||
*/
|
||||
PT(DownloadDb::MultifileRecord) DownloadDb::Db::
|
||||
parse_mfr(const string &data) {
|
||||
parse_mfr(Datagram dg) {
|
||||
|
||||
PT(DownloadDb::MultifileRecord) mfr = new DownloadDb::MultifileRecord;
|
||||
|
||||
Datagram dg(data);
|
||||
DatagramIterator di(dg);
|
||||
int32_t mfr_name_length = di.get_int32();
|
||||
mfr->_name = di.extract_bytes(mfr_name_length);
|
||||
mfr->_name = di.get_string32();
|
||||
mfr->_phase = di.get_float64();
|
||||
mfr->_size = di.get_int32();
|
||||
mfr->_status = di.get_int32();
|
||||
@ -676,14 +671,12 @@ parse_mfr(const string &data) {
|
||||
* Parses a file record (fr) and returns one
|
||||
*/
|
||||
PT(DownloadDb::FileRecord) DownloadDb::Db::
|
||||
parse_fr(const string &data) {
|
||||
parse_fr(Datagram dg) {
|
||||
|
||||
PT(DownloadDb::FileRecord) fr = new DownloadDb::FileRecord;
|
||||
|
||||
Datagram dg(data);
|
||||
DatagramIterator di(dg);
|
||||
int32_t fr_name_length = di.get_int32();
|
||||
fr->_name = di.extract_bytes(fr_name_length);
|
||||
fr->_name = di.get_string32();
|
||||
|
||||
// At one time, we stored files in the database with a backslash separator.
|
||||
// Nowadays we use a forward slash, but we should make sure we properly
|
||||
@ -706,15 +699,14 @@ parse_fr(const string &data) {
|
||||
bool DownloadDb::Db::
|
||||
read(StreamReader &sr, bool want_server_info) {
|
||||
// Read the header
|
||||
string header;
|
||||
header = sr.extract_bytes(_header_length);
|
||||
vector_uchar header = sr.extract_bytes(_header_length);
|
||||
if (header.size() != (size_t)_header_length) {
|
||||
downloader_cat.error() << "truncated db file" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the header
|
||||
int num_multifiles = parse_header(header);
|
||||
int num_multifiles = parse_header(Datagram(move(header)));
|
||||
if (num_multifiles < 0) {
|
||||
downloader_cat.error() << "invalid db header" << endl;
|
||||
return false;
|
||||
@ -727,26 +719,26 @@ read(StreamReader &sr, bool want_server_info) {
|
||||
// of the record
|
||||
int mfr_header_length = sizeof(int32_t);
|
||||
|
||||
string mfr_header = sr.extract_bytes(mfr_header_length);
|
||||
vector_uchar mfr_header = sr.extract_bytes(mfr_header_length);
|
||||
if (mfr_header.size() != (size_t)mfr_header_length) {
|
||||
downloader_cat.error() << "invalid mfr header" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the header
|
||||
int mfr_length = parse_record_header(mfr_header);
|
||||
int mfr_length = parse_record_header(Datagram(move(mfr_header)));
|
||||
|
||||
// Ok, now that we know the size of the mfr, read it in Make a buffer to
|
||||
// read the multifile record into do not count the header length twice
|
||||
int read_length = (mfr_length - mfr_header_length);
|
||||
string mfr_record = sr.extract_bytes(read_length);
|
||||
vector_uchar mfr_record = sr.extract_bytes(read_length);
|
||||
if (mfr_record.size() != (size_t)read_length) {
|
||||
downloader_cat.error() << "invalid mfr record" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the mfr
|
||||
PT(DownloadDb::MultifileRecord) mfr = parse_mfr(mfr_record);
|
||||
PT(DownloadDb::MultifileRecord) mfr = parse_mfr(Datagram(move(mfr_record)));
|
||||
|
||||
// Only read in the individual file info if you are the server
|
||||
if (want_server_info) {
|
||||
@ -758,27 +750,27 @@ read(StreamReader &sr, bool want_server_info) {
|
||||
int fr_header_length = sizeof(int32_t);
|
||||
|
||||
// Read the header
|
||||
string fr_header = sr.extract_bytes(fr_header_length);
|
||||
vector_uchar fr_header = sr.extract_bytes(fr_header_length);
|
||||
if (fr_header.size() != (size_t)fr_header_length) {
|
||||
downloader_cat.error() << "invalid fr header" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the header
|
||||
int fr_length = parse_record_header(fr_header);
|
||||
int fr_length = parse_record_header(Datagram(move(fr_header)));
|
||||
|
||||
// Ok, now that we know the size of the mfr, read it in do not count
|
||||
// the header length twice
|
||||
int read_length = (fr_length - fr_header_length);
|
||||
|
||||
string fr_record = sr.extract_bytes(read_length);
|
||||
vector_uchar fr_record = sr.extract_bytes(read_length);
|
||||
if (fr_record.size() != (size_t)read_length) {
|
||||
downloader_cat.error() << "invalid fr record" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the file record
|
||||
PT(DownloadDb::FileRecord) fr = parse_fr(fr_record);
|
||||
PT(DownloadDb::FileRecord) fr = parse_fr(Datagram(move(fr_record)));
|
||||
|
||||
// Add this file record to the current multifilerecord
|
||||
mfr->add_file_record(fr);
|
||||
@ -900,12 +892,10 @@ write_header(ostream &write_stream) {
|
||||
// Write the number of multifiles
|
||||
dg.add_int32(get_num_multifiles());
|
||||
|
||||
string msg = dg.get_message();
|
||||
|
||||
// Seek back to the beginning of the write stream
|
||||
write_stream.seekp(0);
|
||||
// Overwrite the old bogus header with the real header
|
||||
write_stream.write(msg.data(), msg.length());
|
||||
write_stream.write((const char *)dg.get_data(), dg.get_length());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1100,17 +1090,8 @@ read_version_map(StreamReader &sr) {
|
||||
|
||||
for (int i = 0; i < num_entries; i++) {
|
||||
|
||||
// Get the length of the file name
|
||||
int name_length = sr.get_int32();
|
||||
if (sr.get_istream()->fail()) {
|
||||
return false;
|
||||
}
|
||||
downloader_cat.spam()
|
||||
<< "DownloadDb::read_version_map() - name length: " << name_length
|
||||
<< endl;
|
||||
|
||||
// Get the file name
|
||||
string name = sr.extract_bytes(name_length);
|
||||
string name = sr.get_string32();
|
||||
downloader_cat.spam()
|
||||
<< "DownloadDb::read_version_map() - name: " << name << endl;
|
||||
|
||||
|
@ -171,10 +171,10 @@ public:
|
||||
bool multifile_exists(string mfname) const;
|
||||
PT(MultifileRecord) get_multifile_record_named(string mfname) const;
|
||||
void add_multifile_record(PT(MultifileRecord) mfr);
|
||||
int parse_header(const string &data);
|
||||
int parse_record_header(const string &data);
|
||||
PT(MultifileRecord) parse_mfr(const string &data);
|
||||
PT(FileRecord) parse_fr(const string &data);
|
||||
int parse_header(Datagram dg);
|
||||
int parse_record_header(Datagram dg);
|
||||
PT(MultifileRecord) parse_mfr(Datagram dg);
|
||||
PT(FileRecord) parse_fr(Datagram dg);
|
||||
bool read(StreamReader &sr, bool want_server_info);
|
||||
bool write(StreamWriter &sw, bool want_server_info);
|
||||
Filename _filename;
|
||||
|
@ -50,17 +50,17 @@ SSReader::
|
||||
bool SSReader::
|
||||
do_receive_datagram(Datagram &dg) {
|
||||
if (_tcp_header_size == 0) {
|
||||
_data_expected = _data_so_far.length();
|
||||
_data_expected = _data_so_far.size();
|
||||
}
|
||||
if (_data_expected == 0) {
|
||||
// Read the first two bytes: the datagram length.
|
||||
while ((int)_data_so_far.length() < _tcp_header_size) {
|
||||
while ((int)_data_so_far.size() < _tcp_header_size) {
|
||||
int ch = _istream->get();
|
||||
if (_istream->eof() || _istream->fail()) {
|
||||
_istream->clear();
|
||||
return false;
|
||||
}
|
||||
_data_so_far += (char)ch;
|
||||
_data_so_far.push_back((unsigned char)ch);
|
||||
}
|
||||
|
||||
Datagram header(_data_so_far);
|
||||
@ -70,7 +70,7 @@ do_receive_datagram(Datagram &dg) {
|
||||
} else if (_tcp_header_size == 4) {
|
||||
_data_expected = di.get_uint32();
|
||||
}
|
||||
_data_so_far = _data_so_far.substr(_tcp_header_size);
|
||||
_data_so_far.erase(_data_so_far.begin(), _data_so_far.begin() + _tcp_header_size);
|
||||
|
||||
if (_data_expected == 0) {
|
||||
// Empty datagram.
|
||||
@ -84,20 +84,19 @@ do_receive_datagram(Datagram &dg) {
|
||||
static const size_t buffer_size = 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
size_t read_count = min(_data_expected - _data_so_far.length(),
|
||||
buffer_size);
|
||||
size_t read_count = min(_data_expected - _data_so_far.size(), buffer_size);
|
||||
_istream->read(buffer, read_count);
|
||||
size_t count = _istream->gcount();
|
||||
while (count != 0) {
|
||||
_data_so_far.append(buffer, count);
|
||||
_data_so_far.insert(_data_so_far.end(), buffer, buffer + count);
|
||||
|
||||
read_count = min(_data_expected - _data_so_far.length(),
|
||||
read_count = min(_data_expected - _data_so_far.size(),
|
||||
buffer_size);
|
||||
_istream->read(buffer, read_count);
|
||||
count = _istream->gcount();
|
||||
}
|
||||
|
||||
if (_data_so_far.length() < _data_expected) {
|
||||
if (_data_so_far.size() < _data_expected) {
|
||||
// Not yet here. Clear the istream error flag and return false to
|
||||
// indicate more coming.
|
||||
_istream->clear();
|
||||
@ -108,7 +107,7 @@ do_receive_datagram(Datagram &dg) {
|
||||
dg.append_data(_data_so_far);
|
||||
|
||||
_data_expected = 0;
|
||||
_data_so_far = string();
|
||||
_data_so_far.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "pdeque.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
// At the present, this module is not compiled if OpenSSL is not available,
|
||||
// since the only current use for it is to implement OpenSSL-defined
|
||||
@ -54,7 +55,7 @@ private:
|
||||
|
||||
istream *_istream;
|
||||
size_t _data_expected;
|
||||
string _data_so_far;
|
||||
vector_uchar _data_so_far;
|
||||
int _tcp_header_size;
|
||||
|
||||
#ifdef SIMULATE_NETWORK_DELAY
|
||||
|
@ -42,58 +42,16 @@ Datagram(const void *data, size_t size) :
|
||||
* Constructs a datagram from an existing block of data.
|
||||
*/
|
||||
INLINE Datagram::
|
||||
Datagram(const string &data) :
|
||||
Datagram(vector_uchar data) :
|
||||
_data(move(data)),
|
||||
#ifdef STDFLOAT_DOUBLE
|
||||
_stdfloat_double(true)
|
||||
#else
|
||||
_stdfloat_double(false)
|
||||
#endif
|
||||
{
|
||||
append_data(data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE Datagram::
|
||||
Datagram(const Datagram ©) :
|
||||
_data(copy._data),
|
||||
_stdfloat_double(copy._stdfloat_double)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void Datagram::
|
||||
operator = (const Datagram ©) {
|
||||
_data = copy._data;
|
||||
_stdfloat_double = copy._stdfloat_double;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE Datagram::
|
||||
Datagram(Datagram &&from) NOEXCEPT :
|
||||
_data(move(from._data)),
|
||||
_stdfloat_double(from._stdfloat_double)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void Datagram::
|
||||
operator = (Datagram &&from) NOEXCEPT {
|
||||
_data = move(from._data);
|
||||
_stdfloat_double = from._stdfloat_double;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
/**
|
||||
* Adds a boolean value to the datagram.
|
||||
*/
|
||||
@ -291,7 +249,7 @@ add_string(const string &str) {
|
||||
add_uint16((uint16_t)str.length());
|
||||
|
||||
// Add the string
|
||||
append_data(str);
|
||||
append_data(str.data(), str.length());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,18 +262,18 @@ add_string32(const string &str) {
|
||||
add_uint32((uint32_t)str.length());
|
||||
|
||||
// Add the string
|
||||
append_data(str);
|
||||
append_data(str.data(), str.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a variable-length string to the datagram, as a NULL-terminated string.
|
||||
*/
|
||||
INLINE void Datagram::
|
||||
add_z_string(string str) {
|
||||
add_z_string(const string &str) {
|
||||
// We must not have any nested null characters in the string.
|
||||
size_t null_pos = str.find('\0');
|
||||
// Add the string (sans the null character).
|
||||
append_data(str.substr(0, null_pos));
|
||||
append_data(str.data(), std::min<size_t>(null_pos, str.length()));
|
||||
|
||||
// And the null character.
|
||||
add_uint8('\0');
|
||||
@ -329,11 +287,11 @@ add_z_string(string str) {
|
||||
INLINE void Datagram::
|
||||
add_fixed_string(const string &str, size_t size) {
|
||||
if (str.length() < size) {
|
||||
append_data(str);
|
||||
append_data(str.data(), str.length());
|
||||
pad_bytes(size - str.length());
|
||||
|
||||
} else { // str.length() >= size
|
||||
append_data(str.substr(0, size));
|
||||
append_data(str.data(), size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,8 +299,8 @@ add_fixed_string(const string &str, size_t size) {
|
||||
* Appends some more raw data to the end of the datagram.
|
||||
*/
|
||||
INLINE void Datagram::
|
||||
append_data(const string &data) {
|
||||
append_data(data.data(), data.length());
|
||||
append_data(const vector_uchar &data) {
|
||||
append_data(data.data(), data.size());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,14 +39,7 @@ class EXPCL_PANDAEXPRESS Datagram : public TypedObject {
|
||||
PUBLISHED:
|
||||
INLINE Datagram();
|
||||
INLINE Datagram(const void *data, size_t size);
|
||||
INLINE Datagram(const string &data);
|
||||
INLINE Datagram(const Datagram ©);
|
||||
INLINE void operator = (const Datagram ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Datagram(Datagram &&from) NOEXCEPT;
|
||||
INLINE void operator = (Datagram &&from) NOEXCEPT;
|
||||
#endif
|
||||
INLINE explicit Datagram(vector_uchar data);
|
||||
|
||||
virtual ~Datagram();
|
||||
|
||||
@ -80,13 +73,13 @@ PUBLISHED:
|
||||
|
||||
INLINE void add_string(const string &str);
|
||||
INLINE void add_string32(const string &str);
|
||||
INLINE void add_z_string(string str);
|
||||
INLINE void add_z_string(const string &str);
|
||||
INLINE void add_fixed_string(const string &str, size_t size);
|
||||
void add_wstring(const wstring &str);
|
||||
|
||||
void pad_bytes(size_t size);
|
||||
void append_data(const void *data, size_t size);
|
||||
INLINE void append_data(const string &data);
|
||||
INLINE void append_data(const vector_uchar &data);
|
||||
|
||||
void assign(const void *data, size_t size);
|
||||
|
||||
|
@ -422,14 +422,13 @@ skip_bytes(size_t size) {
|
||||
* Returns the remaining bytes in the datagram as a string, but does not
|
||||
* extract them from the iterator.
|
||||
*/
|
||||
INLINE string DatagramIterator::
|
||||
INLINE vector_uchar DatagramIterator::
|
||||
get_remaining_bytes() const {
|
||||
nassertr(_datagram != (const Datagram *)NULL, "");
|
||||
nassertr(_current_index <= _datagram->get_length(), "");
|
||||
nassertr(_datagram != (const Datagram *)NULL, vector_uchar());
|
||||
nassertr(_current_index <= _datagram->get_length(), vector_uchar());
|
||||
|
||||
const char *ptr = (const char *)_datagram->get_data();
|
||||
size_t remaining_size = _datagram->get_length() - _current_index;
|
||||
return string(ptr + _current_index, remaining_size);
|
||||
const unsigned char *ptr = (const unsigned char *)_datagram->get_data();
|
||||
return vector_uchar(ptr + _current_index, ptr + _datagram->get_length());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,18 +119,18 @@ get_wstring() {
|
||||
* Extracts the indicated number of bytes in the datagram and returns them as
|
||||
* a string.
|
||||
*/
|
||||
string DatagramIterator::
|
||||
vector_uchar DatagramIterator::
|
||||
extract_bytes(size_t size) {
|
||||
nassertr((int)size >= 0, "");
|
||||
nassertr(_datagram != (const Datagram *)NULL, "");
|
||||
nassertr(_current_index + size <= _datagram->get_length(), "");
|
||||
nassertr((int)size >= 0, vector_uchar());
|
||||
nassertr(_datagram != (const Datagram *)NULL, vector_uchar());
|
||||
nassertr(_current_index + size <= _datagram->get_length(), vector_uchar());
|
||||
|
||||
const char *ptr = (const char *)_datagram->get_data();
|
||||
size_t last_index = _current_index;
|
||||
const unsigned char *ptr = (const unsigned char *)_datagram->get_data();
|
||||
ptr += _current_index;
|
||||
|
||||
_current_index += size;
|
||||
|
||||
return string(ptr + last_index, size);
|
||||
return vector_uchar(ptr, ptr + size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,10 +62,10 @@ PUBLISHED:
|
||||
wstring get_wstring();
|
||||
|
||||
INLINE void skip_bytes(size_t size);
|
||||
string extract_bytes(size_t size);
|
||||
vector_uchar extract_bytes(size_t size);
|
||||
size_t extract_bytes(unsigned char *into, size_t size);
|
||||
|
||||
INLINE string get_remaining_bytes() const;
|
||||
INLINE vector_uchar get_remaining_bytes() const;
|
||||
INLINE size_t get_remaining_size() const;
|
||||
|
||||
INLINE const Datagram &get_datagram() const;
|
||||
|
@ -143,11 +143,11 @@ set_from_hex(const string &text) {
|
||||
/**
|
||||
* Returns the HashVal as a 16-byte binary string.
|
||||
*/
|
||||
string HashVal::
|
||||
vector_uchar HashVal::
|
||||
as_bin() const {
|
||||
Datagram dg;
|
||||
write_datagram(dg);
|
||||
return dg.get_message();
|
||||
return vector_uchar((unsigned char *)dg.get_data(), (unsigned char *)dg.get_data() + dg.get_length());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,7 +155,7 @@ as_bin() const {
|
||||
* false otherwise.
|
||||
*/
|
||||
bool HashVal::
|
||||
set_from_bin(const string &text) {
|
||||
set_from_bin(const vector_uchar &text) {
|
||||
nassertr(text.size() == 16, false);
|
||||
Datagram dg(text);
|
||||
DatagramIterator dgi(dg);
|
||||
|
@ -55,8 +55,8 @@ PUBLISHED:
|
||||
string as_hex() const;
|
||||
bool set_from_hex(const string &text);
|
||||
|
||||
string as_bin() const;
|
||||
bool set_from_bin(const string &text);
|
||||
vector_uchar as_bin() const;
|
||||
bool set_from_bin(const vector_uchar &text);
|
||||
|
||||
INLINE void write_datagram(Datagram &destination) const;
|
||||
INLINE void read_datagram(DatagramIterator &source);
|
||||
|
@ -2402,7 +2402,7 @@ check_signatures() {
|
||||
nassertv(stream != NULL);
|
||||
StreamReader reader(*stream);
|
||||
size_t sig_size = reader.get_uint32();
|
||||
string sig_string = reader.extract_bytes(sig_size);
|
||||
vector_uchar sig_data = reader.extract_bytes(sig_size);
|
||||
|
||||
size_t num_certs = reader.get_uint32();
|
||||
|
||||
@ -2470,9 +2470,7 @@ check_signatures() {
|
||||
|
||||
// Now check that the signature matches the hash.
|
||||
int verify_result =
|
||||
EVP_VerifyFinal(md_ctx,
|
||||
(unsigned char *)sig_string.data(),
|
||||
sig_string.size(), pkey);
|
||||
EVP_VerifyFinal(md_ctx, sig_data.data(), sig_data.size(), pkey);
|
||||
if (verify_result == 1) {
|
||||
// The signature matches; save the certificate and its chain.
|
||||
_signatures.push_back(chain);
|
||||
|
@ -92,6 +92,19 @@ PointerToArray(PointerToArray<Element> &&from) NOEXCEPT :
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
/**
|
||||
* Initializes the PTA from a vector.
|
||||
*/
|
||||
template<class Element>
|
||||
INLINE PointerToArray<Element>::
|
||||
PointerToArray(pvector<Element> &&from, TypeHandle type_handle) :
|
||||
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(move(from))),
|
||||
_type_handle(type_handle)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -710,6 +723,19 @@ ConstPointerToArray(ConstPointerToArray<Element> &&from) NOEXCEPT :
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
/**
|
||||
* Initializes the PTA from a vector.
|
||||
*/
|
||||
template<class Element>
|
||||
INLINE ConstPointerToArray<Element>::
|
||||
ConstPointerToArray(pvector<Element> &&from, TypeHandle type_handle) :
|
||||
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(move(from))),
|
||||
_type_handle(type_handle)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -141,6 +141,7 @@ public:
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE PointerToArray(PointerToArray<Element> &&from) NOEXCEPT;
|
||||
INLINE explicit PointerToArray(pvector<Element> &&from, TypeHandle type_handle = get_type_handle(Element));
|
||||
#endif
|
||||
|
||||
public:
|
||||
@ -302,6 +303,7 @@ PUBLISHED:
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE ConstPointerToArray(PointerToArray<Element> &&from) NOEXCEPT;
|
||||
INLINE ConstPointerToArray(ConstPointerToArray<Element> &&from) NOEXCEPT;
|
||||
INLINE explicit ConstPointerToArray(pvector<Element> &&from, TypeHandle type_handle = get_type_handle(Element));
|
||||
#endif
|
||||
|
||||
// Duplicating the interface of vector.
|
||||
|
@ -39,6 +39,16 @@ ReferenceCountedVector(const Element *begin, const Element *end, TypeHandle type
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array that takes its elements from the given vector.
|
||||
*/
|
||||
template<class Element>
|
||||
INLINE ReferenceCountedVector<Element>::
|
||||
ReferenceCountedVector(pvector<Element> &&from) :
|
||||
pvector<Element>(move(from))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
INLINE ReferenceCountedVector(TypeHandle type_handle);
|
||||
INLINE ReferenceCountedVector(size_type initial_size, TypeHandle type_handle);
|
||||
INLINE ReferenceCountedVector(const Element *begin, const Element *end, TypeHandle type_handle);
|
||||
INLINE ReferenceCountedVector(pvector<Element> &&from);
|
||||
ALLOC_DELETED_CHAIN(ReferenceCountedVector<Element>);
|
||||
|
||||
INLINE size_type size() const;
|
||||
|
@ -4207,7 +4207,9 @@ bool Texture::
|
||||
do_read_ktx(CData *cdata, istream &in, const string &filename, bool header_only) {
|
||||
StreamReader ktx(in);
|
||||
|
||||
if (ktx.extract_bytes(12) != "\xABKTX 11\xBB\r\n\x1A\n") {
|
||||
unsigned char magic[12];
|
||||
if (ktx.extract_bytes(magic, 12) != 12 ||
|
||||
memcmp(magic, "\xABKTX 11\xBB\r\n\x1A\n", 12) != 0) {
|
||||
gobj_cat.error()
|
||||
<< filename << " is not a KTX file.\n";
|
||||
return false;
|
||||
|
@ -106,7 +106,8 @@ WavAudioCursor(WavAudio *src, istream *stream) :
|
||||
nassertv(stream != NULL);
|
||||
|
||||
// Beginning of "RIFF" chunk.
|
||||
if (_reader.extract_bytes(4) != "RIFF") {
|
||||
unsigned char magic[4];
|
||||
if (_reader.extract_bytes(magic, 4) != 4 || memcmp(magic, "RIFF", 4) != 0) {
|
||||
movies_cat.error()
|
||||
<< ".wav file is not a valid RIFF file.\n";
|
||||
return;
|
||||
@ -114,7 +115,7 @@ WavAudioCursor(WavAudio *src, istream *stream) :
|
||||
|
||||
unsigned int chunk_size = _reader.get_uint32();
|
||||
|
||||
if (_reader.extract_bytes(4) != "WAVE") {
|
||||
if (_reader.extract_bytes(magic, 4) != 4 || memcmp(magic, "WAVE", 4) != 0) {
|
||||
movies_cat.error()
|
||||
<< ".wav file is a RIFF file but does not start with a WAVE chunk.\n";
|
||||
return;
|
||||
@ -126,10 +127,10 @@ WavAudioCursor(WavAudio *src, istream *stream) :
|
||||
|
||||
while ((!have_fmt || !have_data) && _stream->good() && (bytes_read + 8) < chunk_size) {
|
||||
|
||||
string subchunk_id = _reader.extract_bytes(4);
|
||||
_reader.extract_bytes(magic, 4);
|
||||
unsigned int subchunk_size = _reader.get_uint32();
|
||||
|
||||
if (subchunk_id == "fmt ") {
|
||||
if (memcmp(magic, "fmt ", 4) == 0) {
|
||||
// The format chunk specifies information about the storage.
|
||||
nassertv(subchunk_size >= 16);
|
||||
have_fmt = true;
|
||||
@ -202,7 +203,7 @@ WavAudioCursor(WavAudio *src, istream *stream) :
|
||||
_reader.skip_bytes(subchunk_size - read_bytes);
|
||||
}
|
||||
|
||||
} else if (subchunk_id == "data") {
|
||||
} else if (memcmp(magic, "data", 4) == 0) {
|
||||
// The data chunk contains the actual sammples.
|
||||
if (!have_fmt) {
|
||||
movies_cat.error()
|
||||
|
@ -82,8 +82,10 @@ play_frame(DatagramIterator &scan, BamReader *manager) {
|
||||
|
||||
int num_packets = scan.get_uint16();
|
||||
for (int i = 0; i < num_packets; i++) {
|
||||
string packet = scan.get_string();
|
||||
_data.push_back(Datagram(packet));
|
||||
size_t size = scan.get_uint16();
|
||||
vector_uchar packet(size);
|
||||
scan.extract_bytes(&packet[0], size);
|
||||
_data.push_back(Datagram(move(packet)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,9 +78,8 @@ extract_record(FltRecordReader &reader) {
|
||||
bool FltBeadID::
|
||||
extract_ancillary(FltRecordReader &reader) {
|
||||
if (reader.get_opcode() == FO_long_id) {
|
||||
string s = reader.get_iterator().get_remaining_bytes();
|
||||
size_t zero_byte = s.find('\0');
|
||||
_id = s.substr(0, zero_byte);
|
||||
vector_uchar s = reader.get_iterator().get_remaining_bytes();
|
||||
_id.assign((const char *)s.data(), strnlen((const char *)s.data(), s.size()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -109,14 +108,11 @@ build_record(FltRecordWriter &writer) const {
|
||||
FltError FltBeadID::
|
||||
write_ancillary(FltRecordWriter &writer) const {
|
||||
if (_id.length() > 7) {
|
||||
Datagram dc;
|
||||
|
||||
// Although the manual mentions nothing of this, it is essential that the
|
||||
// length of the record be a multiple of 4 bytes.
|
||||
string id = _id;
|
||||
while ((id.length() % 4) != 0) {
|
||||
id += '\0';
|
||||
}
|
||||
Datagram dc(id);
|
||||
dc.add_fixed_string(_id, (_id.length() + 3) & ~3);
|
||||
|
||||
FltError result = writer.write_record(FO_long_id, dc);
|
||||
if (result != FE_ok) {
|
||||
|
@ -621,7 +621,8 @@ extract_record(FltRecordReader &) {
|
||||
bool FltRecord::
|
||||
extract_ancillary(FltRecordReader &reader) {
|
||||
if (reader.get_opcode() == FO_comment) {
|
||||
_comment = reader.get_iterator().get_remaining_bytes();
|
||||
vector_uchar s = reader.get_iterator().get_remaining_bytes();
|
||||
_comment.assign((const char *)s.data(), strnlen((const char *)s.data(), s.size()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -735,7 +736,7 @@ build_record(FltRecordWriter &) const {
|
||||
FltError FltRecord::
|
||||
write_ancillary(FltRecordWriter &writer) const {
|
||||
if (!_comment.empty()) {
|
||||
Datagram dc(_comment);
|
||||
Datagram dc(_comment.data(), _comment.size());
|
||||
FltError result = writer.write_record(FO_comment, dc);
|
||||
if (result != FE_ok) {
|
||||
return result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user