Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2019-01-10 23:32:29 +01:00
commit ba993aea0d
18 changed files with 236 additions and 44 deletions

View File

@ -8,12 +8,12 @@ Panda3D
Panda3D is a game engine, a framework for 3D rendering and game development for Panda3D is a game engine, a framework for 3D rendering and game development for
Python and C++ programs. Panda3D is open-source and free for any purpose, Python and C++ programs. Panda3D is open-source and free for any purpose,
including commercial ventures, thanks to its including commercial ventures, thanks to its
[liberal license](https://www.panda3d.org/license.php). To learn more about [liberal license](https://www.panda3d.org/license/). To learn more about
Panda3D's capabilities, visit the [gallery](https://www.panda3d.org/gallery.php) Panda3D's capabilities, visit the [gallery](https://www.panda3d.org/gallery/)
and the [feature list](https://www.panda3d.org/features.php). To learn how to and the [feature list](https://www.panda3d.org/features/). To learn how to
use Panda3D, check the [documentation](https://www.panda3d.org/documentation.php) use Panda3D, check the [documentation](https://www.panda3d.org/documentation/)
resources. If you get stuck, ask for help from our active resources. If you get stuck, ask for help from our active
[community](https://www.panda3d.org/community.php). [community](https://discourse.panda3d.org).
Panda3D is licensed under the Modified BSD License. See the LICENSE file for Panda3D is licensed under the Modified BSD License. See the LICENSE file for
more details. more details.
@ -21,7 +21,16 @@ more details.
Installing Panda3D Installing Panda3D
================== ==================
By far, the easiest way to install the latest development build of Panda3D The latest Panda3D SDK can be downloaded from
(this page)[https://www.panda3d.org/download/sdk-1-10-0/].
If you are familiar with installing Python packages, you can use
the following comand:
```bash
pip install panda3d
```
The easiest way to install the latest development build of Panda3D
into an existing Python installation is using the following command: into an existing Python installation is using the following command:
```bash ```bash
@ -31,9 +40,7 @@ pip install --pre --extra-index-url https://archive.panda3d.org/ panda3d
If this command fails, please make sure your version of pip is up-to-date. If this command fails, please make sure your version of pip is up-to-date.
If you prefer to install the full SDK with all tools, the latest development If you prefer to install the full SDK with all tools, the latest development
builds can be obtained from this page: builds can be obtained from (this page)[https://www.panda3d.org/download/].
https://www.panda3d.org/download.php?sdk&version=devel
These are automatically kept up-to-date with the latest GitHub version of Panda. These are automatically kept up-to-date with the latest GitHub version of Panda.
@ -96,7 +103,7 @@ python makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-g
You will probably see some warnings saying that it's unable to find several You will probably see some warnings saying that it's unable to find several
dependency packages. You should determine which ones you want to include in dependency packages. You should determine which ones you want to include in
your build and install the respective development packages. You may visit your build and install the respective development packages. You may visit
[this manual page](https://www.panda3d.org/manual/index.php/Dependencies) [this manual page](https://www.panda3d.org/manual/?title=Third-party_dependencies_and_license_info)
for an overview of the various dependencies. for an overview of the various dependencies.
If you are on Ubuntu, this command should cover the most frequently If you are on Ubuntu, this command should cover the most frequently

View File

@ -26,6 +26,9 @@ get_string() {
// First, get the length of the string // First, get the length of the string
size_t size = get_uint16(); size_t size = get_uint16();
if (size == 0) {
return string();
}
char *buffer = (char *)alloca(size); char *buffer = (char *)alloca(size);
_in->read(buffer, size); _in->read(buffer, size);
@ -42,6 +45,9 @@ get_string32() {
// First, get the length of the string // First, get the length of the string
size_t size = get_uint32(); size_t size = get_uint32();
if (size == 0) {
return string();
}
char *buffer = (char *)PANDA_MALLOC_ARRAY(size); char *buffer = (char *)PANDA_MALLOC_ARRAY(size);
_in->read(buffer, size); _in->read(buffer, size);
@ -60,7 +66,7 @@ get_z_string() {
string result; string result;
int ch = _in->get(); int ch = _in->get();
while (!_in->eof() && !_in->fail() && ch != '\0') { while (!_in->fail() && ch != EOF && ch != '\0') {
result += (char)ch; result += (char)ch;
ch = _in->get(); ch = _in->get();
} }
@ -76,6 +82,10 @@ string StreamReader::
get_fixed_string(size_t size) { get_fixed_string(size_t size) {
nassertr(!_in->eof() && !_in->fail(), string()); nassertr(!_in->eof() && !_in->fail(), string());
if (size == 0) {
return string();
}
char *buffer = (char *)alloca(size); char *buffer = (char *)alloca(size);
_in->read(buffer, size); _in->read(buffer, size);
size_t read_bytes = _in->gcount(); size_t read_bytes = _in->gcount();
@ -90,8 +100,9 @@ get_fixed_string(size_t size) {
*/ */
void StreamReader:: void StreamReader::
skip_bytes(size_t size) { skip_bytes(size_t size) {
nassertv(!_in->eof() && !_in->fail()); nassertv(!_in->fail());
nassertv((int)size >= 0); nassertv((int)size >= 0);
nassertv(size == 0 || !_in->eof());
while (size > 0) { while (size > 0) {
_in->get(); _in->get();
@ -145,9 +156,9 @@ string StreamReader::
readline() { readline() {
string line; string line;
int ch = _in->get(); int ch = _in->get();
while (!_in->eof() && !_in->fail()) { while (ch != EOF && !_in->fail()) {
line += (char)ch; line += (char)ch;
if (ch == '\n') { if (ch == '\n' || _in->eof()) {
// Here's the newline character. // Here's the newline character.
return line; return line;
} }

View File

@ -45,9 +45,9 @@ readline() {
std::string line; std::string line;
int ch = in->get(); int ch = in->get();
while (!in->eof() && !in->fail()) { while (ch != EOF && !in->fail()) {
line += ch; line += ch;
if (ch == '\n') { if (ch == '\n' || in->eof()) {
// Here's the newline character. // Here's the newline character.
break; break;
} }

View File

@ -526,11 +526,6 @@ def makewheel(version, output_dir, platform=None):
# Update relevant METADATA entries # Update relevant METADATA entries
METADATA['version'] = version METADATA['version'] = version
version_classifiers = [
"Programming Language :: Python :: {0}".format(*sys.version_info),
"Programming Language :: Python :: {0}.{1}".format(*sys.version_info),
]
METADATA['classifiers'].extend(version_classifiers)
# Build out the metadata # Build out the metadata
details = METADATA["extensions"]["python.details"] details = METADATA["extensions"]["python.details"]

View File

@ -183,7 +183,7 @@ decompress(const Filename &source_file) {
return false; return false;
int ch = _decompress->get(); int ch = _decompress->get();
while (!_decompress->eof() && !_decompress->fail()) { while (ch != EOF && !_decompress->fail()) {
_dest->put(ch); _dest->put(ch);
ch = _decompress->get(); ch = _decompress->get();
} }
@ -207,7 +207,7 @@ decompress(Ramfile &source_and_dest_file) {
IDecompressStream decompress(&source, false); IDecompressStream decompress(&source, false);
int ch = decompress.get(); int ch = decompress.get();
while (!decompress.eof() && !decompress.fail()) { while (ch != EOF && !decompress.fail()) {
dest.put(ch); dest.put(ch);
ch = decompress.get(); ch = decompress.get();
} }

View File

@ -66,7 +66,7 @@ input(std::istream &in) {
// Scan the tag, up to but not including the closing paren. // Scan the tag, up to but not including the closing paren.
std::string tag; std::string tag;
in >> ch; in >> ch;
while (!in.fail() && !in.eof() && ch != ')') { while (!in.fail() && ch != EOF && ch != ')') {
tag += ch; tag += ch;
// We want to include embedded whitespace, so we use get(). // We want to include embedded whitespace, so we use get().
ch = in.get(); ch = in.get();
@ -81,7 +81,7 @@ input(std::istream &in) {
// Scan the date, up to but not including the closing bracket. // Scan the date, up to but not including the closing bracket.
if (ch != ']') { if (ch != ']') {
std::string date; std::string date;
while (!in.fail() && !in.eof() && ch != ']') { while (!in.fail() && ch != EOF && ch != ']') {
date += ch; date += ch;
ch = in.get(); ch = in.get();
} }

View File

@ -2762,7 +2762,7 @@ bool HTTPChannel::
server_getline(string &str) { server_getline(string &str) {
nassertr(!_source.is_null(), false); nassertr(!_source.is_null(), false);
int ch = (*_source)->get(); int ch = (*_source)->get();
while (!(*_source)->eof() && !(*_source)->fail()) { while (ch != EOF && !(*_source)->fail()) {
switch (ch) { switch (ch) {
case '\n': case '\n':
// end-of-line character, we're done. // end-of-line character, we're done.
@ -2850,7 +2850,7 @@ bool HTTPChannel::
server_get(string &str, size_t num_bytes) { server_get(string &str, size_t num_bytes) {
nassertr(!_source.is_null(), false); nassertr(!_source.is_null(), false);
int ch = (*_source)->get(); int ch = (*_source)->get();
while (!(*_source)->eof() && !(*_source)->fail()) { while (ch != EOF && !(*_source)->fail()) {
_working_get += (char)ch; _working_get += (char)ch;
if (_working_get.length() >= num_bytes) { if (_working_get.length() >= num_bytes) {
str = _working_get; str = _working_get;

View File

@ -279,7 +279,7 @@ input(std::istream &in) {
string date; string date;
ch = in.get(); ch = in.get();
while (!in.fail() && !in.eof() && ch != '"') { while (!in.fail() && ch != EOF && ch != '"') {
date += ch; date += ch;
ch = in.get(); ch = in.get();
} }

View File

@ -56,7 +56,7 @@ do_receive_datagram(Datagram &dg) {
// Read the first two bytes: the datagram length. // Read the first two bytes: the datagram length.
while ((int)_data_so_far.size() < _tcp_header_size) { while ((int)_data_so_far.size() < _tcp_header_size) {
int ch = _istream->get(); int ch = _istream->get();
if (_istream->eof() || _istream->fail()) { if (ch == EOF || _istream->fail()) {
_istream->clear(); _istream->clear();
return false; return false;
} }

View File

@ -50,7 +50,7 @@ input_hex(istream &in) {
size_t i = 0; size_t i = 0;
int ch = in.get(); int ch = in.get();
while (!in.eof() && !in.fail() && isxdigit(ch)) { while (ch != EOF && !in.fail() && isxdigit(ch)) {
if (i < 32) { if (i < 32) {
buffer[i] = (char)ch; buffer[i] = (char)ch;
} }
@ -63,7 +63,7 @@ input_hex(istream &in) {
return; return;
} }
if (!in.eof()) { if (ch != EOF) {
in.putback((char)ch); in.putback((char)ch);
} else { } else {
in.clear(); in.clear();

View File

@ -108,7 +108,7 @@ main(int argc, char *argv[]) {
int col = 0; int col = 0;
unsigned int ch; unsigned int ch;
ch = in.get(); ch = in.get();
while (!in.fail() && !in.eof()) { while (!in.fail() && ch != EOF) {
if (col == 0) { if (col == 0) {
out << "\n "; out << "\n ";
} else if (col == col_width) { } else if (col == col_width) {

View File

@ -1785,8 +1785,7 @@ compare_subfile(int index, const Filename &filename) {
in2.seekg(0); in2.seekg(0);
int byte1 = in1->get(); int byte1 = in1->get();
int byte2 = in2.get(); int byte2 = in2.get();
while (!in1->fail() && !in1->eof() && while (!in1->fail() && !in2.fail()) {
!in2.fail() && !in2.eof()) {
if (byte1 != byte2) { if (byte1 != byte2) {
close_read_subfile(in1); close_read_subfile(in1);
return false; return false;
@ -2497,7 +2496,7 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
StreamReader reader(read); StreamReader reader(read);
streampos next_index = multifile->word_to_streampos(reader.get_uint32()); streampos next_index = multifile->word_to_streampos(reader.get_uint32());
if (read.eof() || read.fail()) { if (read.fail()) {
_flags |= SF_index_invalid; _flags |= SF_index_invalid;
return 0; return 0;
} }
@ -2529,7 +2528,7 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
} }
size_t name_length = reader.get_uint16(); size_t name_length = reader.get_uint16();
if (read.eof() || read.fail()) { if (read.fail()) {
_flags |= SF_index_invalid; _flags |= SF_index_invalid;
return 0; return 0;
} }
@ -2543,7 +2542,7 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
_name = string(name_buffer, name_length); _name = string(name_buffer, name_length);
PANDA_FREE_ARRAY(name_buffer); PANDA_FREE_ARRAY(name_buffer);
if (read.eof() || read.fail()) { if (read.fail()) {
_flags |= SF_index_invalid; _flags |= SF_index_invalid;
return 0; return 0;
} }

View File

@ -4158,7 +4158,7 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
cdata->_num_mipmap_levels_read = cdata->_ram_images.size(); cdata->_num_mipmap_levels_read = cdata->_ram_images.size();
} }
if (in.fail() || in.eof()) { if (in.fail()) {
gobj_cat.error() gobj_cat.error()
<< filename << ": truncated DDS file.\n"; << filename << ": truncated DDS file.\n";
return false; return false;
@ -4924,7 +4924,7 @@ do_read_ktx(CData *cdata, istream &in, const string &filename, bool header_only)
} }
} }
if (in.fail() || in.eof()) { if (in.fail()) {
gobj_cat.error() gobj_cat.error()
<< filename << ": truncated KTX file.\n"; << filename << ": truncated KTX file.\n";
return false; return false;

View File

@ -120,7 +120,7 @@ int
pm_readbigshort(istream *in, short *sP) { pm_readbigshort(istream *in, short *sP) {
StreamReader reader(in, false); StreamReader reader(in, false);
*sP = reader.get_be_int16(); *sP = reader.get_be_int16();
return (!in->eof() && !in->fail()) ? 0 : -1; return (!in->fail()) ? 0 : -1;
} }
int int
@ -134,7 +134,7 @@ int
pm_readbiglong(istream *in, long *lP) { pm_readbiglong(istream *in, long *lP) {
StreamReader reader(in, false); StreamReader reader(in, false);
*lP = reader.get_be_int32(); *lP = reader.get_be_int32();
return (!in->eof() && !in->fail()) ? 0 : -1; return (!in->fail()) ? 0 : -1;
} }
int int
@ -148,7 +148,7 @@ int
pm_readlittleshort(istream *in, short *sP) { pm_readlittleshort(istream *in, short *sP) {
StreamReader reader(in, false); StreamReader reader(in, false);
*sP = reader.get_int16(); *sP = reader.get_int16();
return (!in->eof() && !in->fail()) ? 0 : -1; return (!in->fail()) ? 0 : -1;
} }
int int
@ -162,7 +162,7 @@ int
pm_readlittlelong(istream *in, long *lP) { pm_readlittlelong(istream *in, long *lP) {
StreamReader reader(in, false); StreamReader reader(in, false);
*lP = reader.get_int32(); *lP = reader.get_int32();
return (!in->eof() && !in->fail()) ? 0 : -1; return (!in->fail()) ? 0 : -1;
} }
int int

View File

@ -101,7 +101,7 @@ run() {
int col = 0; int col = 0;
unsigned int ch; unsigned int ch;
ch = in.get(); ch = in.get();
while (!in.fail() && !in.eof()) { while (!in.fail() && ch != EOF) {
if (col == 0) { if (col == 0) {
out << "\n "; out << "\n ";
} else if (col == col_width) { } else if (col == col_width) {

View File

@ -13,10 +13,21 @@ classifiers =
Operating System :: OS Independent Operating System :: OS Independent
Programming Language :: C++ Programming Language :: C++
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: Implementation :: CPython
Topic :: Games/Entertainment Topic :: Games/Entertainment
Topic :: Multimedia Topic :: Multimedia
Topic :: Multimedia :: Graphics Topic :: Multimedia :: Graphics
Topic :: Multimedia :: Graphics :: 3D Rendering Topic :: Multimedia :: Graphics :: 3D Rendering
Topic :: Software Development :: Libraries
Topic :: Software Development :: Libraries :: Application Frameworks
Topic :: Software Development :: Libraries :: Python Modules
author = Panda3D Team author = Panda3D Team
author_email = etc-panda3d@lists.andrew.cmu.edu author_email = etc-panda3d@lists.andrew.cmu.edu

View File

@ -0,0 +1,12 @@
from panda3d.core import Multifile, StringStream, IStreamWrapper
def test_multifile_read_empty():
stream = StringStream(b'pmf\x00\n\r\x01\x00\x01\x00\x01\x00\x00\x00\xdb\x9d7\\\x00\x00\x00\x00')
wrapper = IStreamWrapper(stream)
m = Multifile()
assert m.open_read(wrapper)
assert m.is_read_valid()
assert m.get_num_subfiles() == 0
m.close()

View File

@ -0,0 +1,157 @@
from panda3d.core import StreamReader, StringStream
import pytest
def test_streamreader_string():
# Empty string
stream = StringStream(b'\x00\x00')
reader = StreamReader(stream, False)
assert reader.get_string() == ''
# String size but no string contents
stream = StringStream(b'\x01\x00')
reader = StreamReader(stream, False)
assert reader.get_string() == ''
# String of length 1
stream = StringStream(b'\x01\x00A')
reader = StreamReader(stream, False)
assert reader.get_string() == 'A'
# String with excess data
stream = StringStream(b'\x01\x00AB')
reader = StreamReader(stream, False)
assert reader.get_string() == 'A'
# EOF before end of string
stream = StringStream(b'\x03\x00AB')
reader = StreamReader(stream, False)
assert reader.get_string() == 'AB'
# Preserves null bytes
stream = StringStream(b'\x02\x00\x00\x00')
reader = StreamReader(stream, False)
assert reader.get_string() == '\x00\x00'
def test_streamreader_string32():
# Empty string
stream = StringStream(b'\x00\x00\x00\x00')
reader = StreamReader(stream, False)
assert reader.get_string32() == ''
# String size but no string contents
stream = StringStream(b'\x01\x00\x00\x00')
reader = StreamReader(stream, False)
assert reader.get_string32() == ''
# String of length 1
stream = StringStream(b'\x01\x00\x00\x00A')
reader = StreamReader(stream, False)
assert reader.get_string32() == 'A'
# String with excess data
stream = StringStream(b'\x01\x00\x00\x00AB')
reader = StreamReader(stream, False)
assert reader.get_string32() == 'A'
# EOF before end of string
stream = StringStream(b'\x04\x00\x00\x00AB')
reader = StreamReader(stream, False)
assert reader.get_string32() == 'AB'
# Preserves null bytes
stream = StringStream(b'\x02\x00\x00\x00\x00\x00')
reader = StreamReader(stream, False)
assert reader.get_string32() == '\x00\x00'
def test_streamreader_z_string():
# Empty stream
stream = StringStream(b'')
reader = StreamReader(stream, False)
assert reader.get_z_string() == ''
# Empty string
stream = StringStream(b'\x00')
reader = StreamReader(stream, False)
assert reader.get_z_string() == ''
# String of length 1
stream = StringStream(b'A\x00')
reader = StreamReader(stream, False)
assert reader.get_z_string() == 'A'
# String with excess data
stream = StringStream(b'ABC\x00AB')
reader = StreamReader(stream, False)
assert reader.get_z_string() == 'ABC'
# EOF before end of string
stream = StringStream(b'ABC')
reader = StreamReader(stream, False)
assert reader.get_z_string() == 'ABC'
def test_streamreader_fixed_string():
# Zero-length string
stream = StringStream(b'ABC')
reader = StreamReader(stream, False)
assert reader.get_fixed_string(0) == ''
# Empty stream
stream = StringStream(b'')
reader = StreamReader(stream, False)
assert reader.get_fixed_string(1) == ''
# Empty string
stream = StringStream(b'\x00')
reader = StreamReader(stream, False)
assert reader.get_fixed_string(1) == ''
# String of length 1
stream = StringStream(b'A')
reader = StreamReader(stream, False)
assert reader.get_fixed_string(1) == 'A'
# String of length 1, excess data
stream = StringStream(b'ABC\x00')
reader = StreamReader(stream, False)
assert reader.get_fixed_string(1) == 'A'
# EOF before end of string
stream = StringStream(b'AB')
reader = StreamReader(stream, False)
assert reader.get_fixed_string(4) == 'AB'
def test_streamreader_readline():
# Empty stream
stream = StringStream(b'')
reader = StreamReader(stream, False)
assert reader.readline() == b''
assert reader.readline() == b''
# Single line without newline
stream = StringStream(b'A')
reader = StreamReader(stream, False)
assert reader.readline() == b'A'
assert reader.readline() == b''
# Single newline
stream = StringStream(b'\n')
reader = StreamReader(stream, False)
assert reader.readline() == b'\n'
assert reader.readline() == b''
# Line with text followed by empty line
stream = StringStream(b'A\n\n')
reader = StreamReader(stream, False)
assert reader.readline() == b'A\n'
assert reader.readline() == b'\n'
assert reader.readline() == b''
# Preserve null byte
stream = StringStream(b'\x00\x00')
reader = StreamReader(stream, False)
assert reader.readline() == b'\x00\x00'