[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