mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
use multifiles instead of tarfiles
This commit is contained in:
parent
9e7337557a
commit
7d2a154bf5
@ -18,6 +18,7 @@
|
|||||||
p3dFileDownload.h p3dFileDownload.I \
|
p3dFileDownload.h p3dFileDownload.I \
|
||||||
p3dInstance.h p3dInstance.I \
|
p3dInstance.h p3dInstance.I \
|
||||||
p3dInstanceManager.h p3dInstanceManager.I \
|
p3dInstanceManager.h p3dInstanceManager.I \
|
||||||
|
p3dMultifileReader.h p3dMultifileReader.I \
|
||||||
p3dPackage.h p3dPackage.I \
|
p3dPackage.h p3dPackage.I \
|
||||||
p3dSession.h p3dSession.I
|
p3dSession.h p3dSession.I
|
||||||
|
|
||||||
@ -27,6 +28,7 @@
|
|||||||
p3dFileDownload.cxx \
|
p3dFileDownload.cxx \
|
||||||
p3dInstance.cxx \
|
p3dInstance.cxx \
|
||||||
p3dInstanceManager.cxx \
|
p3dInstanceManager.cxx \
|
||||||
|
p3dMultifileReader.cxx \
|
||||||
p3dPackage.cxx \
|
p3dPackage.cxx \
|
||||||
p3dSession.cxx
|
p3dSession.cxx
|
||||||
|
|
||||||
|
@ -27,10 +27,7 @@ Options:
|
|||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
import os
|
import os
|
||||||
import tarfile
|
import zlib
|
||||||
import gzip
|
|
||||||
import stat
|
|
||||||
import md5
|
|
||||||
|
|
||||||
import direct
|
import direct
|
||||||
from pandac.PandaModules import *
|
from pandac.PandaModules import *
|
||||||
@ -42,25 +39,15 @@ class FileSpec:
|
|||||||
def __init__(self, filename, pathname):
|
def __init__(self, filename, pathname):
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.pathname = pathname
|
self.pathname = pathname
|
||||||
self.size = 0
|
|
||||||
self.timestamp = 0
|
|
||||||
self.hash = None
|
|
||||||
|
|
||||||
s = os.stat(self.pathname)
|
self.size = pathname.getFileSize()
|
||||||
self.size = s[stat.ST_SIZE]
|
self.timestamp = pathname.getTimestamp()
|
||||||
self.timestamp = s[stat.ST_MTIME]
|
|
||||||
|
|
||||||
m = md5.new()
|
hv = HashVal()
|
||||||
f = open(self.pathname, 'rb')
|
hv.hashFile(pathname)
|
||||||
data = f.read(4096)
|
self.hash = hv.asHex()
|
||||||
while data:
|
|
||||||
m.update(data)
|
|
||||||
data = f.read(4096)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
self.hash = m.hexdigest()
|
def getParams(self):
|
||||||
|
|
||||||
def get_params(self):
|
|
||||||
return 'filename="%s" size=%s timestamp=%s hash="%s"' % (
|
return 'filename="%s" size=%s timestamp=%s hash="%s"' % (
|
||||||
self.filename, self.size, self.timestamp, self.hash)
|
self.filename, self.size, self.timestamp, self.hash)
|
||||||
|
|
||||||
@ -85,9 +72,11 @@ class PackageMaker:
|
|||||||
|
|
||||||
self.cleanDir(self.stageDir)
|
self.cleanDir(self.stageDir)
|
||||||
|
|
||||||
uncompressedArchiveBasename = '%s.tar' % (self.packageFullname)
|
uncompressedArchiveBasename = '%s.mf' % (self.packageFullname)
|
||||||
uncompressedArchivePathname = os.path.join(self.stageDir, uncompressedArchiveBasename)
|
uncompressedArchivePathname = Filename(self.stageDir, uncompressedArchiveBasename)
|
||||||
self.archive = tarfile.open(uncompressedArchivePathname, 'w')
|
self.archive = Multifile()
|
||||||
|
if not self.archive.openWrite(uncompressedArchivePathname):
|
||||||
|
raise IOError, "Couldn't open %s for writing" % (uncompressedArchivePathname)
|
||||||
|
|
||||||
self.components = []
|
self.components = []
|
||||||
|
|
||||||
@ -96,34 +85,37 @@ class PackageMaker:
|
|||||||
|
|
||||||
uncompressedArchive = FileSpec(uncompressedArchiveBasename, uncompressedArchivePathname)
|
uncompressedArchive = FileSpec(uncompressedArchiveBasename, uncompressedArchivePathname)
|
||||||
|
|
||||||
compressedArchiveBasename = '%s.tgz' % (self.packageFullname)
|
compressedArchiveBasename = '%s.mf.pz' % (self.packageFullname)
|
||||||
compressedArchivePathname = os.path.join(self.stageDir, compressedArchiveBasename)
|
compressedArchivePathname = Filename(self.stageDir, compressedArchiveBasename)
|
||||||
|
|
||||||
print "\ncompressing"
|
print "\ncompressing"
|
||||||
f = open(uncompressedArchivePathname, 'rb')
|
|
||||||
gz = gzip.open(compressedArchivePathname, 'w', 9)
|
source = open(uncompressedArchivePathname.toOsSpecific(), 'rb')
|
||||||
data = f.read(4096)
|
target = open(compressedArchivePathname.toOsSpecific(), 'w')
|
||||||
|
z = zlib.compressobj(9)
|
||||||
|
data = source.read(4096)
|
||||||
while data:
|
while data:
|
||||||
gz.write(data)
|
target.write(z.compress(data))
|
||||||
data = f.read(4096)
|
data = source.read(4096)
|
||||||
gz.close()
|
target.write(z.flush())
|
||||||
f.close()
|
target.close()
|
||||||
|
source.close()
|
||||||
|
|
||||||
compressedArchive = FileSpec(compressedArchiveBasename, compressedArchivePathname)
|
compressedArchive = FileSpec(compressedArchiveBasename, compressedArchivePathname)
|
||||||
|
|
||||||
os.unlink(uncompressedArchivePathname)
|
uncompressedArchivePathname.unlink()
|
||||||
|
|
||||||
descFileBasename = '%s.xml' % (self.packageFullname)
|
descFileBasename = '%s.xml' % (self.packageFullname)
|
||||||
descFilePathname = os.path.join(self.stageDir, descFileBasename)
|
descFilePathname = Filename(self.stageDir, descFileBasename)
|
||||||
|
|
||||||
f = open(descFilePathname, 'w')
|
f = open(descFilePathname.toOsSpecific(), 'w')
|
||||||
print >> f, '<?xml version="1.0" ?>'
|
print >> f, '<?xml version="1.0" ?>'
|
||||||
print >> f, ''
|
print >> f, ''
|
||||||
print >> f, '<package name="%s" version="%s">' % (self.packageName, self.packageVersion)
|
print >> f, '<package name="%s" version="%s">' % (self.packageName, self.packageVersion)
|
||||||
print >> f, ' <uncompressed_archive %s />' % (uncompressedArchive.get_params())
|
print >> f, ' <uncompressed_archive %s />' % (uncompressedArchive.getParams())
|
||||||
print >> f, ' <compressed_archive %s />' % (compressedArchive.get_params())
|
print >> f, ' <compressed_archive %s />' % (compressedArchive.getParams())
|
||||||
for file in self.components:
|
for file in self.components:
|
||||||
print >> f, ' <component %s />' % (file.get_params())
|
print >> f, ' <component %s />' % (file.getParams())
|
||||||
print >> f, '</package>'
|
print >> f, '</package>'
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
@ -132,46 +124,41 @@ class PackageMaker:
|
|||||||
""" Remove all the files in the named directory. Does not
|
""" Remove all the files in the named directory. Does not
|
||||||
operate recursively. """
|
operate recursively. """
|
||||||
|
|
||||||
for filename in os.listdir(dirname):
|
for filename in os.listdir(dirname.toOsSpecific()):
|
||||||
pathname = os.path.join(dirname, filename)
|
pathname = Filename(dirname, filename)
|
||||||
try:
|
pathname.unlink()
|
||||||
os.unlink(pathname)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def addComponents(self):
|
def addComponents(self):
|
||||||
""" Walks through all the files in the start directory and
|
""" Walks through all the files in the start directory and
|
||||||
adds them to the archive. Recursively visits
|
adds them to the archive. Recursively visits
|
||||||
sub-directories. """
|
sub-directories. """
|
||||||
|
|
||||||
startDir = self.startDir
|
startDir = self.startDir.toOsSpecific()
|
||||||
if startDir.endswith(os.sep):
|
if startDir.endswith(os.sep):
|
||||||
startDir = startDir[:-1]
|
startDir = startDir[:-1]
|
||||||
elif os.altsep and startDir.endswith(os.altsep):
|
|
||||||
startDir = startDir[:-1]
|
|
||||||
prefix = startDir + os.sep
|
prefix = startDir + os.sep
|
||||||
for dirpath, dirnames, filenames in os.walk(startDir):
|
for dirpath, dirnames, filenames in os.walk(startDir):
|
||||||
if dirpath == startDir:
|
if dirpath == startDir:
|
||||||
localpath = ''
|
localpath = ''
|
||||||
else:
|
else:
|
||||||
assert dirpath.startswith(prefix)
|
assert dirpath.startswith(prefix)
|
||||||
localpath = dirpath[len(prefix):]
|
localpath = dirpath[len(prefix):] + '/'
|
||||||
|
|
||||||
for basename in filenames:
|
for basename in filenames:
|
||||||
file = FileSpec(os.path.join(localpath, basename),
|
file = FileSpec(localpath + basename,
|
||||||
os.path.join(startDir, basename))
|
Filename(self.startDir, basename))
|
||||||
print file.filename
|
print file.filename
|
||||||
self.components.append(file)
|
self.components.append(file)
|
||||||
self.archive.add(file.pathname, file.filename, recursive = False)
|
self.archive.addSubfile(file.filename, file.pathname, 0)
|
||||||
|
|
||||||
def makePackage(args):
|
def makePackage(args):
|
||||||
opts, args = getopt.getopt(args, 'd:p:v:h')
|
opts, args = getopt.getopt(args, 'd:p:v:h')
|
||||||
|
|
||||||
pm = PackageMaker()
|
pm = PackageMaker()
|
||||||
pm.startDir = '.'
|
pm.startDir = Filename('.')
|
||||||
for option, value in opts:
|
for option, value in opts:
|
||||||
if option == '-d':
|
if option == '-d':
|
||||||
pm.stageDir = Filename.fromOsSpecific(value).toOsSpecific()
|
pm.stageDir = Filename.fromOsSpecific(value)
|
||||||
elif option == '-p':
|
elif option == '-p':
|
||||||
pm.packageName = value
|
pm.packageName = value
|
||||||
elif option == '-v':
|
elif option == '-v':
|
||||||
|
40
direct/src/plugin/p3dMultifileReader.I
Normal file
40
direct/src/plugin/p3dMultifileReader.I
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Filename: p3dMultifileReader.I
|
||||||
|
// Created by: drose (15Jun09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMultifileReader::read_uint16
|
||||||
|
// Access: Private
|
||||||
|
// Description: Extracts an unsigned short from the file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline unsigned int P3DMultifileReader::
|
||||||
|
read_uint16() {
|
||||||
|
unsigned int a = _in.get();
|
||||||
|
unsigned int b = _in.get();
|
||||||
|
return (b << 8) | a;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMultifileReader::read_uint32
|
||||||
|
// Access: Private
|
||||||
|
// Description: Extracts an unsigned long from the file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline unsigned int P3DMultifileReader::
|
||||||
|
read_uint32() {
|
||||||
|
unsigned int a = _in.get();
|
||||||
|
unsigned int b = _in.get();
|
||||||
|
unsigned int c = _in.get();
|
||||||
|
unsigned int d = _in.get();
|
||||||
|
return (d << 24) | (c << 16) | (b << 8) | a;
|
||||||
|
}
|
162
direct/src/plugin/p3dMultifileReader.cxx
Normal file
162
direct/src/plugin/p3dMultifileReader.cxx
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// Filename: p3dMultifileReader.cxx
|
||||||
|
// Created by: drose (15Jun09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "p3dMultifileReader.h"
|
||||||
|
|
||||||
|
// This sequence of bytes begins each Multifile to identify it as a
|
||||||
|
// Multifile.
|
||||||
|
const char P3DMultifileReader::_header[] = "pmf\0\n\r";
|
||||||
|
const size_t P3DMultifileReader::_header_size = 6;
|
||||||
|
|
||||||
|
const int P3DMultifileReader::_current_major_ver = 1;
|
||||||
|
const int P3DMultifileReader::_current_minor_ver = 1;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMultifileReader::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
P3DMultifileReader::
|
||||||
|
P3DMultifileReader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMultifileReader::extract
|
||||||
|
// Access: Public
|
||||||
|
// Description: Reads the named multifile, and extracts all files
|
||||||
|
// within it to the indicated directory. Returns true
|
||||||
|
// on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DMultifileReader::
|
||||||
|
extract(const string &pathname, const string &to_dir) {
|
||||||
|
_subfiles.clear();
|
||||||
|
|
||||||
|
_in.open(pathname.c_str(), ios::in | ios::binary);
|
||||||
|
if (!_in) {
|
||||||
|
cerr << "Couldn't open " << pathname << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < _header_size; ++i) {
|
||||||
|
int ch = _in.get();
|
||||||
|
if (ch != _header[i]) {
|
||||||
|
cerr << "Failed header check: " << pathname << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int major = read_uint16();
|
||||||
|
unsigned int minor = read_uint16();
|
||||||
|
if (major != _current_major_ver || minor != _current_minor_ver) {
|
||||||
|
cerr << "Incompatible multifile version: " << pathname << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int scale = read_uint32();
|
||||||
|
if (scale != 1) {
|
||||||
|
cerr << "Unsupported scale factor in " << pathname << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't care about the timestamp.
|
||||||
|
read_uint32();
|
||||||
|
|
||||||
|
if (!read_index()) {
|
||||||
|
cerr << "Error reading multifile index\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now walk through all of the files.
|
||||||
|
Subfiles::iterator si;
|
||||||
|
for (si = _subfiles.begin(); si != _subfiles.end(); ++si) {
|
||||||
|
const Subfile &s = (*si);
|
||||||
|
cerr << s._filename << "\n";
|
||||||
|
|
||||||
|
string output_pathname = to_dir + "/" + s._filename;
|
||||||
|
ofstream out(output_pathname.c_str(), ios::out | ios::trunc | ios::binary);
|
||||||
|
if (!out) {
|
||||||
|
cerr << "Unable to create " << output_pathname << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_in.seekg(s._start);
|
||||||
|
|
||||||
|
static const size_t buffer_size = 1024;
|
||||||
|
char buffer[buffer_size];
|
||||||
|
|
||||||
|
size_t remaining_data = s._length;
|
||||||
|
_in.read(buffer, min(buffer_size, remaining_data));
|
||||||
|
size_t count = _in.gcount();
|
||||||
|
while (count != 0) {
|
||||||
|
remaining_data -= count;
|
||||||
|
out.write(buffer, count);
|
||||||
|
_in.read(buffer, min(buffer_size, remaining_data));
|
||||||
|
count = _in.gcount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining_data != 0) {
|
||||||
|
cerr << "Unable to extract " << s._filename << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMultifileReader::read_index
|
||||||
|
// Access: Public
|
||||||
|
// Description: Assuming the file stream is positioned at the first
|
||||||
|
// record, reads all of the records into the _subfiles
|
||||||
|
// list. Returns true on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DMultifileReader::
|
||||||
|
read_index() {
|
||||||
|
unsigned int next_entry = read_uint32();
|
||||||
|
if (!_in) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (next_entry != 0) {
|
||||||
|
Subfile s;
|
||||||
|
s._start = read_uint32();
|
||||||
|
s._length = read_uint32();
|
||||||
|
unsigned int flags = read_uint16();
|
||||||
|
if (flags != 0) {
|
||||||
|
cerr << "Unsupported per-subfile options in multifile\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
read_uint32();
|
||||||
|
size_t name_length = read_uint16();
|
||||||
|
char *buffer = new char[name_length];
|
||||||
|
_in.read(buffer, name_length);
|
||||||
|
|
||||||
|
// The filenames are xored with 0xff just for fun.
|
||||||
|
for (size_t ni = 0; ni < name_length; ++ni) {
|
||||||
|
buffer[ni] ^= 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
s._filename = string(buffer, name_length);
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
_subfiles.push_back(s);
|
||||||
|
|
||||||
|
_in.seekg(next_entry);
|
||||||
|
next_entry = read_uint32();
|
||||||
|
if (!_in) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
59
direct/src/plugin/p3dMultifileReader.h
Normal file
59
direct/src/plugin/p3dMultifileReader.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Filename: p3dMultifileReader.h
|
||||||
|
// Created by: drose (15Jun09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef P3DMULTIFILEREADER_H
|
||||||
|
#define P3DMULTIFILEREADER_H
|
||||||
|
|
||||||
|
#include "p3d_plugin_common.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : P3DMultifileReader
|
||||||
|
// Description : A way-simple implementation of Panda's multifile
|
||||||
|
// reader. See panda/src/express/multifile.cxx for a
|
||||||
|
// full description of the binary format. This
|
||||||
|
// implementation doesn't support per-subfile
|
||||||
|
// compression or encryption.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class P3DMultifileReader {
|
||||||
|
public:
|
||||||
|
P3DMultifileReader();
|
||||||
|
|
||||||
|
bool extract(const string &pathname, const string &to_dir);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool read_index();
|
||||||
|
inline unsigned int read_uint16();
|
||||||
|
inline unsigned int read_uint32();
|
||||||
|
|
||||||
|
ifstream _in;
|
||||||
|
|
||||||
|
class Subfile {
|
||||||
|
public:
|
||||||
|
string _filename;
|
||||||
|
size_t _start;
|
||||||
|
size_t _length;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef vector<Subfile> Subfiles;
|
||||||
|
Subfiles _subfiles;
|
||||||
|
|
||||||
|
static const char _header[];
|
||||||
|
static const size_t _header_size;
|
||||||
|
static const int _current_major_ver;
|
||||||
|
static const int _current_minor_ver;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "p3dMultifileReader.I"
|
||||||
|
|
||||||
|
#endif
|
@ -47,6 +47,26 @@ get_package_dir() const {
|
|||||||
return _package_dir;
|
return _package_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DPackage::get_package_name
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the name of this package.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline const string &P3DPackage::
|
||||||
|
get_package_name() const {
|
||||||
|
return _package_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DPackage::get_package_version
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the version string of this package.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline const string &P3DPackage::
|
||||||
|
get_package_version() const {
|
||||||
|
return _package_version;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DPackage::decode_hexdigit
|
// Function: P3DPackage::decode_hexdigit
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
#include "p3dPackage.h"
|
#include "p3dPackage.h"
|
||||||
#include "p3dInstanceManager.h"
|
#include "p3dInstanceManager.h"
|
||||||
|
#include "p3dMultifileReader.h"
|
||||||
|
|
||||||
#include "openssl/md5.h"
|
#include "openssl/md5.h"
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
#include "libtar.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -301,8 +301,8 @@ uncompress_archive() {
|
|||||||
string source_pathname = _package_dir + "/" + _compressed_archive._filename;
|
string source_pathname = _package_dir + "/" + _compressed_archive._filename;
|
||||||
string target_pathname = _package_dir + "/" + _uncompressed_archive._filename;
|
string target_pathname = _package_dir + "/" + _uncompressed_archive._filename;
|
||||||
|
|
||||||
gzFile source = gzopen(source_pathname.c_str(), "rb");
|
ifstream source(source_pathname.c_str(), ios::in | ios::binary);
|
||||||
if (source == NULL) {
|
if (!source) {
|
||||||
cerr << "Couldn't open " << source_pathname << "\n";
|
cerr << "Couldn't open " << source_pathname << "\n";
|
||||||
report_done(false);
|
report_done(false);
|
||||||
return;
|
return;
|
||||||
@ -312,38 +312,85 @@ uncompress_archive() {
|
|||||||
if (!target) {
|
if (!target) {
|
||||||
cerr << "Couldn't write to " << target_pathname << "\n";
|
cerr << "Couldn't write to " << target_pathname << "\n";
|
||||||
report_done(false);
|
report_done(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int buffer_size = 1024;
|
z_stream z;
|
||||||
char buffer[buffer_size];
|
z.next_in = Z_NULL;
|
||||||
|
z.avail_in = 0;
|
||||||
|
z.zalloc = Z_NULL;
|
||||||
|
z.zfree = Z_NULL;
|
||||||
|
z.opaque = Z_NULL;
|
||||||
|
z.msg = (char *)"no error message";
|
||||||
|
|
||||||
int count = gzread(source, buffer, buffer_size);
|
int result = inflateInit(&z);
|
||||||
while (count > 0) {
|
if (result < 0) {
|
||||||
target.write(buffer, count);
|
cerr << z.msg << "\n";
|
||||||
count = gzread(source, buffer, buffer_size);
|
report_done(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int decompress_buffer_size = 1024;
|
||||||
|
char decompress_buffer[decompress_buffer_size];
|
||||||
|
static const int write_buffer_size = 1024;
|
||||||
|
char write_buffer[write_buffer_size];
|
||||||
|
|
||||||
|
bool eof = false;
|
||||||
|
int flush = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (z.avail_in == 0 && !eof) {
|
||||||
|
source.read(decompress_buffer, decompress_buffer_size);
|
||||||
|
size_t read_count = source.gcount();
|
||||||
|
eof = (read_count == 0 || source.eof() || source.fail());
|
||||||
|
|
||||||
|
z.next_in = (Bytef *)decompress_buffer;
|
||||||
|
z.avail_in = read_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
z.next_out = (Bytef *)write_buffer;
|
||||||
|
z.avail_out = write_buffer_size;
|
||||||
|
int result = inflate(&z, flush);
|
||||||
|
if (z.avail_out < write_buffer_size) {
|
||||||
|
target.write(write_buffer, write_buffer_size - z.avail_out);
|
||||||
|
if (!target) {
|
||||||
|
cerr << "Couldn't write entire file to " << target_pathname << "\n";
|
||||||
|
report_done(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == Z_STREAM_END) {
|
||||||
|
// Here's the end of the file.
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else if (result == Z_BUF_ERROR && flush == 0) {
|
||||||
|
// We might get this if no progress is possible, for instance if
|
||||||
|
// the input stream is truncated. In this case, tell zlib to
|
||||||
|
// dump everything it's got.
|
||||||
|
flush = Z_FINISH;
|
||||||
|
|
||||||
|
} else if (result < 0) {
|
||||||
|
cerr << z.msg << "\n";
|
||||||
|
inflateEnd(&z);
|
||||||
|
report_done(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count < 0) {
|
result = inflateEnd(&z);
|
||||||
cerr << "gzip error decompressing " << source_pathname << "\n";
|
if (result < 0) {
|
||||||
int errnum;
|
cerr << z.msg << "\n";
|
||||||
cerr << gzerror(source, &errnum) << "\n";
|
|
||||||
gzclose(source);
|
|
||||||
report_done(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gzclose(source);
|
|
||||||
|
|
||||||
if (!target) {
|
|
||||||
cerr << "Couldn't write entire file to " << target_pathname << "\n";
|
|
||||||
report_done(false);
|
report_done(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source.close();
|
||||||
target.close();
|
target.close();
|
||||||
|
|
||||||
if (!_uncompressed_archive.full_verify(_package_dir)) {
|
if (!_uncompressed_archive.full_verify(_package_dir)) {
|
||||||
cerr << "after uncompressing " << target_pathname << ", failed hash check\n";
|
cerr << "after uncompressing " << target_pathname
|
||||||
|
<< ", failed hash check\n";
|
||||||
report_done(false);
|
report_done(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -364,25 +411,14 @@ extract_archive() {
|
|||||||
cerr << "extracting " << _uncompressed_archive._filename << "\n";
|
cerr << "extracting " << _uncompressed_archive._filename << "\n";
|
||||||
|
|
||||||
string source_pathname = _package_dir + "/" + _uncompressed_archive._filename;
|
string source_pathname = _package_dir + "/" + _uncompressed_archive._filename;
|
||||||
|
P3DMultifileReader reader;
|
||||||
TAR *tar = NULL;
|
if (!reader.extract(source_pathname, _package_dir)) {
|
||||||
int result = tar_open
|
cerr << "Failure extracting " << _uncompressed_archive._filename
|
||||||
(&tar, (char *)source_pathname.c_str(), NULL, O_RDONLY, 0666, TAR_VERBOSE);
|
<< "\n";
|
||||||
if (result != 0) {
|
|
||||||
cerr << "Unable to open " << source_pathname << "\n";
|
|
||||||
report_done(false);
|
report_done(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (th_read(tar) == 0) {
|
|
||||||
string basename = th_get_pathname(tar);
|
|
||||||
cerr << basename << "\n";
|
|
||||||
string pathname = _package_dir + "/" + basename;
|
|
||||||
tar_extract_file(tar, (char *)pathname.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
tar_close(tar);
|
|
||||||
|
|
||||||
cerr << "done extracting\n";
|
cerr << "done extracting\n";
|
||||||
report_done(true);
|
report_done(true);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ public:
|
|||||||
inline bool get_ready() const;
|
inline bool get_ready() const;
|
||||||
inline bool get_failed() const;
|
inline bool get_failed() const;
|
||||||
inline const string &get_package_dir() const;
|
inline const string &get_package_dir() const;
|
||||||
|
inline const string &get_package_name() const;
|
||||||
|
inline const string &get_package_version() const;
|
||||||
|
|
||||||
void set_callback(Callback *callback);
|
void set_callback(Callback *callback);
|
||||||
void cancel_callback(Callback *callback);
|
void cancel_callback(Callback *callback);
|
||||||
|
@ -649,7 +649,12 @@ package_ready(P3DPackage *package, bool success) {
|
|||||||
if (this == _session->_panda3d_callback) {
|
if (this == _session->_panda3d_callback) {
|
||||||
_session->_panda3d_callback = NULL;
|
_session->_panda3d_callback = NULL;
|
||||||
if (package == _session->_panda3d) {
|
if (package == _session->_panda3d) {
|
||||||
_session->start_p3dpython();
|
if (success) {
|
||||||
|
_session->start_p3dpython();
|
||||||
|
} else {
|
||||||
|
cerr << "Failed to install " << package->get_package_name()
|
||||||
|
<< "_" << package->get_package_version() << "\n";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cerr << "Unexpected panda3d package: " << package << "\n";
|
cerr << "Unexpected panda3d package: " << package << "\n";
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
#include "p3dFileDownload.cxx"
|
#include "p3dFileDownload.cxx"
|
||||||
#include "p3dInstance.cxx"
|
#include "p3dInstance.cxx"
|
||||||
#include "p3dInstanceManager.cxx"
|
#include "p3dInstanceManager.cxx"
|
||||||
|
#include "p3dMultifileReader.cxx"
|
||||||
#include "p3dPackage.cxx"
|
#include "p3dPackage.cxx"
|
||||||
#include "p3dSession.cxx"
|
#include "p3dSession.cxx"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user