[Scummvm-cvs-logs] SF.net SVN: scummvm:[47997] scummvm/trunk/common
peres001 at users.sourceforge.net
peres001 at users.sourceforge.net
Mon Feb 8 17:15:05 CET 2010
Revision: 47997
http://scummvm.svn.sourceforge.net/scummvm/?rev=47997&view=rev
Author: peres001
Date: 2010-02-08 16:15:05 +0000 (Mon, 08 Feb 2010)
Log Message:
-----------
Made ArjFile use a new ArjArchive class.
Modified Paths:
--------------
scummvm/trunk/common/unarj.cpp
scummvm/trunk/common/unarj.h
Modified: scummvm/trunk/common/unarj.cpp
===================================================================
--- scummvm/trunk/common/unarj.cpp 2010-02-08 16:14:42 UTC (rev 47996)
+++ scummvm/trunk/common/unarj.cpp 2010-02-08 16:15:05 UTC (rev 47997)
@@ -752,68 +752,85 @@
_outstream->write(_ntext, r);
}
+#pragma mark ArjArchive implementation
-#pragma mark ArjFile implementation
+ArjArchive::ArjArchive(const String &filename) : _arjFilename(filename) {
+ Common::File arjFile;
-ArjFile::ArjFile() {
- _fallBack = false;
-}
-
-ArjFile::~ArjFile() {
- for (uint i = 0; i < _headers.size(); i++)
- delete _headers[i];
-}
-
-void ArjFile::registerArchive(const String &filename) {
- int32 first_hdr_pos;
- ArjHeader *header;
- File archiveFile;
-
- if (!archiveFile.open(filename))
+ if (!arjFile.open(_arjFilename)) {
+ warning("ArjArchive::ArjArchive(): Could not find the archive file");
return;
+ }
+
+ int32 firstHeaderOffset = findHeader(arjFile);
- first_hdr_pos = findHeader(archiveFile);
-
- if (first_hdr_pos < 0) {
- warning("ArjFile::registerArchive(): Could not find a valid header");
+ if (firstHeaderOffset < 0) {
+ warning("ArjArchive::ArjArchive(): Could not find a valid header");
return;
}
- archiveFile.seek(first_hdr_pos, SEEK_SET);
- if (readHeader(archiveFile) == NULL)
+ arjFile.seek(firstHeaderOffset, SEEK_SET);
+ if (readHeader(arjFile) == NULL)
return;
- while ((header = readHeader(archiveFile)) != NULL) {
+ ArjHeader *header;
+ while ((header = readHeader(arjFile)) != NULL) {
_headers.push_back(header);
- archiveFile.seek(header->compSize, SEEK_CUR);
+ arjFile.seek(header->compSize, SEEK_CUR);
_fileMap[header->filename] = _headers.size() - 1;
- _archMap[header->filename] = filename;
}
- debug(0, "ArjFile::registerArchive(%s): Located %d files", filename.c_str(), _headers.size());
+ debug(0, "ArjArchive::ArjArchive(%s): Located %d files", filename.c_str(), _headers.size());
}
-SeekableReadStream *ArjFile::open(const Common::String &filename) {
+ArjArchive::~ArjArchive() {
+ for (uint i = 0; i < _headers.size(); i++)
+ delete _headers[i];
+}
- if (_fallBack && SearchMan.hasFile(filename)) {
- return SearchMan.createReadStreamForMember(filename);
+
+bool ArjArchive::hasFile(const String &name) {
+ return _fileMap.contains(name);
+}
+
+int ArjArchive::listMembers(ArchiveMemberList &list) {
+ int matches = 0;
+
+ Common::Array<ArjHeader *>::iterator it = _headers.begin();
+ for ( ; it != _headers.end(); ++it) {
+ list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember((*it)->filename, this)));
+ matches++;
}
- if (!_fileMap.contains(filename))
+ return matches;
+}
+
+ArchiveMemberPtr ArjArchive::getMember(const String &name) {
+ if (!hasFile(name))
+ return ArchiveMemberPtr();
+
+ return ArchiveMemberPtr(new GenericArchiveMember(name, this));
+}
+
+SeekableReadStream *ArjArchive::createReadStreamForMember(const String &name) const {
+ if (!_fileMap.contains(name)) {
return 0;
+ }
- ArjHeader *hdr = _headers[_fileMap[filename]];
+ ArjHeader *hdr = _headers[_fileMap[name]];
+ Common::File archiveFile;
+ archiveFile.open(_arjFilename);
+ archiveFile.seek(hdr->pos, SEEK_SET);
+
+
// TODO: It would be good if ArjFile could decompress files in a streaming
// mode, so it would not need to pre-allocate the entire output.
byte *uncompressedData = (byte *)malloc(hdr->origSize);
+ assert(uncompressedData);
- File archiveFile;
- archiveFile.open(_archMap[filename]);
- archiveFile.seek(hdr->pos, SEEK_SET);
-
if (hdr->method == 0) { // store
int32 len = archiveFile.read(uncompressedData, hdr->origSize);
assert(len == hdr->origSize);
@@ -824,8 +841,8 @@
// If reading from archiveFile directly is too slow to be usable,
// maybe the filesystem code should instead wrap its files
// in a BufferedReadStream.
- decoder->_compressed = new BufferedReadStream(&archiveFile, 4096, false);
- decoder->_outstream = new MemoryWriteStream(uncompressedData, hdr->origSize);
+ decoder->_compressed = new Common::BufferedReadStream(&archiveFile, 4096, false);
+ decoder->_outstream = new Common::MemoryWriteStream(uncompressedData, hdr->origSize);
if (hdr->method == 1 || hdr->method == 2 || hdr->method == 3)
decoder->decode(hdr->origSize);
@@ -835,8 +852,29 @@
delete decoder;
}
- return new MemoryReadStream(uncompressedData, hdr->origSize, true);
+ return new Common::MemoryReadStream(uncompressedData, hdr->origSize, true);
}
+#pragma mark ArjFile implementation
+ArjFile::ArjFile() {
+ _fallBack = false;
+}
+
+ArjFile::~ArjFile() {
+}
+
+void ArjFile::registerArchive(const String &filename) {
+ add(filename, new ArjArchive(filename));
+}
+
+SeekableReadStream *ArjFile::open(const Common::String &filename) {
+ if (_fallBack && SearchMan.hasFile(filename)) {
+ return SearchMan.createReadStreamForMember(filename);
+ }
+
+ return createReadStreamForMember(filename);
+}
+
+
} // End of namespace Common
Modified: scummvm/trunk/common/unarj.h
===================================================================
--- scummvm/trunk/common/unarj.h 2010-02-08 16:14:42 UTC (rev 47996)
+++ scummvm/trunk/common/unarj.h 2010-02-08 16:15:05 UTC (rev 47997)
@@ -28,6 +28,7 @@
#include "common/file.h"
#include "common/hash-str.h"
+#include "common/archive.h"
namespace Common {
@@ -35,9 +36,27 @@
typedef HashMap<String, int, IgnoreCase_Hash, IgnoreCase_EqualTo> ArjFilesMap;
+class ArjArchive : public Common::Archive {
+
+ Common::Array<ArjHeader *> _headers;
+ ArjFilesMap _fileMap;
+
+ Common::String _arjFilename;
+
+public:
+ ArjArchive(const String &name);
+ virtual ~ArjArchive();
+
+ // Common::Archive implementation
+ virtual bool hasFile(const String &name);
+ virtual int listMembers(ArchiveMemberList &list);
+ virtual ArchiveMemberPtr getMember(const String &name);
+ virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
+};
+
// TODO: Get rid of this class, by implementing an ArjArchive subclass of Common::Archive.
// Then ArjFile can be substituted by a SearchSet full of ArjArchives plus SearchMan.
-class ArjFile : public NonCopyable {
+class ArjFile : public SearchSet {
public:
ArjFile();
~ArjFile();
@@ -51,9 +70,6 @@
private:
bool _fallBack;
- Array<ArjHeader *> _headers;
- ArjFilesMap _fileMap;
- StringMap _archMap;
};
} // End of namespace Common
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list