From 3f53ccb07c7af9160f7d2b233055328c300ca025 Mon Sep 17 00:00:00 2001 From: Rtch90 Date: Tue, 4 Sep 2012 23:52:05 +0100 Subject: [PATCH] [Add] Starting some file compression work on @KonoM 's request. -- Maybe have it done in a couple days. Be patient! --- Bin/LibD.pro | 4 + src/System/Filesystem/Checksum.cpp | 8 +- .../Filesystem/InputCompressedFileStream.cpp | 105 ++++++++++++++++++ .../Filesystem/InputCompressedFileStream.h | 27 +++++ src/System/Filesystem/InputStreamWrapper.cpp | 22 ++-- src/System/Filesystem/InputStreamWrapper.h | 12 +- 6 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 src/System/Filesystem/InputCompressedFileStream.cpp create mode 100644 src/System/Filesystem/InputCompressedFileStream.h diff --git a/Bin/LibD.pro b/Bin/LibD.pro index e1f46f3..17819f7 100644 --- a/Bin/LibD.pro +++ b/Bin/LibD.pro @@ -38,7 +38,9 @@ HEADERS += ../src/Actor/Player.h \ ../src/System/Debug.h \ ../src/System/ResourceManager.h \ ../src/System/Convert/str2int.h \ + ../src/System/Filesystem/FileTimestampChecker.h \ ../src/System/Convert/ConvertType.h \ + ../src/System/Filesystem/InputCompressedFileStream.h \ ../src/System/Filesystem/InputStream.h \ ../src/System/Filesystem/OutputStream.h \ ../src/System/Filesystem/EmptyBuffer.h \ @@ -102,6 +104,8 @@ SOURCES += ../src/Actor/Player.cpp \ ../src/Sprite/Sprite.cpp \ ../src/System/Debug.cpp \ ../src/System/Convert/str2int.cpp \ + ../src/System/Filesystem/FileTimestampChecker.cpp \ + ../src/System/Filesystem/InputCompressedFileStream.cpp \ ../src/System/Filesystem/InputStream.cpp \ ../src/System/Filesystem/OutputStream.cpp \ ../src/System/Filesystem/FileList.cpp \ diff --git a/src/System/Filesystem/Checksum.cpp b/src/System/Filesystem/Checksum.cpp index bae9d07..d0381a8 100644 --- a/src/System/Filesystem/Checksum.cpp +++ b/src/System/Filesystem/Checksum.cpp @@ -34,17 +34,17 @@ bool Checksum::DoesChecksumAndSizeMatchFile(unsigned int checksum, int filesize, bool Checksum::CountChecksumForFileImpl(unsigned int* checksum, int* filesize, const char* filename) { assert(filename != NULL); - filesystem::FB_FILE* f = filesystem::fb_fopen(filename, "rb"); + filesystem::SC_FILE* f = filesystem::sc_fopen(filename, "rb"); if(f == NULL) { return false; } - int size = filesystem::fb_fsize(f); + int size = filesystem::sc_fsize(f); char* buf = new char[size]; bool success = true; - int got = filesystem::fb_fread(buf, size, 1, f); + int got = filesystem::sc_fread(buf, size, 1, f); if(got != 1) { success = false; } else { @@ -61,7 +61,7 @@ bool Checksum::CountChecksumForFileImpl(unsigned int* checksum, int* filesize, c if(hashmult > 23) hashmult -= 23; } delete [] buf; - filesystem::fb_fclose(f); + filesystem::sc_fclose(f); return success; } } diff --git a/src/System/Filesystem/InputCompressedFileStream.cpp b/src/System/Filesystem/InputCompressedFileStream.cpp new file mode 100644 index 0000000..d9f44b8 --- /dev/null +++ b/src/System/Filesystem/InputCompressedFileStream.cpp @@ -0,0 +1,105 @@ +#include +#include +#include + +#include "../Debug.h" +#include "FileTimestampChecker.h" +#include "InputCompressedFileStream.h" + +namespace saracraft { +namespace filesystem { + +struct InputCompressedFileStreamBufferData { + std::vector buffer; + int readPosition; + int timeValue; + + InputCompressedFileStreamBufferData(const std::string filename) : readPosition(0), timeValue(0) { + + std::ifstream stream(filename.c_str(), std::ios::binary); + if(!stream) + return; + + /*std::filebuf* streamBuffer = stream.rdbuf(); + if(!streamBuffer) + return; + std::streamsize compressedSize = streamBuffer->in_avail() - sizeof(int); */ + + stream.seekg(0, std::ios::end); + std::streamsize compressedSize = stream.tellg(); + compressedSize -= sizeof(int); + stream.seekg(0, std::ios::beg); + + int bytes = 0; + stream.read((char*) &bytes, sizeof(int)); + if(!bytes) + return; + + buffer.resize(bytes); + std::vector compressedBuffer((int)compressedSize); + stream.read(&compressedBuffer[0], compressedSize); + + Bytef* source = (Bytef*)&compressedBuffer[0]; + uLong sourceLength = compressedBuffer.size(); + Bytef* destination = &buffer[0]; + uLong destinationLength = buffer.size(); + + int code = ::uncompress(destination, &destinationLength, source, sourceLength); + (void)code; + //if(code != Z_OK) + // int a = 0; + + timeValue = FileTimestampChecker::GetFileTimestamp(filename.c_str()); + } +}; + +InputCompressedFileStreamBuffer::InputCompressedFileStreamBuffer(const std::string& filename) { + boost::scoped_ptr tempData(new InputCompressedFileStreamBufferData(filename)); + _data.swap(tempData); +} + +InputCompressedFileStreamBuffer::~InputCompressedFileStreamBuffer(void) { + +} + +unsigned char InputCompressedFileStreamBuffer::PopByte(void) { + char byte = 0; + if(!IsEof()) + byte = _data->buffer[_data->readPosition++]; + return byte; +} + +bool InputCompressedFileStreamBuffer::IsEof(void) const { + if(_data->readPosition >= GetSize()) + return true; + return false; +} + +int InputCompressedFileStreamBuffer::GetSize(void) const { + return int(_data->buffer.size()); +} + +void InputCompressedFileStreamBuffer::PopBytes(char* buffer, int bytes) { + int readSize = bytes; + + if(_data->readPosition + readSize > GetSize()) { + readSize = GetSize() - _data->readPosition; + for(int i = readSize; i < bytes; ++i) + buffer[i] = 0; + } + + for(int i = 0; i < readSize; ++i) + buffer[i] = _data->buffer[_data->readPosition++]; +} + +InputStream CreateInputCompressedFileStream(const std::string& filename) { + InputStream inputStream; + boost::shared_ptr inputBuffer(new InputCompressedFileStreamBuffer(filename)); + + inputStream.SetBuffer(inputBuffer); + return inputStream; +} + +} // Namespace filesystem. +} // Namespace saracraft. + diff --git a/src/System/Filesystem/InputCompressedFileStream.h b/src/System/Filesystem/InputCompressedFileStream.h new file mode 100644 index 0000000..1310921 --- /dev/null +++ b/src/System/Filesystem/InputCompressedFileStream.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include "InputStream.h" + +namespace saracraft { +namespace filesystem { + +struct InputCompressedFileStreamBufferData; + +class InputCompressedFileStreamBuffer : public IInputStreamBuffer { + boost::scoped_ptr _data; +public: + InputCompressedFileStreamBuffer(const std::string& filename); + ~InputCompressedFileStreamBuffer(void); + + unsigned char PopByte(void); + bool IsEof(void) const; + int GetSize(void) const; + + void PopBytes(char* buffer, int bytes); +}; + +InputStream CreateInputCompressedFileStream(const std::string& filename); + +} // Namespace filesystem. +} // Namespace saracraft. + diff --git a/src/System/Filesystem/InputStreamWrapper.cpp b/src/System/Filesystem/InputStreamWrapper.cpp index 2bf7684..0f84b66 100644 --- a/src/System/Filesystem/InputStreamWrapper.cpp +++ b/src/System/Filesystem/InputStreamWrapper.cpp @@ -18,19 +18,19 @@ namespace { Tracker tracker; } // Namespace Unamed. -struct FB_FILE { +struct SC_FILE { InputStream stream; - FB_FILE(InputStream& stream_) : stream(stream_) { + SC_FILE(InputStream& stream_) : stream(stream_) { ++openFileAmount; } - ~FB_FILE(void) { + ~SC_FILE(void) { --openFileAmount; } }; -FB_FILE* fb_fopen(const char* filename, const char*) { +SC_FILE* sc_fopen(const char* filename, const char*) { if(!filename) return 0; @@ -41,17 +41,17 @@ FB_FILE* fb_fopen(const char* filename, const char*) { if(stream.IsEof()) return 0; - return new FB_FILE(stream); + return new SC_FILE(stream); } -size_t fb_fread(void* buffer, size_t size, size_t count, FB_FILE* stream) { +size_t sc_fread(void* buffer, size_t size, size_t count, SC_FILE* stream) { if(!stream) { - Debug::logger->message("fb_fread - Attempt to read when no stream is available."); + Debug::logger->message("sc_fread - Attempt to read when no stream is available."); return 0; } if(stream->stream.IsEof()) { - Debug::logger->message("fb_fread - Attempt to read past the end of the file."); + Debug::logger->message("sc_fread - Attempt to read past the end of the file."); } unsigned char* charBuffer = reinterpret_cast (buffer); @@ -60,20 +60,20 @@ size_t fb_fread(void* buffer, size_t size, size_t count, FB_FILE* stream) { return count; } -size_t fb_fsize(FB_FILE* stream) { +size_t sc_fsize(SC_FILE* stream) { if(!stream) return 0; return stream->stream.GetSize(); } -int fb_feof(FB_FILE* stream) { +int sc_feof(SC_FILE* stream) { if(!stream || stream->stream.IsEof()) return 1; return 0; } -int fb_fclose(FB_FILE* stream) { +int sc_fclose(SC_FILE* stream) { delete stream; return 0; } diff --git a/src/System/Filesystem/InputStreamWrapper.h b/src/System/Filesystem/InputStreamWrapper.h index b8a1d61..4ade6ce 100644 --- a/src/System/Filesystem/InputStreamWrapper.h +++ b/src/System/Filesystem/InputStreamWrapper.h @@ -3,13 +3,13 @@ namespace saracraft { namespace filesystem { -struct FB_FILE; +struct SC_FILE; -FB_FILE* fb_fopen(const char* filename, const char*); -size_t fb_fread(void* buffer, size_t size, size_t count, FB_FILE* stream); -size_t fb_fsize(FB_FILE* stream); -int fb_fclose(FB_FILE* stream); -int fb_feof(FB_FILE* stream); +SC_FILE* sc_fopen(const char* filename, const char*); +size_t sc_fread(void* buffer, size_t size, size_t count, SC_FILE* stream); +size_t sc_fsize(SC_FILE* stream); +int sc_fclose(SC_FILE* stream); +int sc_feof(SC_FILE* stream); } // Namespace filesystem. } // Namespace saracraft.