[Remove] WTF was I doing with this filesystem stuff anyway? :/
This commit is contained in:
parent
7bcd594476
commit
2c00325c29
@ -54,21 +54,21 @@
|
||||
</layer>
|
||||
<layer name="Collision" width="50" height="50">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJztl8ESwyAIRJP//+leemA6oIC7BhvejIemlV0QNb2upir3d2TnZeYyyHi5lYHWYsaWc5ha2TpFNFZ0Inn86jCY5SGf7exbK8bMm/xs/darZ3lA1yGSR0ZzpI/cvzvy8PiIxNR8ovaaxxsrDxSM+LP9dSnfIzQ1ndWY6L70ajLy0OqP0rHOCkadGHW3YiPvHQZe/dH6R+Iw8Xiovh5VPEiifrS9m723VkF4qNDj/5AHsi+eXgvpRT47ich6sOu9Yz13vEecmAdDI3IXN03TNE3zHqz3z9GoSOa/cUVOywPVJ5m5qJ5k9XamBitarF5YzaPK+RLVP+n8a5rmnXwA7bUBUA==
|
||||
eJztl8ESwyAIRJP//+leemA6oIC7BhvejIemlV0QNb2upir3d2TnZeYyyHi5lYHWYsaWc5ha2TpFNFZ0Inn86jCY5SGf7exbK8bMm/xs/darZ3lA1yGSR0ZzpI/cvzvy8PiIxNR8ovaaxxsrDxSM+LP9dSnfIzQ1ndWY6L70ajLy0OqP0rHOCkadGHW3YiPvHQZe/dH6R+Iw8Xiovh5VPEiifrS9m723VkF4qNDj/5AHsi+eXgvpRT47ich6sOu9Yz13vEecmAdDI3IXN03TNE3zHqz3z9GoSOa/cUVOywPVJ5m5qJ5k9XamBitarF5YzaPK+RLVP+n8a5rmnXwA7bUBUA==
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup name="Events" width="50" height="50">
|
||||
<object name="NPC!!!" type="NPC" x="544" y="320" width="32" height="32">
|
||||
<properties>
|
||||
<property name="image" value="Player"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object name="Warp to house" type="warp" x="605" y="188" width="34" height="59">
|
||||
<properties>
|
||||
<property name="map" value="../Data/Map/house.tmx"/>
|
||||
<property name="x" value="7"/>
|
||||
<property name="y" value="13"/>
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
</map>
|
||||
</layer>
|
||||
<objectgroup name="Events" width="50" height="50">
|
||||
<object name="NPC!!!" type="NPC" x="544" y="320" width="32" height="32">
|
||||
<properties>
|
||||
<property name="image" value="Player"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object name="Warp to house" type="warp" x="605" y="188" width="34" height="59">
|
||||
<properties>
|
||||
<property name="map" value="../Data/Map/house.tmx"/>
|
||||
<property name="x" value="7"/>
|
||||
<property name="y" value="13"/>
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
</map>
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
bool IsSelected(void) const { return _selected; }
|
||||
void SetSelected(bool selected) { _selected = selected; }
|
||||
bool Triggered(void) const { return _triggered; }
|
||||
bool Triggered(void) const { return _triggered; }
|
||||
|
||||
int GetX(void) { return x; }
|
||||
int GetY(void) { return y; }
|
||||
|
@ -1,71 +0,0 @@
|
||||
#include "Checksum.h"
|
||||
#include "InputStreamWrapper.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
unsigned int Checksum::CountChecksumForFile(const char* filename) {
|
||||
unsigned int chksum = 0;
|
||||
int filesize = 0;
|
||||
bool success = CountChecksumForFileImpl(&chksum, &filesize, filename);
|
||||
if(success) {
|
||||
return chksum;
|
||||
} else {
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Checksum::DoesChecksumAndSizeMatchFile(unsigned int checksum, int filesize, const char* filename) {
|
||||
unsigned int chksum = 0;
|
||||
int size = 0;
|
||||
bool success = CountChecksumForFileImpl(&chksum, &size, filename);
|
||||
if(success) {
|
||||
if(chksum == checksum && filesize == size)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Checksum::CountChecksumForFileImpl(unsigned int* checksum, int* filesize, const char* filename) {
|
||||
assert(filename != NULL);
|
||||
|
||||
filesystem::SC_FILE* f = filesystem::sc_fopen(filename, "rb");
|
||||
if(f == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = filesystem::sc_fsize(f);
|
||||
|
||||
char* buf = new char[size];
|
||||
|
||||
bool success = true;
|
||||
int got = filesystem::sc_fread(buf, size, 1, f);
|
||||
if(got != 1) {
|
||||
success = false;
|
||||
} else {
|
||||
success = true;
|
||||
*filesize = size;
|
||||
unsigned int hashCode = 1327341033;
|
||||
int hashmult = 0;
|
||||
for(int i = 0; i < size; i++) {
|
||||
if((i % 73) == 0)
|
||||
hashCode += (buf[i] << hashmult);
|
||||
else
|
||||
hashCode ^= (buf[i] << hashmult);
|
||||
hashmult+=4;
|
||||
if(hashmult > 23) hashmult -= 23;
|
||||
}
|
||||
delete [] buf;
|
||||
filesystem::sc_fclose(f);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace filesystem.
|
||||
} // End of namespace saracraft.
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class Checksum {
|
||||
public:
|
||||
static unsigned int CountChecksumForFile(const char* filename);
|
||||
static bool DoesChecksumAndSizeMatchFile(unsigned int checksum,
|
||||
int filesize, const char* filename);
|
||||
private:
|
||||
static bool CountChecksumForFileImpl(unsigned int* checksum,
|
||||
int* filesize, const char* filename);
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "InputStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct EmptyBuffer: public IInputStreamBuffer {
|
||||
unsigned char PopByte(void) { return 0; }
|
||||
bool IsEof(void) const { return true; }
|
||||
int GetSize(void) const { return 0; }
|
||||
void PopBytes(char*, int) { }
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,119 +0,0 @@
|
||||
#include <fstream>
|
||||
#include "../Debug.h"
|
||||
#include "InputFileStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct InputFileStreamBufferData {
|
||||
FILE* fp;
|
||||
size_t size;
|
||||
|
||||
InputFileStreamBufferData(const std::string filename) : fp(0), size(0) {
|
||||
fp = fopen(filename.c_str(), "rb");
|
||||
|
||||
#ifdef __UNIX__
|
||||
// Another ugly as hell case sensitive hack.
|
||||
// if anyone finds a nice way to handle this. Please implement it. -- Allanis
|
||||
if(!fp) {
|
||||
std::string filename = filename;
|
||||
for(unsigned int i = 0; i < filename.size(); i++) {
|
||||
if(isupper(filename[i]))
|
||||
filename[i] = tolower(filename[i]);
|
||||
else if(filename[i] == '\\')
|
||||
filename[i] = '/';
|
||||
}
|
||||
fp = fopen(filename.c_str(), "rb");
|
||||
}
|
||||
#endif
|
||||
if(fp) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
}
|
||||
if(!size)
|
||||
Close();
|
||||
}
|
||||
|
||||
~InputFileStreamBufferData(void) {
|
||||
Close();
|
||||
}
|
||||
|
||||
void Close(void) {
|
||||
if(fp) {
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InputFileStreamBuffer::~InputFileStreamBuffer(void) {
|
||||
|
||||
}
|
||||
|
||||
unsigned char InputFileStreamBuffer::PopByte(void) {
|
||||
char byte = 0;
|
||||
if(_data->fp) {
|
||||
int input = fgetc(_data->fp);
|
||||
if(input == EOF)
|
||||
_data->Close();
|
||||
else
|
||||
byte = (char)input;
|
||||
}
|
||||
return byte;
|
||||
}
|
||||
|
||||
bool InputFileStreamBuffer::IsEof(void) const {
|
||||
if(!_data->fp)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int InputFileStreamBuffer::GetSize(void) const {
|
||||
if(!_data->fp)
|
||||
return 0;
|
||||
|
||||
// This could cause maybe about a 2GB limimitation to file size
|
||||
// by casting to int. Feel free to FIXME.
|
||||
// -- Allanis
|
||||
return int(_data->size);
|
||||
}
|
||||
|
||||
void InputFileStreamBuffer::PopBytes(char* buffer, int bytes) {
|
||||
if(!_data->fp) {
|
||||
for(int i = 0; i < bytes; ++i)
|
||||
buffer[i] = 0;
|
||||
} else {
|
||||
//_data->stream.read(buffer, bytes);
|
||||
if(fread(buffer, 1, bytes, _data->fp) != (unsigned)bytes)
|
||||
_data->Close();
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: ffs. This is needed to get some sense into the input stream error reporting.
|
||||
//bool input_file_stream_no_nonexisting_error_message = false;
|
||||
|
||||
//void SetInputStreamErrorReporting(bool logNonExisting) {
|
||||
// input_file_stream_no_nonexisting_error_message = !logNonExisting;
|
||||
//}
|
||||
|
||||
InputStream CreateInputFileStream(const std::string& filename) {
|
||||
|
||||
InputStream inputStream;
|
||||
boost::shared_ptr<InputFileStreamBuffer> inputBuffer(new InputBuffer(filename));
|
||||
// Eh.. No.
|
||||
// TODO: Would need a seperate error check, eof is not the same as the file does not exist..
|
||||
// This would just spam error messages. We don't want that.
|
||||
/*if(!inputBuffer->IsEof()) {
|
||||
if(!input_file_stream_no_nonexisting_error_message) {
|
||||
Debug->logger("CreateInputFileStream - File \"%s\"does not exist or is zero length.", filename.c_str());
|
||||
}
|
||||
}*/
|
||||
inputStream.SetBuffer(inputBuffer);
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,282 +0,0 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "FileList.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
namespace {
|
||||
|
||||
struct Dir;
|
||||
typedef vector<string> StringList;
|
||||
typedef map<string, Dir> DirList;
|
||||
typedef vector<DirList::iterator> IteratorList;
|
||||
|
||||
struct Dir {
|
||||
StringList files;
|
||||
IteratorList subDirs;
|
||||
|
||||
void AddFile(const string& file) {
|
||||
for(unsigned int i = 0; i < files.size(); ++i) {
|
||||
if(file == files[i])
|
||||
return;
|
||||
}
|
||||
files.push_back(file);
|
||||
}
|
||||
};
|
||||
|
||||
void HaxFile(string& str) {
|
||||
for(unsigned int i = 0; i < str.size(); ++i) {
|
||||
if(str[i] == '\\')
|
||||
str[i] = '/';
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertLower(string& str) {
|
||||
for(unsigned int i = 0; i < str.size(); ++i) {
|
||||
str[i] = tolower(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void GetDirPart(const string& file, string& dir) {
|
||||
string::size_type index = file.find_last_of("\\/");
|
||||
if(index == file.npos) {
|
||||
dir = string();
|
||||
return;
|
||||
}
|
||||
dir = file.substr(0, index);
|
||||
}
|
||||
|
||||
int GetDirAmountImpl(const IteratorList& list) {
|
||||
int result = list.size();
|
||||
/*for(IteratorList::const_iterator it = list.begin(); it != list.end(); ++i) {
|
||||
const DirList::const_iterator& i = *it;
|
||||
result += GetDirAmountImpl(i->second.subDirs);
|
||||
}*/
|
||||
return result;
|
||||
}
|
||||
|
||||
int GetDirNameImpl(const IteratorList& list, string& result, int currentIndex, int findIndex) {
|
||||
int original = currentIndex;
|
||||
for(IteratorList::const_iterator it = list.begin(); it != list.end(); ++it) {
|
||||
const DirList::const_iterator& i = *it;
|
||||
if(currentIndex++ == findIndex) {
|
||||
result = i->first;
|
||||
break;
|
||||
}
|
||||
//currentIndex += GetDirNameImpl(i->second.subDirs
|
||||
}
|
||||
return currentIndex - original;
|
||||
}
|
||||
string empty;
|
||||
|
||||
} // Namespace unamed.
|
||||
|
||||
struct FileList::Data {
|
||||
bool caseSensitive;
|
||||
DirList dirs;
|
||||
|
||||
Data(void) : caseSensitive(false) {}
|
||||
|
||||
// Might want to put some directory hierarchy stuff here?
|
||||
|
||||
void AddDir(const string& dir) {
|
||||
DirList::iterator it;
|
||||
if(!FindDir(it, dir)) {
|
||||
dirs[dir] = Dir();
|
||||
FindDir(it, dir);
|
||||
|
||||
// Add a parent to the list.
|
||||
string current = dir;
|
||||
DirList::iterator currentIt = it;
|
||||
|
||||
for(int i = 0; ; ++i) {
|
||||
string parent;
|
||||
GetDirPart(current, parent);
|
||||
if(parent.empty())
|
||||
break;
|
||||
|
||||
bool needAdd = false;
|
||||
|
||||
DirList::iterator parentIt;
|
||||
if(!FindDir(parentIt, parent)) {
|
||||
dirs[parent] = Dir();
|
||||
FindDir(parentIt, parent);
|
||||
needAdd = true;
|
||||
}
|
||||
parentIt->second.subDirs.push_back(currentIt);
|
||||
if(!needAdd)
|
||||
break;
|
||||
current = parent;
|
||||
currentIt = parentIt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FindDir(DirList::iterator& it, const string& dir) {
|
||||
it = dirs.find(dir);
|
||||
if(it == dirs.end())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
FileList::FileList(void) {
|
||||
scoped_ptr<Data> tempData(new Data());
|
||||
_data.swap(tempData);
|
||||
}
|
||||
|
||||
FileList::~FileList(void) {
|
||||
|
||||
}
|
||||
|
||||
void FileList::SetCaseSensitivity(bool enable) {
|
||||
_data->caseSensitive = enable;
|
||||
}
|
||||
|
||||
void FileList::AddDir(const string& dir_) {
|
||||
string dir = dir_;
|
||||
if(!_data->caseSensitive)
|
||||
ConvertLower(dir);
|
||||
|
||||
HaxFile(dir);
|
||||
_data->AddDir(dir);
|
||||
}
|
||||
|
||||
void FileList::AddFile(const string& file_) {
|
||||
string file = file_;
|
||||
if(!_data->caseSensitive)
|
||||
ConvertLower(file);
|
||||
HaxFile(file);
|
||||
|
||||
string dir;
|
||||
GetDirPart(file, dir);
|
||||
_data->AddDir(dir);
|
||||
|
||||
DirList::iterator it;
|
||||
_data->FindDir(it, dir);
|
||||
it->second.AddFile(file);
|
||||
}
|
||||
|
||||
int FileList::GetDirAmount(const string& root_) const {
|
||||
string root = root_;
|
||||
if(!_data->caseSensitive)
|
||||
ConvertLower(root);
|
||||
HaxFile(root);
|
||||
DirList::iterator it;
|
||||
|
||||
if(!_data->FindDir(it, root))
|
||||
return 0;
|
||||
return GetDirAmountImpl(it->second.subDirs);
|
||||
}
|
||||
|
||||
string FileList::GetDirName(const string& root_, int index) const {
|
||||
string root = root_;
|
||||
if(!_data->caseSensitive)
|
||||
ConvertLower(root);
|
||||
|
||||
HaxFile(root);
|
||||
DirList::iterator it;
|
||||
if(!_data->FindDir(it, root))
|
||||
return empty;
|
||||
|
||||
string result;
|
||||
GetDirNameImpl(it->second.subDirs, result, 0, index);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int FileList::GetFileAmount(const string& root_) const {
|
||||
string root = root_;
|
||||
if(!_data->caseSensitive)
|
||||
ConvertLower(root);
|
||||
HaxFile(root);
|
||||
|
||||
DirList::iterator it;
|
||||
if(!_data->FindDir(it, root))
|
||||
return 0;
|
||||
return it->second.files.size();
|
||||
}
|
||||
|
||||
const string& FileList::GetFileName(const string& root_, int index) const {
|
||||
string root = root_;
|
||||
if(!_data->caseSensitive)
|
||||
ConvertLower(root);
|
||||
HaxFile(root);
|
||||
|
||||
DirList::iterator it;
|
||||
if(!_data->FindDir(it, root))
|
||||
return empty;
|
||||
return it->second.files[index];
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
namespace {
|
||||
void GetAllFilesImpl(IFileList& list, const string& root, vector<string>& result, bool recurse) {
|
||||
//if(root.find("
|
||||
|
||||
// The hell is your problem?!
|
||||
int fileAmount = list.GetFileAmount(root);
|
||||
for(int i = 0; i < fileAmount; ++i) {
|
||||
const string& file = list.GetFileName(root, i);
|
||||
result.push_back(file);
|
||||
}
|
||||
if(recurse) {
|
||||
int dirAmount = list.GetDirAmount(root);
|
||||
for(int i = 0; i < dirAmount; ++i) {
|
||||
const string& dir = list.GetDirName(root, i);
|
||||
if(dir.length() > 4 && dir.substr(dir.length() - 4, 4) == ".svn") {
|
||||
// We should never even get here..
|
||||
} else {
|
||||
GetAllFilesImpl(list, dir, result, recurse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetAllDirsImpl(IFileList& list, const string& root, vector<string>& result, bool recurse) {
|
||||
int dirAmount = list.GetDirAmount(root);
|
||||
for(int i = 0; i < dirAmount; ++i) {
|
||||
const string& dir = list.GetDirName(root, i);
|
||||
if(dir.length() > 4 && dir.substr(dir.length() - 4, 4) == ".svn") {
|
||||
// We should never even get here..
|
||||
} else {
|
||||
result.push_back(dir);
|
||||
|
||||
if(recurse)
|
||||
GetAllDirsImpl(list, dir, result, recurse);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Unamed namespace.
|
||||
|
||||
void GetAllFiles(IFileList& list, const string& root_, vector<string>& result, bool recurse, bool caseSensitive) {
|
||||
string root = root_;
|
||||
if(!caseSensitive)
|
||||
ConvertLower(root);
|
||||
HaxFile(root);
|
||||
|
||||
GetAllFilesImpl(list, root, result, recurse);
|
||||
std::sort(result.begin(), result.end());
|
||||
}
|
||||
|
||||
|
||||
void GetAllDirs(IFileList& list, const string& root_, vector<string>& result, bool recurse, bool caseSensitive) {
|
||||
string root = root_;
|
||||
if(!caseSensitive)
|
||||
ConvertLower(root);
|
||||
HaxFile(root);
|
||||
|
||||
GetAllDirsImpl(list, root, result, recurse);
|
||||
std::sort(result.begin(), result.end());
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "IFileList.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class FileList: public IFileList {
|
||||
struct Data;
|
||||
boost::scoped_ptr<Data> _data;
|
||||
|
||||
public:
|
||||
FileList(void);
|
||||
~FileList(void);
|
||||
|
||||
void SetCaseSensitivity(bool enable);
|
||||
|
||||
void AddDir(const std::string& dir);
|
||||
void AddFile(const std::string& file);
|
||||
|
||||
int GetDirAmount(const std::string& root) const;
|
||||
std::string GetDirName(const std::string& root, int index) const;
|
||||
int GetFileAmount(const std::string& root) const;
|
||||
const std::string& GetFileName(const std::string& root, int index) const;
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,109 +0,0 @@
|
||||
#include <map>
|
||||
#include "../Debug.h"
|
||||
#include "FilePackageManager.h"
|
||||
#include "EmptyBuffer.h"
|
||||
#include "FileList.h"
|
||||
|
||||
// HACK: This is not a good dependancy for error reporting.
|
||||
// We are going to use it anyway though.
|
||||
#include "InputFileStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
namespace {
|
||||
typedef std::multimap<int, boost::shared_ptr<IFilePackage> > PackageMap;
|
||||
FilePackageManager instance;
|
||||
FilePackageManager* instancePtr = 0;
|
||||
} // Unamed namespace.
|
||||
|
||||
using namespace util;
|
||||
|
||||
struct FilePackageManagerData {
|
||||
PackageMap packages;
|
||||
bool logNonExisting;
|
||||
|
||||
FilePackageManagerData(void) : logNonExisting(true) {}
|
||||
|
||||
InputStream GetFile(std::string filename) {
|
||||
for(unsigned int i = 0; i < filename.size(); ++i) {
|
||||
if(filename[i] == '\\')
|
||||
filename[i] = '/';
|
||||
}
|
||||
|
||||
for(PackageMap::reverse_iterator it = packages.rbegin(); it != packages.rend(); ++it) {
|
||||
InputStream result = it->second->GetFile(filename);
|
||||
if(!result.IsEof())
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is a bit of a hack.
|
||||
// Fix all data to use only lowercase letters if you
|
||||
// want it to work right. But you know me and upercase characters. --Allanis
|
||||
for(unsigned int i = 0; i < filename.size(); ++i) {
|
||||
// Not found try again in lowercase..
|
||||
if(isupper(filename[i]))
|
||||
filename[i] = tolower(filename[i]);
|
||||
}
|
||||
|
||||
// Nothing has been found.
|
||||
if(logNonExisting) {
|
||||
Debug::logger->message("FilePackageManager::GetFile - File: \"%s\" does not exist or is zero in length!", filename.c_str());
|
||||
}
|
||||
InputStream inputStream;
|
||||
boost::shared_ptr<EmptyBuffer> inputBuffer(new EmptyBuffer());
|
||||
|
||||
inputStream.SetBuffer(inputBuffer);
|
||||
return inputStream;
|
||||
}
|
||||
};
|
||||
|
||||
FilePackageManager::FilePackageManager(void) {
|
||||
boost::scoped_ptr<FilePackageManagerData> tempData(new FilePackageManagerData());
|
||||
_data.swap(tempData);
|
||||
}
|
||||
|
||||
FilePackageManager::~FilePackageManager(void) {
|
||||
}
|
||||
|
||||
void FilePackageManager::AddPackage(boost::shared_ptr<IFilePackage> filePackage, int priority) {
|
||||
std::pair<int, boost::shared_ptr<IFilePackage> > value(priority, filePackage);
|
||||
_data->packages.insert(value);
|
||||
}
|
||||
|
||||
boost::shared_ptr<IFileList> FilePackageManager::FindFiles(const std::string& dir, const std::string& extension, bool caseSensitive) {
|
||||
boost::shared_ptr<IFileList> result(new FileList());
|
||||
result->SetCaseSensitivity(caseSensitive);
|
||||
|
||||
for(PackageMap::iterator it = _data->packages.begin(); it != _data->packages.end(); ++it)
|
||||
it->second->FindFiles(dir, extension, *result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
InputStream FilePackageManager::GetFile(const std::string& filename) {
|
||||
return _data->GetFile(filename);
|
||||
}
|
||||
|
||||
void FilePackageManager::SetInputStreamErrorReporting(bool logNonExisting) {
|
||||
// HACK: This goes directly to the input file stream...
|
||||
_data->logNonExisting = logNonExisting;
|
||||
}
|
||||
|
||||
FilePackageManager& FilePackageManager::GetInstance(void) {
|
||||
if(!instancePtr)
|
||||
instancePtr = &instance;
|
||||
return *instancePtr;
|
||||
}
|
||||
|
||||
void FilePackageManager::SetInstancePtr(FilePackageManager* newInstance) {
|
||||
assert(newInstance);
|
||||
instancePtr = newInstance;
|
||||
|
||||
//FilePackageManager& oldInstance = GetInstance();
|
||||
//oldInstance._data->packages = newInstance->_data->packages;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "IFilePackage.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class IFileList;
|
||||
struct FilePackageManagerData;
|
||||
|
||||
class FilePackageManager {
|
||||
boost::scoped_ptr<FilePackageManagerData> _data;
|
||||
public:
|
||||
FilePackageManager(void);
|
||||
~FilePackageManager(void);
|
||||
|
||||
void AddPackage(boost::shared_ptr<IFilePackage> filePackae, int priority);
|
||||
boost::shared_ptr<IFileList> FindFiles(const std::string& dir, const std::string& extension, bool caseSensitive = false);
|
||||
InputStream GetFile(const std::string& filename);
|
||||
|
||||
void SetInputStreamErrorReporting(bool logNonExisting);
|
||||
|
||||
static FilePackageManager& GetInstance(void);
|
||||
static void SetInstancePtr(FilePackageManager* instance);
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,85 +0,0 @@
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "InputStreamWrapper.h"
|
||||
#include "FileTimestampChecker.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
/*bool FileTimestampChecker::IsFileNewerThanFile(const char* file, const char* secondFile) {
|
||||
assert
|
||||
}*/
|
||||
|
||||
bool FileTimestampChecker::IsFileNewerOrSameThanFile(const char* file, const char* secondfile) {
|
||||
if(GetFileTimestamp(file) >= GetFileTimestamp(secondfile))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileTimestampChecker::IsFileNewerOrAlmostSameThanFile(const char* file, const char* secondfile) {
|
||||
// WARNING: Max 60 seconds older file is also accepted as newer..
|
||||
if(GetFileTimestamp(file) + 60 >= GetFileTimestamp(secondfile))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileTimestampChecker::IsFileUpToDateComparedTo(const char* file, const char* secondfile) {
|
||||
FILE* f = fopen(file, "rb");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
return FileTimestampChecker::IsFileNewerOrAlmostSameThanFile(file, secondfile);
|
||||
}
|
||||
|
||||
filesystem::SC_FILE* fp = filesystem::sc_fopen(file, "rb");
|
||||
if(fp) {
|
||||
filesystem::sc_fclose(fp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define _stat stat
|
||||
|
||||
#ifndef _WIN32_
|
||||
#define _fileno fileno
|
||||
#endif
|
||||
|
||||
#define _fstat fstat
|
||||
#endif
|
||||
|
||||
|
||||
int FileTimestampChecker::GetFileTimestamp(const char* file) {
|
||||
struct _stat buf;
|
||||
FILE* f;
|
||||
int fh, result;
|
||||
int ret;
|
||||
|
||||
f = fopen(file, "rb");
|
||||
if(f == NULL) return -1;
|
||||
|
||||
fh = _fileno(f);
|
||||
|
||||
result = _fstat(fh, &buf);
|
||||
|
||||
if(result != 0) {
|
||||
return -1;
|
||||
} else {
|
||||
ret = int(buf.st_mtime);
|
||||
}
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // End of namespace filesystem.
|
||||
} // End of namespace saracraft.
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class FileTimestampChecker {
|
||||
public:
|
||||
// Check if the given file with given name has been modified after another
|
||||
// file of given name.
|
||||
// Return true if file *IS* newer.
|
||||
|
||||
// This is not needed....
|
||||
//static bool IsFileNewerThanFile(const char* file, const char* secondfile);
|
||||
static bool IsFileNewerOrSameThanFile(const char* file, const char* secondfile);
|
||||
static bool IsFileNewerOrAlmostSameThanFile(const char* file, const char* secondfile);
|
||||
static bool IsFileUpToDateComparedTo(const char* file, const char* secondfile);
|
||||
|
||||
static int GetFileTimestamp(const char *file);
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class IFileList {
|
||||
public:
|
||||
virtual ~IFileList(void) {}
|
||||
|
||||
virtual void SetCaseSensitivity(bool enable) = 0;
|
||||
|
||||
virtual void AddDir(const std::string& dir) = 0;
|
||||
virtual void AddFile(const std::string& file) = 0;
|
||||
|
||||
virtual int GetDirAmount(const std::string& root) const = 0;
|
||||
virtual std::string GetDirName(const std::string& root, int index) const = 0;
|
||||
virtual int GetFileAmount(const std::string& root) const = 0;
|
||||
virtual const std::string& GetFileName(const std::string& root, int index) const = 0;
|
||||
};
|
||||
|
||||
void GetAllFiles(IFileList& list, const std::string& root, std::vector<std::string>& result, bool recurse, bool caseSensitive = false);
|
||||
void GetAllDirs(IFileList& list, const std::string& root, std::vector<std::string>& result, bool recurse, bool caseSensitive = false);
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
#include "InputStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class IFileList;
|
||||
class IFilePackage {
|
||||
public:
|
||||
virtual ~IFilePackage(void) {}
|
||||
|
||||
virtual void FindFiles(const std::string& dir, const std::string& extension, IFileList& result) = 0;
|
||||
virtual InputStream GetFile(const std::string& filename) = 0;
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,60 +0,0 @@
|
||||
// This is an IO base function header for compress and uncompress.
|
||||
// This is for files using zlib + zip or unzip.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ZLIB_FILEFUNC_SEEK_CUR (1)
|
||||
#define ZLIB_FILEFUNC_SEEK_END (2)
|
||||
#define ZLIB_FILEFUNC_SEEK_SET (3)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_READ (1)
|
||||
#define ZLIB_FILEFUNC_MODE_WRITE (2)
|
||||
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
|
||||
#define ZLIB_FILEFUNC_MODE_CREATE (8)
|
||||
|
||||
#ifndef ZCALLBACK
|
||||
#if(defined(WIN32) || defined(WINDOWS) || defined(_WINDOWS)) && \
|
||||
defined(CALLBACK) && defined(USEWINDOWS_CALLBACK)
|
||||
#else
|
||||
#define ZCALLBACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef voidpf(ZCALLBACK* open_file_func) OF((voidpf opaque, const char* filename, int mode));
|
||||
typedef uLong (ZCALLBACK* read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
typedef uLong (ZCALLBACK* write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
|
||||
typedef long (ZCALLBACK* tell_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK* seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
|
||||
typedef int (ZCALLBACK* close_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef int (ZCALLBACK* testerror_file_func) OF((voidpf opaque, voidpf stream));
|
||||
|
||||
typedef struct zlib_filefunc_def_s { // WHY ?!?!?!!?!
|
||||
open_file_func zopen_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell_file_func ztell_file;
|
||||
seek_file_func zseek_file;
|
||||
close_file_func zclose_file;
|
||||
testerror_file_func zerror_file;
|
||||
voidpf opaque;
|
||||
} zlib_filefunc_def;
|
||||
|
||||
void Fill_Fopen_FileFunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
|
||||
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filfunc).opaque,filestream,pos,mode))
|
||||
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
|
||||
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,105 +0,0 @@
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "../Debug.h"
|
||||
#include "FileTimestampChecker.h"
|
||||
#include "InputCompressedFileStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct InputCompressedFileStreamBufferData {
|
||||
std::vector<unsigned char> 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<char> 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<InputCompressedFileStreamBufferData> 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<InputCompressedFileStreamBuffer> inputBuffer(new InputCompressedFileStreamBuffer(filename));
|
||||
|
||||
inputStream.SetBuffer(inputBuffer);
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "InputStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct InputCompressedFileStreamBufferData;
|
||||
|
||||
class InputCompressedFileStreamBuffer : public IInputStreamBuffer {
|
||||
boost::scoped_ptr<InputCompressedFileStreamBufferData> _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.
|
||||
|
@ -1,122 +0,0 @@
|
||||
#include <fstream>
|
||||
#include "../Debug.h"
|
||||
#include "InputFileStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct InputFileStreamBufferData {
|
||||
FILE* fp;
|
||||
size_t size;
|
||||
|
||||
InputFileStreamBufferData(const std::string filename) : fp(0), size(0) {
|
||||
fp = fopen(filename.c_str(), "rb");
|
||||
|
||||
#ifdef __UNIX__
|
||||
// Another ugly as hell case sensitive hack.
|
||||
// if anyone finds a nice way to handle this. Please implement it. -- Allanis
|
||||
if(!fp) {
|
||||
std::string filename = filename;
|
||||
for(unsigned int i = 0; i < filename.size(); i++) {
|
||||
if(isupper(filename[i]))
|
||||
filename[i] = tolower(filename[i]);
|
||||
else if(filename[i] == '\\')
|
||||
filename[i] = '/';
|
||||
}
|
||||
fp = fopen(filename.c_str(), "rb");
|
||||
}
|
||||
#endif
|
||||
if(fp) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
}
|
||||
if(!size)
|
||||
Close();
|
||||
}
|
||||
|
||||
~InputFileStreamBufferData(void) {
|
||||
Close();
|
||||
}
|
||||
|
||||
void Close(void) {
|
||||
if(fp) {
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InputFileStreamBuffer::~InputFileStreamBuffer(void) {
|
||||
|
||||
}
|
||||
|
||||
unsigned char InputFileStreamBuffer::PopByte(void) {
|
||||
char byte = 0;
|
||||
if(_data->fp) {
|
||||
int input = fgetc(_data->fp);
|
||||
if(input == EOF)
|
||||
_data->Close();
|
||||
else
|
||||
byte = (char)input;
|
||||
}
|
||||
return byte;
|
||||
}
|
||||
|
||||
bool InputFileStreamBuffer::IsEof(void) const {
|
||||
if(!_data->fp)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int InputFileStreamBuffer::GetSize(void) const {
|
||||
if(!_data->fp)
|
||||
return 0;
|
||||
|
||||
// This could cause maybe about a 2GB limimitation to file size
|
||||
// by casting to int. Feel free to FIXME.
|
||||
// -- Allanis
|
||||
return int(_data->size);
|
||||
}
|
||||
|
||||
void InputFileStreamBuffer::PopBytes(char* buffer, int bytes) {
|
||||
if(!_data->fp) {
|
||||
for(int i = 0; i < bytes; ++i)
|
||||
buffer[i] = 0;
|
||||
} else {
|
||||
//_data->stream.read(buffer, bytes);
|
||||
if(fread(buffer, 1, bytes, _data->fp) != (unsigned)bytes)
|
||||
_data->Close();
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: ffs. This is needed to get some sense into the input stream error reporting.
|
||||
//bool input_file_stream_no_nonexisting_error_message = false;
|
||||
|
||||
//void SetInputStreamErrorReporting(bool logNonExisting) {
|
||||
// input_file_stream_no_nonexisting_error_message = !logNonExisting;
|
||||
//}
|
||||
|
||||
InputStream CreateInputFileStream(const std::string& filename) {
|
||||
|
||||
// This whole method is pissing me off!!!!!!!!!!
|
||||
//There..
|
||||
|
||||
//InputStream inputStream;
|
||||
//boost::shared_ptr<InputFileStreamBuffer> inputBuffer(new InputFileStreamBuffer(filename));
|
||||
// Eh.. No.
|
||||
// TODO: Would need a seperate error check, eof is not the same as the file does not exist..
|
||||
// This would just spam error messages. We don't want that.
|
||||
/*if(!inputBuffer->IsEof()) {
|
||||
if(!input_file_stream_no_nonexisting_error_message) {
|
||||
Debug->logger("CreateInputFileStream - File \"%s\"does not exist or is zero length.", filename.c_str());
|
||||
}
|
||||
}*/
|
||||
//inputStream.SetBuffer(inputBuffer);
|
||||
//return inputStream;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,30 +0,0 @@
|
||||
// I forgot some code..
|
||||
#pragma once
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "InputStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct InputFileStreamBufferData;
|
||||
|
||||
class InputFileStreamBuffer: public IInputStreamBuffer {
|
||||
boost::scoped_ptr<InputFileStreamBufferData> _data;
|
||||
|
||||
public:
|
||||
InputFileStreamBuffer(const std::string& filename);
|
||||
~InputFileStreamBuffer(void);
|
||||
|
||||
unsigned char PopByte(void);
|
||||
bool IsEof(void) const;
|
||||
int GetSize(void) const;
|
||||
|
||||
void PopBytes(char* buffer, int bytes);
|
||||
};
|
||||
|
||||
InputStream CreateInputFileStream(const std::string& filename);
|
||||
void SetInputStreamErrorReporting(bool logNonExisting);
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,155 +0,0 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include "../Convert/ConvertType.h"
|
||||
#include <limits.h>
|
||||
#include "InputStream.h"
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning(disable: 444) // I think intel will complain at the base class not being virtual.
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(saracraft::util::uint16_t) * CHAR_BIT == 16);
|
||||
BOOST_STATIC_ASSERT(CHAR_BIT == 8);
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
namespace {
|
||||
|
||||
template<class T>
|
||||
void ReadFromStream(IInputStreamBuffer& buffer, T& value) {
|
||||
util::ConvertTo<T> converter;
|
||||
for(int i = 0; i < converter.GetSize(); ++i)
|
||||
converter.SetByte(i, buffer.PopByte());
|
||||
|
||||
value = converter.GetValue();
|
||||
}
|
||||
|
||||
} // End of unamed namespace.
|
||||
|
||||
InputStream::InputStream(void) {
|
||||
|
||||
}
|
||||
|
||||
InputStream::~InputStream(void) {
|
||||
|
||||
}
|
||||
|
||||
void InputStream::SetBuffer(boost::shared_ptr<IInputStreamBuffer> streamBuffer_) {
|
||||
assert(streamBuffer_);
|
||||
_streamBuffer = streamBuffer_;
|
||||
}
|
||||
|
||||
bool InputStream::IsEof(void) const {
|
||||
assert(_streamBuffer);
|
||||
return _streamBuffer->IsEof();
|
||||
}
|
||||
|
||||
int InputStream::GetSize(void) const {
|
||||
assert(_streamBuffer);
|
||||
return _streamBuffer->GetSize();
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(std::string& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
util::uint16_t stringSize = 0;
|
||||
this->Read(stringSize);
|
||||
|
||||
value.resize(stringSize);
|
||||
for(int i = 0; i < stringSize; ++i)
|
||||
value[i] = _streamBuffer->PopByte();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(bool& value) {
|
||||
assert(_streamBuffer);
|
||||
value = _streamBuffer->PopByte() != 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(unsigned char& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
value = _streamBuffer->PopByte();
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(char& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
value = _streamBuffer->PopByte();
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(signed char& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
value = _streamBuffer->PopByte();
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(unsigned short& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
ReadFromStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(signed short& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
ReadFromStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(unsigned int& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
ReadFromStream(*_streamBuffer, value);
|
||||
return * this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(signed int& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
ReadFromStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(float& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
ReadFromStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(double& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
ReadFromStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(unsigned char* buffer, int elements) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
_streamBuffer->PopBytes(reinterpret_cast<char*>(buffer), elements);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(char* buffer, int elements) {
|
||||
assert(_streamBuffer);
|
||||
_streamBuffer->PopBytes(buffer, elements);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::Read(unsigned short* buffer, int elements) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
_streamBuffer->PopBytes(reinterpret_cast<char*>(buffer), elements * sizeof(short));
|
||||
}
|
||||
|
||||
} // End of namespace filesystem.
|
||||
} // End of namespace saracraft.
|
@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef INCLUDED_BOOST_SHARED_PTR_HPP
|
||||
#define INCLUDED_BOOST_SHATED_PTR_HPP
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#endif
|
||||
#ifndef INCLUDED_STRING
|
||||
#define INCLUDED_STRING
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class IInputStreamBuffer {
|
||||
public:
|
||||
virtual ~IInputStreamBuffer(void) { }
|
||||
|
||||
virtual unsigned char PopByte(void) = 0;
|
||||
virtual bool IsEof(void) const = 0;
|
||||
virtual int GetSize(void) const = 0;
|
||||
|
||||
virtual void PopBytes(char* buffer, int bytes) = 0;
|
||||
};
|
||||
|
||||
class InputStream {
|
||||
boost::shared_ptr<IInputStreamBuffer> _streamBuffer;
|
||||
public:
|
||||
InputStream(void);
|
||||
~InputStream(void);
|
||||
|
||||
void SetBuffer(boost::shared_ptr<IInputStreamBuffer> streamBuffer);
|
||||
bool IsEof(void) const;
|
||||
int GetSize(void) const;
|
||||
|
||||
private:
|
||||
InputStream& Read(std::string& value);
|
||||
InputStream& Read(bool& value);
|
||||
|
||||
InputStream& Read(unsigned char& value);
|
||||
InputStream& Read(char& value);
|
||||
InputStream& Read(signed char& value);
|
||||
|
||||
InputStream& Read(unsigned short& value);
|
||||
InputStream& Read(signed short& value);
|
||||
|
||||
InputStream& Read(unsigned int& value);
|
||||
InputStream& Read(signed int& value);
|
||||
|
||||
InputStream& Read(float& value);
|
||||
InputStream& Read(double& value);
|
||||
|
||||
friend InputStream& operator >> (InputStream&, std::string&);
|
||||
friend InputStream& operator >> (InputStream&, bool&);
|
||||
friend InputStream& operator >> (InputStream&, unsigned char&);
|
||||
friend InputStream& operator >> (InputStream&, char&);
|
||||
friend InputStream& operator >> (InputStream&, signed char&);
|
||||
friend InputStream& operator >> (InputStream&, unsigned short&);
|
||||
friend InputStream& operator >> (InputStream&, signed short&);
|
||||
friend InputStream& operator >> (InputStream&, unsigned int&);
|
||||
friend InputStream& operator >> (InputStream&, signed int&);
|
||||
friend InputStream& operator >> (InputStream&, float&);
|
||||
friend InputStream& operator >> (InputStream&, double&);
|
||||
|
||||
public:
|
||||
// Optimized readers.
|
||||
InputStream& Read(unsigned char* buffer, int elements);
|
||||
InputStream& Read(char* buffer, int elements);
|
||||
InputStream& Read(unsigned short* buffer, int elements);
|
||||
};
|
||||
|
||||
inline InputStream& operator >> (InputStream& stream, std::string& value) { return stream.Read(value); }
|
||||
inline InputStream& operator >> (InputStream& stream, bool& value) { return stream.Read(value); }
|
||||
|
||||
inline InputStream& operator >> (InputStream& stream, unsigned char& value) { return stream.Read(value); }
|
||||
inline InputStream& operator >> (InputStream& stream, char& value) { return stream.Read(value); }
|
||||
inline InputStream& operator >> (InputStream& stream, signed char& value) { return stream.Read(value); }
|
||||
|
||||
inline InputStream& operator >> (InputStream& stream, unsigned short& value) { return stream.Read(value); }
|
||||
inline InputStream& operator >> (InputStream& stream, signed short& value) { return stream.Read(value); }
|
||||
|
||||
inline InputStream& operator >> (InputStream& stream, unsigned int& value) { return stream.Read(value); }
|
||||
inline InputStream& operator >> (InputStream& stream, signed int& value) { return stream.Read(value); }
|
||||
|
||||
inline InputStream& operator >> (InputStream& stream, float& value) { return stream.Read(value); }
|
||||
inline InputStream& operator >> (InputStream& stream, double& value) { return stream.Read(value); }
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,85 +0,0 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../Debug.h"
|
||||
#include "InputStreamWrapper.h"
|
||||
#include "FilePackageManager.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
namespace {
|
||||
int openFileAmount = 0;
|
||||
|
||||
struct Tracker {
|
||||
Tracker(void) {}
|
||||
|
||||
~Tracker(void) { assert(openFileAmount == 0); }
|
||||
};
|
||||
|
||||
Tracker tracker;
|
||||
} // Namespace Unamed.
|
||||
|
||||
using namespace util;
|
||||
|
||||
struct SC_FILE {
|
||||
InputStream stream;
|
||||
|
||||
SC_FILE(InputStream& stream_) : stream(stream_) {
|
||||
++openFileAmount;
|
||||
}
|
||||
|
||||
~SC_FILE(void) {
|
||||
--openFileAmount;
|
||||
}
|
||||
};
|
||||
|
||||
SC_FILE* sc_fopen(const char* filename, const char*) {
|
||||
if(!filename)
|
||||
return 0;
|
||||
|
||||
FilePackageManager& manager = FilePackageManager::GetInstance();
|
||||
manager.SetInputStreamErrorReporting(false);
|
||||
InputStream stream = manager.GetFile(filename);
|
||||
manager.SetInputStreamErrorReporting(true);
|
||||
|
||||
// if(stream.IsEof())
|
||||
// return 0;
|
||||
return new SC_FILE(stream);
|
||||
}
|
||||
|
||||
size_t sc_fread(void* buffer, size_t size, size_t count, SC_FILE* stream) {
|
||||
if(!stream) {
|
||||
Debug::logger->message("sc_fread - Attempt to read when no stream is available.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(stream->stream.IsEof()) {
|
||||
Debug::logger->message("sc_fread - Attempt to read past the end of the file.");
|
||||
}
|
||||
|
||||
unsigned char* charBuffer = reinterpret_cast<unsigned char*> (buffer);
|
||||
stream->stream.Read(charBuffer, size * count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t sc_fsize(SC_FILE* stream) {
|
||||
if(!stream)
|
||||
return 0;
|
||||
|
||||
return stream->stream.GetSize();
|
||||
}
|
||||
|
||||
int sc_feof(SC_FILE* stream) {
|
||||
if(!stream || stream->stream.IsEof())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sc_fclose(SC_FILE* stream) {
|
||||
delete stream;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct SC_FILE;
|
||||
|
||||
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.
|
||||
|
@ -1,48 +0,0 @@
|
||||
#include <queue>
|
||||
#include "MemoryStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct MemoryStreamBufferData {
|
||||
std::queue<unsigned char> buffer;
|
||||
};
|
||||
|
||||
MemoryStreamBuffer::MemoryStreamBuffer(void) {
|
||||
boost::scoped_ptr<MemoryStreamBufferData> tempData(new MemoryStreamBufferData());
|
||||
_data.swap(tempData);
|
||||
}
|
||||
|
||||
MemoryStreamBuffer::~MemoryStreamBuffer(void) {
|
||||
|
||||
}
|
||||
|
||||
unsigned char MemoryStreamBuffer::PopByte(void) {
|
||||
if(!_data->buffer.empty()) {
|
||||
unsigned char value = _data->buffer.front();
|
||||
_data->buffer.pop();
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MemoryStreamBuffer::IsEof(void) const {
|
||||
return _data->buffer.empty();
|
||||
}
|
||||
|
||||
int MemoryStreamBuffer::GetSize(void) const {
|
||||
return _data->buffer.size();
|
||||
}
|
||||
|
||||
void MemoryStreamBuffer::PutByte(unsigned char byte) {
|
||||
_data->buffer.push(byte);
|
||||
}
|
||||
|
||||
void MemoryStreamBuffer::PopBytes(char* buffer, int bytes) {
|
||||
for(int i = 0; i < bytes; ++i)
|
||||
buffer[i] = PopByte();
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,26 +0,0 @@
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "InputStream.h"
|
||||
#include "OutputStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct MemoryStreamBufferData;
|
||||
|
||||
class MemoryStreamBuffer : public IInputStreamBuffer, public IOutputStreamBuffer {
|
||||
boost::scoped_ptr<MemoryStreamBufferData> _data;
|
||||
public:
|
||||
MemoryStreamBuffer(void);
|
||||
~MemoryStreamBuffer(void);
|
||||
|
||||
unsigned char PopByte(void);
|
||||
bool IsEof(void) const;
|
||||
int GetSize(void) const;
|
||||
|
||||
void PutByte(unsigned char byte);
|
||||
void PopBytes(char* buffer, int bytes);
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,66 +0,0 @@
|
||||
#include <vector>
|
||||
#include <zlib.h>
|
||||
#include <fstream>
|
||||
|
||||
#include "OutputCompressedFileStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct OutputCompressedFileStreamBufferData {
|
||||
std::ofstream stream;
|
||||
std::vector<unsigned char> buffer;
|
||||
|
||||
OutputCompressedFileStreamBufferData(const std::string filename) :
|
||||
stream(filename.c_str(), std::ios::binary) {
|
||||
|
||||
}
|
||||
|
||||
~OutputCompressedFileStreamBufferData(void) {
|
||||
}
|
||||
|
||||
void Compress(void) {
|
||||
int bytes = buffer.size();
|
||||
stream.write((char*)& bytes, sizeof(int));
|
||||
if(!bytes)
|
||||
return;
|
||||
|
||||
std::vector<char> tempBuffer(bytes+12);
|
||||
Bytef* source = &buffer[0];
|
||||
uLong sourceLength = buffer.size();
|
||||
Bytef* destination = (Bytef*)& tempBuffer[0];
|
||||
uLong destinationLength = tempBuffer.size();
|
||||
|
||||
int code = ::compress(destination, &destinationLength, source, sourceLength);
|
||||
if(code != Z_OK)
|
||||
int a = 0;
|
||||
stream.write(&tempBuffer[0], destinationLength);
|
||||
}
|
||||
};
|
||||
|
||||
OutputCompressedFileStreamBuffer::OutputCompressedFileStreamBuffer(const std::string& filename) {
|
||||
boost::scoped_ptr<OutputCompressedFileStreamBufferData> tempData(new OutputCompressedFileStreamBufferData(filename));
|
||||
_data.swap(tempData);
|
||||
}
|
||||
|
||||
OutputCompressedFileStreamBuffer::~OutputCompressedFileStreamBuffer(void) {
|
||||
_data->Compress();
|
||||
}
|
||||
|
||||
void OutputCompressedFileStreamBuffer::PutByte(unsigned char c) {
|
||||
_data->buffer.push_back(c);
|
||||
//char c_ = c;
|
||||
//_data->stream.Write(&c_, 1);
|
||||
}
|
||||
|
||||
OutputStream CreateOutputCompressedFileStream(const std::string& filename) {
|
||||
OutputStream outputStream;
|
||||
boost::shared_ptr<OutputCompressedFileStreamBuffer> outputBuffer(new OutputCompressedFileStreamBuffer(filename));
|
||||
|
||||
outputStream.SetBuffer(outputBuffer);
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "OutputStream.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
struct OutputCompressedFileStreamBufferData;
|
||||
|
||||
class OutputCompressedFileStreamBuffer : public IOutputStreamBuffer {
|
||||
boost::scoped_ptr<OutputCompressedFileStreamBufferData> _data;
|
||||
public:
|
||||
OutputCompressedFileStreamBuffer(const std::string& filename);
|
||||
~OutputCompressedFileStreamBuffer(void);
|
||||
|
||||
void PutByte(unsigned char c);
|
||||
};
|
||||
|
||||
OutputStream CreateOutputCompressedFileStream(const std::string& filename);
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,130 +0,0 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include "../Convert/ConvertType.h"
|
||||
#include <limits.h>
|
||||
#include "OutputStream.h"
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning(disable: 444) // I think intel will complain at the base class not being virtual.
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(saracraft::util::uint16_t) * CHAR_BIT == 16);
|
||||
BOOST_STATIC_ASSERT(CHAR_BIT == 8);
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
namespace {
|
||||
|
||||
template<class T>
|
||||
void SendToStream(IOutputStreamBuffer& buffer, T& value) {
|
||||
util::ConvertFrom<T> converter(value);
|
||||
for(int i = 0; i < converter.GetSize(); ++i)
|
||||
buffer.PutByte(converter.GetByte(i));
|
||||
}
|
||||
|
||||
} // End of unamed namespace.
|
||||
|
||||
OutputStream::OutputStream(void) : _textStrings(false){
|
||||
|
||||
}
|
||||
|
||||
OutputStream::~OutputStream(void) {
|
||||
|
||||
}
|
||||
|
||||
void OutputStream::SetBuffer(boost::shared_ptr<IOutputStreamBuffer> streamBuffer_) {
|
||||
assert(streamBuffer_);
|
||||
_streamBuffer = streamBuffer_;
|
||||
}
|
||||
|
||||
void OutputStream::UseTextStrings(void) {
|
||||
_textStrings = true;
|
||||
}
|
||||
|
||||
|
||||
OutputStream& OutputStream::Write(std::string& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
util::uint16_t stringSize = 0;
|
||||
|
||||
if(!_textStrings)
|
||||
Write(stringSize);
|
||||
|
||||
for(int i = 0; i < stringSize; ++i)
|
||||
_streamBuffer->PutByte(value[i]);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(bool& value) {
|
||||
assert(_streamBuffer);
|
||||
unsigned char b = (value) ? 1:0;
|
||||
_streamBuffer->PutByte(b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(unsigned char& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
_streamBuffer->PutByte(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(char& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
_streamBuffer->PutByte(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(signed char& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
_streamBuffer->PutByte(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(unsigned short& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
SendToStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(signed short& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
SendToStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(unsigned int& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
SendToStream(*_streamBuffer, value);
|
||||
return * this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(signed int& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
SendToStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(float& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
SendToStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::Write(double& value) {
|
||||
assert(_streamBuffer);
|
||||
|
||||
SendToStream(*_streamBuffer, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // End of namespace filesystem.
|
||||
} // End of namespace saracraft.
|
@ -1,80 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef INCLUDED_BOOST_SHARED_PTR_HPP
|
||||
#define INCLUDED_BOOST_SHATED_PTR_HPP
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#endif
|
||||
#ifndef INCLUDED_STRING
|
||||
#define INCLUDED_STRING
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class IOutputStreamBuffer {
|
||||
public:
|
||||
virtual ~IOutputStreamBuffer(void) { }
|
||||
|
||||
virtual void PutByte(unsigned char byte) = 0;
|
||||
};
|
||||
|
||||
class OutputStream {
|
||||
boost::shared_ptr<IOutputStreamBuffer> _streamBuffer;
|
||||
bool _textStrings;
|
||||
public:
|
||||
OutputStream(void);
|
||||
~OutputStream(void);
|
||||
|
||||
void SetBuffer(boost::shared_ptr<IOutputStreamBuffer> streamBuffer);
|
||||
void UseTextStrings(void); // Insert pure strings. Put std::endl manually!!!
|
||||
|
||||
private:
|
||||
OutputStream& Write(std::string& value);
|
||||
OutputStream& Write(bool& value);
|
||||
|
||||
OutputStream& Write(unsigned char& value);
|
||||
OutputStream& Write(char& value);
|
||||
OutputStream& Write(signed char& value);
|
||||
|
||||
OutputStream& Write(unsigned short& value);
|
||||
OutputStream& Write(signed short& value);
|
||||
|
||||
OutputStream& Write(unsigned int& value);
|
||||
OutputStream& Write(signed int& value);
|
||||
|
||||
OutputStream& Write(float& value);
|
||||
OutputStream& Write(double& value);
|
||||
|
||||
friend OutputStream& operator >> (OutputStream&, std::string&);
|
||||
friend OutputStream& operator >> (OutputStream&, bool&);
|
||||
friend OutputStream& operator >> (OutputStream&, unsigned char&);
|
||||
friend OutputStream& operator >> (OutputStream&, char&);
|
||||
friend OutputStream& operator >> (OutputStream&, signed char&);
|
||||
friend OutputStream& operator >> (OutputStream&, unsigned short&);
|
||||
friend OutputStream& operator >> (OutputStream&, signed short&);
|
||||
friend OutputStream& operator >> (OutputStream&, unsigned int&);
|
||||
friend OutputStream& operator >> (OutputStream&, signed int&);
|
||||
friend OutputStream& operator >> (OutputStream&, float&);
|
||||
friend OutputStream& operator >> (OutputStream&, double&);
|
||||
};
|
||||
|
||||
inline OutputStream& operator >> (OutputStream& stream, std::string& value) { return stream.Write(value); }
|
||||
inline OutputStream& operator >> (OutputStream& stream, bool& value) { return stream.Write(value); }
|
||||
|
||||
inline OutputStream& operator >> (OutputStream& stream, unsigned char& value) { return stream.Write(value); }
|
||||
inline OutputStream& operator >> (OutputStream& stream, char& value) { return stream.Write(value); }
|
||||
inline OutputStream& operator >> (OutputStream& stream, signed char& value) { return stream.Write(value); }
|
||||
|
||||
inline OutputStream& operator >> (OutputStream& stream, unsigned short& value) { return stream.Write(value); }
|
||||
inline OutputStream& operator >> (OutputStream& stream, signed short& value) { return stream.Write(value); }
|
||||
|
||||
inline OutputStream& operator >> (OutputStream& stream, unsigned int& value) { return stream.Write(value); }
|
||||
inline OutputStream& operator >> (OutputStream& stream, signed int& value) { return stream.Write(value); }
|
||||
|
||||
inline OutputStream& operator >> (OutputStream& stream, float& value) { return stream.Write(value); }
|
||||
inline OutputStream& operator >> (OutputStream& stream, double& value) { return stream.Write(value); }
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,348 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "SCpak.h"
|
||||
#include "InputStreamWrapper.h"
|
||||
#include "RlePackedFileWrapper.h"
|
||||
|
||||
#define USE_SC_INPUT_STREAM_WRAPPER
|
||||
|
||||
static const int RLE_PACKED_CHUNK_MAGIC = *((int*)"RLE1");
|
||||
|
||||
using namespace saracraft::filesystem;
|
||||
|
||||
|
||||
struct RLE_PACKED_FILE {
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
SC_FILE* inputFile;
|
||||
#else
|
||||
FILE* inputtFile;
|
||||
#endif
|
||||
FILE* outputFile;
|
||||
bool errorFlag;
|
||||
bool inputIsRle;
|
||||
|
||||
RLE_PACKED_FILE(void) :
|
||||
inputFile(NULL), outputFile(NULL), errorFlag(false), inputIsRle(false) {
|
||||
|
||||
}
|
||||
|
||||
~RLE_PACKED_FILE(void) {
|
||||
assert(inputFile == NULL);
|
||||
assert(outputFile == NULL);
|
||||
}
|
||||
};
|
||||
|
||||
bool RlePackedDetect(const char* filename) {
|
||||
bool wasRLE = false;
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
SC_FILE* inputFile = sc_fopen(filename, "rb");
|
||||
#else
|
||||
FILE* inputFile = fopen(filename, "rb");
|
||||
#endif
|
||||
if(inputFile != NULL) {
|
||||
int chunkId;
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
int got = sc_fread(&chunkId, sizeof(int), 1, inputFile);
|
||||
#else
|
||||
int got = fread(&chunkId, sizeof(int), 1, inputFile);
|
||||
#endif
|
||||
if(got == 1 && chunkId == RLE_PACKED_CHUNK_MAGIC) {
|
||||
wasRLE = true;
|
||||
}
|
||||
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
sc_fclose(inputFile);
|
||||
#else
|
||||
fclose(inputFile);
|
||||
#endif
|
||||
}
|
||||
return wasRLE;
|
||||
}
|
||||
|
||||
RLE_PACKED_FILE* RlePacked_fopen(const char* filename, const char* params) {
|
||||
assert(params != NULL);
|
||||
if(params == NULL)
|
||||
return NULL;
|
||||
|
||||
if(strcmp(params, "rb") == 0) {
|
||||
bool rle = false;
|
||||
if(RlePackedDetect(filename))
|
||||
rle = true;
|
||||
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
SC_FILE* inputFile = sc_fopen(filename, params);
|
||||
#else
|
||||
FILE* inputFile = fopen(filename, params);
|
||||
#endif
|
||||
if(inputFile != NULL) {
|
||||
RLE_PACKED_FILE* f = new RLE_PACKED_FILE();
|
||||
f->inputFile = inputFile;
|
||||
f->inputIsRle = rle;
|
||||
return f;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(strcmp(params, "wb") == 0) {
|
||||
FILE* outputFile = fopen(filename, params);
|
||||
if(outputFile != NULL) {
|
||||
RLE_PACKED_FILE* f = new RLE_PACKED_FILE();
|
||||
f->outputFile = outputFile;
|
||||
return f;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
assert(!"RlePacked_fopen - unsupported open params.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t RlePacked_fread(void* buffer, size_t size, size_t count, RLE_PACKED_FILE* stream) {
|
||||
assert(stream != NULL);
|
||||
assert(stream->inputFile != NULL);
|
||||
|
||||
if(!stream->inputIsRle) {
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
size_t ret = sc_fread(buffer, size, count, stream->inputFile);
|
||||
#else
|
||||
size_t ret = fread(buffer, size, count, stream->inputFile);
|
||||
#endif
|
||||
if(ret <= 0)
|
||||
stream->errorFlag = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tmpgot = 0;
|
||||
int chunkId = 0;
|
||||
char isPacked = 0;
|
||||
int packedSize = 0;
|
||||
int unpackedSize = 0;
|
||||
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
tmpgot = sc_fread(&chunkId, sizeof(int), 1, stream->inputFile);
|
||||
#else
|
||||
tmpgot = fread(&chunkId, sizeof(int), 1, stream->inputFile);
|
||||
#endif
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fread - no more data available (expected chunk id, but got nothing).");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(chunkId != RLE_PACKED_CHUNK_MAGIC) {
|
||||
assert(!"RlePacked_fread - invalid data (expected chunk id, but got something else).");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
tmpgot = sc_fread(&isPacked, sizeof(char), 1, stream->inputFile);
|
||||
#else
|
||||
tmpgot = fread(&isPacked, sizor(char), 1, stream->inputFile);
|
||||
#endif
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fread - truncated chunk header (expected packed flag). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(isPacked != 0 && isPacked != 1) {
|
||||
assert(!"RlePacked_fread - invalid data (expected packed flag, but got something else). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
tmpgot = sc_fread(&packedSize, sizeof(int), 1, stream->inputFile);
|
||||
#else
|
||||
tmpgot = fread(&packedSize, sizeof(int), 1, stream->inputFile);
|
||||
#endif
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fread - truncated chunk header (expected packed size). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(packedSize <= 0) {
|
||||
assert(!"RlePacked_fread - invalid data (packed size is zero or negative). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(packedSize > (int)count * (int)size) {
|
||||
assert(!"RlePacked_fread - invalid data (size of packed chunk is larger than requested data). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
tmpgot = sc_fread(&unpackedSize, sizeof(int), 1, stream->inputFile);
|
||||
#else
|
||||
tmpgot = fread(&unpackedSize, sizeof(int), 1, stream->inputFile);
|
||||
#endif
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fread - truncated chunk header (expected unpacked size). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(unpackedSize <= 0) {
|
||||
assert(!"RlePacked_fread - invalid data (unpacked size is zero or negative). ");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(unpackedSize != count * size) {
|
||||
assert(!"RlePacked_fread - invalid data (size of unpacked chunk does not equal requested size).");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
if(!isPacked && packedSize != unpackedSize) {
|
||||
assert(!"RlePacked_fread - invalid data (supposed to be unpacked chunk, but packed and unpacked size mismatch).");
|
||||
stream->errorFlag = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char* packedbuf = new unsigned char[packedSize+16];
|
||||
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
int got = sc_fread(packedbuf, packedSize, 1, stream->inputFile);
|
||||
#else
|
||||
int got = fread(packedbuf, packedSize, 1, stream->inputFile);
|
||||
#endif
|
||||
if(got == 1) {
|
||||
if(isPacked) {
|
||||
scpak_set_bits(16);
|
||||
scpak_set_16bit_params(0xA0EA, 0xA0EB, 0xA0EC);
|
||||
int resultSize = scpak_unpack(packedSize, packedbuf, (unsigned char*)buffer, unpackedSize);
|
||||
if(resultSize != unpackedSize) {
|
||||
assert(!"RlePacked_fread - invalid data (chunk header unpacked size did not match actual resulting unpacked size).");
|
||||
stream->errorFlag = true;
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
memcpy(buffer, packedbuf, packedSize);
|
||||
}
|
||||
delete [] packedbuf;
|
||||
return count;
|
||||
} else {
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t RlePacked_fwrite(void* buffer, size_t size, size_t count, RLE_PACKED_FILE* stream) {
|
||||
assert(stream != NULL);
|
||||
assert(stream->outputFile != NULL);
|
||||
assert(size > 0 && count > 0);
|
||||
|
||||
int unpackedSize = (int)size*(int)count;
|
||||
assert(unpackedSize > 0);
|
||||
|
||||
unsigned char* packedbuf = new unsigned char[unpackedSize+16];
|
||||
|
||||
scpak_set_bits(16);
|
||||
scpak_set_16bit_params(0xA0EA, 0xA0EB, 0xA0EC);
|
||||
int packedSize = scpak_pack(unpackedSize, (unsigned char*)buffer, packedbuf);
|
||||
|
||||
char isPacked = 1;
|
||||
if(packedSize == 0) {
|
||||
isPacked = 0;
|
||||
packedSize = unpackedSize;
|
||||
memcpy(packedbuf, buffer, packedSize);
|
||||
}
|
||||
|
||||
int tmpgot = 0;
|
||||
|
||||
tmpgot = fwrite(&RLE_PACKED_CHUNK_MAGIC, sizeof(int), 1, stream->outputFile);
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fwrte - write failed (chunk id).");
|
||||
stream->errorFlag = true;
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmpgot = fwrite(&isPacked, sizeof(char), 1, stream->outputFile);
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fwrite - write failed (chunk packed flag).");
|
||||
stream->errorFlag = true;
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmpgot = fwrite(&packedSize, sizeof(int), 1, stream->outputFile);
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fwrite - write failed (chunk packed size).");
|
||||
stream->errorFlag = true;
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmpgot = fwrite(&unpackedSize, sizeof(int), 1, stream->outputFile);
|
||||
if(tmpgot != 1) {
|
||||
assert(!"RlePacked_fwrite - write failed (chunk unpacked size).");
|
||||
stream->errorFlag = true;
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int got = fwrite(packedbuf, packedSize, 1, stream->outputFile);
|
||||
if(got != 1) {
|
||||
assert(!"RlePacked_fwrite - write failed (packed data).");
|
||||
stream->errorFlag = true;
|
||||
delete [] packedbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
delete [] packedbuf;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
long RlePacked_fsize(RLE_PACKED_FILE* stream) {
|
||||
assert(stream != NULL);
|
||||
assert(stream->inputFile != NULL || stream->outputFile != NULL);
|
||||
|
||||
if(stream->inputFile != NULL) {
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
return sc_fsize(stream->inputFile);
|
||||
#else
|
||||
fpos_t pos;
|
||||
if(fgetpos(stream->inputFile, &pos) != 0) {
|
||||
assert(!"fgetpos failed.");
|
||||
stream->errorFlag = true;
|
||||
return -1;
|
||||
}
|
||||
fseek(stream->inputFile, 0, SEEK_END);
|
||||
long tmp = ftell(stream->inputFile);
|
||||
|
||||
if(fsetpos(stream->inputFile, &pos) != 0) {
|
||||
assert(!"fsetpos failed.");
|
||||
stream->errorFlag = true;
|
||||
return -1;
|
||||
}
|
||||
return tmp;
|
||||
#endif
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int RlePacked_fclose(RLE_PACKED_FILE* stream) {
|
||||
assert(stream != NULL);
|
||||
assert(stream->inputFile != NULL || stream->outputFile != NULL);
|
||||
|
||||
int result = 0;
|
||||
if(stream->inputFile != NULL) {
|
||||
#ifdef USE_SC_INPUT_STREAM_WRAPPER
|
||||
result = sc_fclose(stream->inputFile);
|
||||
#else
|
||||
result = fclose(stream->inputFile);
|
||||
#endif
|
||||
stream->inputFile = NULL;
|
||||
}
|
||||
if(stream->outputFile != NULL) {
|
||||
fclose(stream->outputFile);
|
||||
stream->outputFile = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool RlePackedWasError(RLE_PACKED_FILE* stream) {
|
||||
assert(stream != NULL);
|
||||
return stream->errorFlag;
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// A silly read/write "chunk packed" file.
|
||||
// *Must* read data in the same sized chunks as it was written!
|
||||
// Also reading/writing in really small chunks will just result in extremely
|
||||
// large files..
|
||||
|
||||
struct RLE_PACKED_FILE;
|
||||
|
||||
// Return true if the file seems to be rle packed.
|
||||
bool RlePackedDetect(const char* filename);
|
||||
|
||||
RLE_PACKED_FILE* RlePacked_fopen(const char* filename, const char* params);
|
||||
|
||||
size_t RlePacked_fread(void* buffer, size_t size, size_t count, RLE_PACKED_FILE* stream);
|
||||
|
||||
size_t RlePacked_fwrite(void* buffer, size_t size, size_t count, RLE_PACKED_FILE* stream);
|
||||
|
||||
long RlePacked_fsize(RLE_PACKED_FILE* stream);
|
||||
|
||||
bool RlePackedWasError(RLE_PACKED_FILE* stream);
|
||||
|
||||
int RlePacked_fclose(RLE_PACKED_FILE* stream);
|
||||
|
@ -1,25 +0,0 @@
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "InputStream.h"
|
||||
#include "FilePackageManager.h"
|
||||
|
||||
#include "SCCopyFile.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
void SCCopyFile::CopyFile(const std::string& from, const std::string& to) {
|
||||
std::fstream out(to.c_str(), std::ios::out);
|
||||
saracraft::filesystem::InputStream in = saracraft::filesystem::FilePackageManager::GetInstance().GetFile(from);
|
||||
|
||||
std::string temp;
|
||||
temp.resize(in.GetSize());
|
||||
in.Read((unsigned char*)&temp[0], in.GetSize());
|
||||
out << temp << std::endl;
|
||||
|
||||
out.close();
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class SCCopyFile {
|
||||
public:
|
||||
|
||||
// TODO: This will currently only handle smallish text files
|
||||
// propperly.
|
||||
|
||||
/*** DON'T USE FOR BINARY FILES!!!! ***/
|
||||
static void CopyFile(const std::string& from, const std::string& to);
|
||||
};
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
@ -1,327 +0,0 @@
|
||||
#include <assert.h>
|
||||
#include "SCpak.h"
|
||||
|
||||
unsigned char scpak_bits = 8;
|
||||
|
||||
// These mark values 1-3 must be incremental!!!
|
||||
unsigned char scpak_mark8_1 = 0xFA;
|
||||
unsigned char scpak_mark8_2 = 0xFB;
|
||||
unsigned char scpak_mark8_3 = 0xFC;
|
||||
|
||||
unsigned short scpak_mark16_1 = 0xA0EA;
|
||||
unsigned short scpak_mark16_2 = 0xA0EB;
|
||||
unsigned short scpak_mark16_3 = 0xA0EC;
|
||||
|
||||
void scpak_set_bits(unsigned char bits) {
|
||||
if(bits == 8 || bits == 16) {
|
||||
scpak_bits = bits;
|
||||
} else {
|
||||
// An error accured.
|
||||
assert("scpak_set_bits - invalid parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
void scpak_set_8bit_params(unsigned char mark1, unsigned char mark2, unsigned char mark3) {
|
||||
if(mark1 != mark2 && mark1 != mark3 && mark2 != mark3
|
||||
&& mark2 == mark1 + 1 && mark3 == mark2 + 1) {
|
||||
|
||||
scpak_mark8_1 = mark1;
|
||||
scpak_mark8_2 = mark2;
|
||||
scpak_mark8_3 = mark3;
|
||||
} else {
|
||||
// Error!
|
||||
assert(!"scpak_set_8bit_params - invalid parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
void scpak_set_16bit_params(unsigned short mark1, unsigned short mark2, unsigned short mark3) {
|
||||
if(mark1 != mark2 && mark1 != mark3 && mark2 != mark3
|
||||
&& mark2 == mark1 + 1 && mark3 == mark2 + 1) {
|
||||
scpak_mark16_1 = mark1;
|
||||
scpak_mark16_2 = mark2;
|
||||
scpak_mark16_3 - mark3;
|
||||
} else {
|
||||
// Error!
|
||||
assert(!"scpak_set_16bit_params - invalid parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
int scpak_pack_8b(int size, unsigned const char* src, unsigned char* dest) {
|
||||
int s;
|
||||
int d = 0;
|
||||
short count = 0;
|
||||
unsigned char prev;
|
||||
|
||||
if(size < 1) return 0;
|
||||
|
||||
prev = src[0];
|
||||
|
||||
for(s = 1; s < size; s++) {
|
||||
if(src[s] == prev && count < 255) {
|
||||
count++;
|
||||
} else {
|
||||
if(count <= 1 && (prev < scpak_mark8_1 || prev > scpak_mark8_3)) {
|
||||
if(count == 0) {
|
||||
dest[d] = prev;
|
||||
d++;
|
||||
} else {
|
||||
dest[d] = prev;
|
||||
dest[d+1] = prev;
|
||||
d+=2;
|
||||
}
|
||||
} else {
|
||||
if(prev == 0) {
|
||||
dest[d] = scpak_mark8_3;
|
||||
dest[d+1] = (unsigned char)count;
|
||||
d+=2;
|
||||
} else {
|
||||
if(count <= 15 && prev <=15) {
|
||||
dest[d] = scpak_mark8_2;
|
||||
dest[d+1] = prev | (count << 4);
|
||||
d+=2;
|
||||
} else {
|
||||
dest[d] = scpak_mark8_1;
|
||||
dest[d+1] = prev;
|
||||
dest[d+2] = (unsigned char)count;
|
||||
d+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
prev = src[s];
|
||||
if(d >= size - 3) break;
|
||||
}
|
||||
}
|
||||
if(count <= 1 && (prev < scpak_mark8_1 || prev > scpak_mark8_3)) {
|
||||
if(count == 0) {
|
||||
dest[d] = prev;
|
||||
d++;
|
||||
} else {
|
||||
dest[d] = prev;
|
||||
dest[d+1] = prev;
|
||||
d+=2;
|
||||
}
|
||||
} else {
|
||||
if(prev == 0) {
|
||||
dest[d] = scpak_mark8_3;
|
||||
dest[d+1] = (unsigned char)count;
|
||||
d+=2;
|
||||
} else {
|
||||
if(count <= 15 && prev <= 15) {
|
||||
dest[d] = scpak_mark8_2;
|
||||
dest[d+1] = prev | (count << 4);
|
||||
d+=2;
|
||||
} else {
|
||||
dest[d] = scpak_mark8_1;
|
||||
dest[d+1] = prev;
|
||||
dest[d+2] = (unsigned char) count;
|
||||
d+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d > size - 3) return 0;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
int scpak_unpack_8b(int size, unsigned const char* src, unsigned char* dest, int maxDestSize) {
|
||||
int s;
|
||||
int d = 0;
|
||||
short count = 0;
|
||||
unsigned char rep;
|
||||
|
||||
if(size < 1) return 0;
|
||||
|
||||
if(maxDestSize == 0)
|
||||
maxDestSize = 0x7fffffff - 256; // Should really be INT_MAX - 256. (This ok for 32 bit.)
|
||||
|
||||
for(s = 0; s < size; s++) {
|
||||
rep = src[s];
|
||||
if(rep < scpak_mark8_1 || rep > scpak_mark8_3) {
|
||||
if(d >= maxDestSize) {
|
||||
return 0;
|
||||
}
|
||||
dest[d] = rep;
|
||||
d++;
|
||||
} else {
|
||||
if(rep == scpak_mark8_1) {
|
||||
rep = src[s+1];
|
||||
count = src[s+2];
|
||||
s+=2;
|
||||
} else {
|
||||
if(rep == scpak_mark8_3) {
|
||||
rep = 0;
|
||||
count = src[s+1];
|
||||
s++;
|
||||
} else {
|
||||
rep = src[s+1] & 15;
|
||||
count = src[s+1] >> 4;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if(d + count + 1 > maxDestSize) {
|
||||
/*count = maxDestSize - d - 1;
|
||||
for( ; count >= 0; count--) {
|
||||
dest[d] = rep;
|
||||
d++;
|
||||
}
|
||||
assert(d == maxDestSize);
|
||||
break;*/
|
||||
return 0;
|
||||
}
|
||||
for( ; count >= 0; count--) {
|
||||
dest[d] = rep;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
int scpak_pack_16b(int size, unsigned const short* src, unsigned short* dest) {
|
||||
int s;
|
||||
int d = 0;
|
||||
short count = 0;
|
||||
unsigned short prev;
|
||||
|
||||
if(size < 1) return 0;
|
||||
|
||||
size = ((size+1) >> 1);
|
||||
prev = src[0];
|
||||
|
||||
for(s = 1; s < size; s++) {
|
||||
if(src[s] == prev && count < 255) {
|
||||
count++;
|
||||
} else {
|
||||
if(count <= 1 && (prev < scpak_mark16_1 || prev > scpak_mark16_3)) {
|
||||
if(count == 0) {
|
||||
dest[d] = prev;
|
||||
d++;
|
||||
} else {
|
||||
dest[d] = prev;
|
||||
dest[d+1] = prev;
|
||||
d+=2;
|
||||
}
|
||||
} else {
|
||||
if(prev == 0) {
|
||||
dest[d] = scpak_mark16_3;
|
||||
dest[d+1] = count;
|
||||
d+=2;
|
||||
} else {
|
||||
if(count <= 255 && prev <= 255) {
|
||||
dest[d] = scpak_mark16_2;
|
||||
dest[d+1] = prev | (count << 8);
|
||||
d+=2;
|
||||
} else {
|
||||
dest[d] = scpak_mark16_1;
|
||||
dest[d+1] = prev;
|
||||
dest[d+2] = count;
|
||||
d+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
prev = src[s];
|
||||
if(d >= size-3) break;
|
||||
}
|
||||
}
|
||||
if(count <= 1 && (prev < scpak_mark16_1 || prev > scpak_mark16_3)) {
|
||||
if(count == 0) {
|
||||
dest[d] = prev;
|
||||
d++;
|
||||
} else {
|
||||
dest[d] = prev;
|
||||
dest[d+1] = prev;
|
||||
d+=2;
|
||||
}
|
||||
} else {
|
||||
if(prev == 0) {
|
||||
dest[d] = scpak_mark16_3;
|
||||
dest[d+1] = count;
|
||||
d+=2;
|
||||
} else {
|
||||
if(count <= 255 && prev <= 255) {
|
||||
dest[d] = scpak_mark16_2;
|
||||
dest[d+1] = prev | (count << 8);
|
||||
d+=2;
|
||||
} else {
|
||||
dest[d] = scpak_mark16_1;
|
||||
dest[d+1] = prev;
|
||||
dest[d+2] = count;
|
||||
d+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d > size-3) return 0;
|
||||
|
||||
return d*2;
|
||||
}
|
||||
|
||||
int scpak_unpack_16b(int size, unsigned const short* src, unsigned short* dest, int maxDestSize) {
|
||||
int s;
|
||||
int d = 0;
|
||||
short count = 0;
|
||||
unsigned short rep;
|
||||
|
||||
if(size < 1) return 0;
|
||||
|
||||
assert((maxDestSize & 1) == 0);
|
||||
|
||||
maxDestSize = (maxDestSize >> 1);
|
||||
if(maxDestSize == 0)
|
||||
maxDestSize = 0x7fffffff - 256; // This should be INT_MAX - 256. (This is ok for 32 bit.)
|
||||
|
||||
size = ((size+1) >> 1);
|
||||
|
||||
for(s = 0; s < size; s++) {
|
||||
rep = src[s];
|
||||
if(rep < scpak_mark16_1 || rep > scpak_mark16_3) {
|
||||
if(d > maxDestSize) {
|
||||
return 0;
|
||||
}
|
||||
dest[d] = rep;
|
||||
d++;
|
||||
} else {
|
||||
if(rep == scpak_mark16_1) {
|
||||
rep = src[s+1];
|
||||
count = src[s+2];
|
||||
s+=2;
|
||||
} else {
|
||||
if(rep == scpak_mark16_3) {
|
||||
rep = 0;
|
||||
count = src[s+1];
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if(d + count + 1 > maxDestSize) {
|
||||
return 0;
|
||||
}
|
||||
for( ; count >= 0; count--) {
|
||||
dest[d] = rep;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return d*2;
|
||||
}
|
||||
|
||||
int scpak_pack(int size, unsigned const char* src, unsigned char* dest) {
|
||||
if(scpak_bits == 8) {
|
||||
return scpak_pack_8b(size, src, dest);
|
||||
} else {
|
||||
if(scpak_bits == 16)
|
||||
return scpak_pack_16b(size, (unsigned const short*)src, (unsigned short*)dest);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scpak_unpack(int size, unsigned const char* src, unsigned char* dest, int maxDestSize) {
|
||||
if(scpak_bits == 8) {
|
||||
return scpak_unpack_8b(size, src, dest, maxDestSize);
|
||||
} else {
|
||||
if(scpak_bits == 16)
|
||||
return scpak_unpack_16b(size, (unsigned const short*)src, (unsigned short*)dest, maxDestSize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Size reflects the size of the unpacked source buffer. Destination should be
|
||||
// slightly over allocated to be save. There is no predefined rule for the destination
|
||||
// buffer over allocation, +16 bytes will be nice ;)
|
||||
//
|
||||
// If using 16 bit packing, buffer sizes must be padded to 2 byte size (pas source with zeroes!)
|
||||
// returns 0 if packed data would have been larger than source, in which case you need to handle it
|
||||
// differently..
|
||||
extern int scpak_pack(int size, unsigned const char* src, unsigned char* dest);
|
||||
|
||||
// Size reflects the size of the unpacked source buffer, destination buffer should be large
|
||||
// enough to fin the unpacked data (size of unpacked data should be written in the
|
||||
// packfile or somewhere...) maxDestSize gives the maximum allowed size for unpacked data
|
||||
// or if 0, no limit (could cause a buffer overflow...)
|
||||
extern int scpak_unpack(int size, unsigned const char* src, unsigned char* dest, int maxDestSize = 0);
|
||||
|
||||
// 8 or 16 bit supported.
|
||||
extern void scpak_set_bits(unsigned char bits);
|
||||
|
||||
extern void scpak_set_8bit_params(unsigned char mark1, unsigned char mark2, unsigned char mark3);
|
||||
extern void scpak_set_16bit_params(unsigned short mark1, unsigned short mark2, unsigned short mark3);
|
||||
|
@ -1,375 +0,0 @@
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
// Minizip! -- Included this in libs as it is a bit of a pain.
|
||||
#include "../../../Libs/MiniZip/unzip.h"
|
||||
|
||||
#include "EmptyBuffer.h"
|
||||
#include "IFileList.h"
|
||||
#include "../Convert/str2int.h"
|
||||
#include "../Debug.h"
|
||||
#include "ZipPackage.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
namespace {
|
||||
|
||||
static const int BUFFER_SIZE = 100*1024;
|
||||
|
||||
// --
|
||||
|
||||
void ConvertLower(std::string& str) {
|
||||
for(unsigned int i = 0; i < str.size(); ++i) {
|
||||
str[i] = tolower(str[i]);
|
||||
if(str[i] == '\\')
|
||||
str[i] = '/';
|
||||
}
|
||||
}
|
||||
|
||||
int FindTokenIndex(const std::string& str, const std::string& token, std::string::size_type start) {
|
||||
if(token.size() >= str.size() - start)
|
||||
return str.npos;
|
||||
|
||||
for(std::string::size_type i = start; i <= str.size() - token.size(); ++i) {
|
||||
bool found = true;
|
||||
for(std::string::size_type j = 0; j < token.size(); ++j) {
|
||||
if(token[j] != str[i+j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
return i;
|
||||
}
|
||||
return str.npos;
|
||||
}
|
||||
|
||||
bool ContainsToken(const std::string& string, const std::string& token, std::string::size_type start) {
|
||||
if(start + token.size() >= string.size())
|
||||
return false;
|
||||
|
||||
for(unsigned int i = 0; i < token.size(); ++i) {
|
||||
if(token[i] != string[i+start])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FindTokens(const std::string& string, std::vector<std::string>& result, const std::string& seperator) {
|
||||
std::string::size_type start = string.find_first_of(seperator);
|
||||
if(start == string.npos) {
|
||||
result.push_back(string);
|
||||
return;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
std::string::size_type end = string.find_first_of(seperator, start + 1);
|
||||
if(end == string.npos) {
|
||||
std::string token = string.substr(start+1, string.size() - start - 1);
|
||||
result.push_back(token);
|
||||
break;
|
||||
}
|
||||
std::string token = string.substr(start,end-start);
|
||||
result.push_back(token);
|
||||
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
|
||||
/*void AddFile(std::string& file, IFileList& result) {
|
||||
std::vector<std::string> dirs;
|
||||
FindTokens(file, dirs, "/");
|
||||
|
||||
std::stack<FileList:Dir*> dirsStack;
|
||||
dirStack.push(&result.root);
|
||||
|
||||
for(unsigned int i = 0; i < dirs.size() - 1; ++i) {
|
||||
const std::string& dirName = dirs[i];
|
||||
|
||||
FileList::Dir* current = dirStack.top();
|
||||
int index = current->FindDirIndex(dirName);
|
||||
if(index == -1) {
|
||||
FileList::Dir newDir;
|
||||
newDir.name = dirName;
|
||||
current->dirs.push_back(newDir);
|
||||
index = current->dirs.size() - 1;
|
||||
}
|
||||
dirStack.push(¤t->dirs[index]);
|
||||
}
|
||||
FileList::Dir* final = dirStack.top();
|
||||
final->files.puch_back(dirs[dirs.size() - 1]);
|
||||
}*/
|
||||
|
||||
struct ZipFileData {
|
||||
int size;
|
||||
unz_file_pos filePosition;
|
||||
|
||||
ZipFileData(void) : size(0) {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<std::string, ZipFileData> ZipFileList;
|
||||
|
||||
struct ZipData {
|
||||
unzFile fileId;
|
||||
ZipFileList fileList;
|
||||
|
||||
ZipData(const std::string& archive) : fileId(0) {
|
||||
fileId = unzOpen(archive.c_str());
|
||||
if(fileId)
|
||||
FindFiles();
|
||||
}
|
||||
|
||||
~ZipData(void) {
|
||||
if(fileId)
|
||||
unzClose(fileId);
|
||||
}
|
||||
|
||||
void FindFiles(void) {
|
||||
unz_global_info globalInfo = { 0 };
|
||||
if(unzGetGlobalInfo(fileId, &globalInfo) != UNZ_OK)
|
||||
return;
|
||||
|
||||
char file[1024] = { 0 };
|
||||
for(unsigned int i = 0; i < globalInfo.number_entry; ++i) {
|
||||
if(i != 0 && unzGoToNextFile(fileId) != UNZ_OK)
|
||||
break;
|
||||
unz_file_info fileInfo = { 0 };
|
||||
if(unzGetCurrentFileInfo(fileId, &fileInfo, file, sizeof(file) - 1, 0, 0, 0, 0) != UNZ_OK)
|
||||
return;
|
||||
if(fileInfo.uncompressed_size <= 0)
|
||||
continue;
|
||||
|
||||
ZipFileData zipFile;
|
||||
zipFile.size = fileInfo.uncompressed_size;
|
||||
unzGetFilePos(fileId, &zipFile.filePosition);
|
||||
|
||||
std::string filename = file;
|
||||
ConvertLower(filename);
|
||||
fileList[filename] = zipFile;
|
||||
}
|
||||
}
|
||||
|
||||
void FindFiles(std::string dir, std::string extension, IFileList& result) {
|
||||
ConvertLower(dir);
|
||||
ConvertLower(extension);
|
||||
|
||||
if(extension.empty())
|
||||
return;
|
||||
|
||||
std::vector<std::string> tokens;
|
||||
FindTokens(extension, tokens, "*");
|
||||
if(tokens.empty() || tokens.size() > 1)
|
||||
return;
|
||||
|
||||
ZipFileList::iterator it = fileList.begin();
|
||||
for(; it != fileList.end(); ++it) {
|
||||
const std::string& file = it->first;
|
||||
if(!ContainsToken(file, dir, 0))
|
||||
continue;
|
||||
//if(ContainsToken(....)
|
||||
|
||||
std::string::size_type fileStart = file.find_last_of("/");
|
||||
std::string::size_type index = FindTokenIndex(file, tokens[0], fileStart);
|
||||
|
||||
// This will only detect search tokens begining with "*" -- FIXME
|
||||
if(index == file.size() - tokens[0].size())
|
||||
result.AddFile(file);
|
||||
|
||||
/* Eh.. Just find each token index (if there is one..) and move those forward
|
||||
// hierarchically if needed.
|
||||
if(!ContainsToken(file, dir, 0))
|
||||
continue;
|
||||
if*/
|
||||
}
|
||||
}
|
||||
|
||||
bool FindFile(std::string file, ZipFileList::iterator& it) {
|
||||
ConvertLower(file);
|
||||
|
||||
it = fileList.find(file);
|
||||
if(it == fileList.end())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#if READ_CHUNKS
|
||||
class ZipInputBuffer: public IInputStreamBuffer {
|
||||
boost::shared_ptr<ZipData> zipData;
|
||||
unsigned char buffer[BUFFER_SIZE];
|
||||
int currentPosition;
|
||||
int readBytes;
|
||||
unsigned long offset;
|
||||
|
||||
ZipFileData fileData;
|
||||
|
||||
/*void Release(void) const {
|
||||
|
||||
}*/
|
||||
void FillBuffer(void) {
|
||||
beginTime();
|
||||
int readSize = BUFFER_SIZE;
|
||||
if(readBytes + readSize >= fileData.size)
|
||||
readSize = fileData.size - readBytes;
|
||||
|
||||
currentPossition = 0;
|
||||
int id = unzGoToFilePos(zipData->fileId, &fileData.filePosition);
|
||||
if(id != UNZ_OK)
|
||||
return;
|
||||
if(unzOpenCurrentFile(zipData->fileId) != UNZ_OK)
|
||||
return;
|
||||
|
||||
if(offset > 0 && if(unzSetOffset(zipData->fileId, readBytes) != UNZ_OK)
|
||||
return;
|
||||
|
||||
unzReadCurrentFile(fileData->fileId, buffer, readSize);
|
||||
//offset = unzGetOffser(zipData->fileId);
|
||||
unzCloseCurrentFile(zipData->fileId);
|
||||
|
||||
endTime("fileBuffer");
|
||||
}
|
||||
public:
|
||||
ZipInputBuffer(boost::shared_ptr<ZipData>& zipData_, const ZipFileData& fileData_) :
|
||||
zipData(zipData_),
|
||||
fileData(fileData_) {
|
||||
|
||||
currentPosition = -1;
|
||||
readBytes = 0;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
~ZipInputBuffer(void) {
|
||||
}
|
||||
|
||||
unsigned char PopByte(void) {
|
||||
if(!zipData->fileId || readBytes >= fileData.size)
|
||||
FillBuffer();
|
||||
|
||||
++readBytes;
|
||||
return buffer[currentPosition++];
|
||||
}
|
||||
|
||||
bool IsEof(void) const {
|
||||
if(!zipData->fileId || readBytes >= fileData.size)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetSize(void) const {
|
||||
return fileData.size;
|
||||
}
|
||||
|
||||
void PopBytes(char* buffer, int bytes) {
|
||||
for(int i = 0; i < bytes; ++i)
|
||||
buffer[i] = PopByte();
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class ZipInputBuffer : public IInputStreamBuffer {
|
||||
boost::shared_ptr<ZipData> zipData;
|
||||
std::vector<unsigned char> buffer;
|
||||
int position;
|
||||
|
||||
ZipFileData fileData;
|
||||
|
||||
void FillBuffer(void) {
|
||||
int readSize = fileData.size;
|
||||
|
||||
if(unzGoToFilePos(zipData->fileId, &fileData.filePosition) != UNZ_OK)
|
||||
return;
|
||||
if(unzOpenCurrentFile(zipData->fileId) != UNZ_OK)
|
||||
return;
|
||||
|
||||
int bytes = unzReadCurrentFile(zipData->fileId, &buffer[0], readSize);
|
||||
assert(bytes == readSize);
|
||||
|
||||
unzCloseCurrentFile(zipData->fileId);
|
||||
}
|
||||
public:
|
||||
ZipInputBuffer(boost::shared_ptr<ZipData>& zipData_, const ZipFileData& fileData_) :
|
||||
zipData(zipData_),
|
||||
fileData(fileData_) {
|
||||
|
||||
position = 0;
|
||||
}
|
||||
|
||||
~ZipInputBuffer(void) {
|
||||
|
||||
}
|
||||
|
||||
unsigned char PopByte(void) {
|
||||
if(position >= fileData.size)
|
||||
return 0;
|
||||
if(position == 0) {
|
||||
buffer.reserve(fileData.size);
|
||||
FillBuffer();
|
||||
}
|
||||
return buffer[position++];
|
||||
}
|
||||
|
||||
bool IsEof(void) const {
|
||||
if(position >= fileData.size)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetSize(void) const {
|
||||
return fileData.size;
|
||||
}
|
||||
|
||||
void PopBytes(char* buffer, int bytes) {
|
||||
for(int i = 0; i < bytes; ++i)
|
||||
buffer[i] = PopByte();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // Namespace unamed.
|
||||
|
||||
struct ZipPackageData {
|
||||
std::string archiveName;
|
||||
boost::shared_ptr<ZipData> zipData;
|
||||
|
||||
ZipPackageData(void) {
|
||||
}
|
||||
|
||||
void Load(void) {
|
||||
zipData.reset(new ZipData(archiveName));
|
||||
}
|
||||
};
|
||||
|
||||
ZipPackage::ZipPackage(const std::string& archiveName) {
|
||||
boost::scoped_ptr<ZipPackageData> tempData(new ZipPackageData());
|
||||
tempData->archiveName = archiveName;
|
||||
tempData->Load();
|
||||
_data.swap(tempData);
|
||||
}
|
||||
|
||||
ZipPackage::~ZipPackage(void) {
|
||||
|
||||
}
|
||||
|
||||
void ZipPackage::FindFiles(const std::string& dir, const std::string& extension, IFileList& result) {
|
||||
_data->zipData->FindFiles(dir, extension, result);
|
||||
}
|
||||
|
||||
InputStream ZipPackage::GetFile(const std::string& filename) {
|
||||
InputStream inputStream;
|
||||
|
||||
ZipFileList::iterator it;
|
||||
if(_data->zipData->FindFile(filename, it)) {
|
||||
boost::shared_ptr<ZipInputBuffer> inputBuffer(new ZipInputBuffer(_data->zipData, it->second));
|
||||
inputStream.SetBuffer(inputBuffer);
|
||||
} else {
|
||||
boost::shared_ptr<EmptyBuffer> inputBuffer(new EmptyBuffer());
|
||||
inputStream.SetBuffer(inputBuffer);
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
} // Namespace filesystem.
|
||||
} // Namespace saracraft.
|
||||
|
@ -1,22 +0,0 @@
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "IFilePackage.h"
|
||||
|
||||
namespace saracraft {
|
||||
namespace filesystem {
|
||||
|
||||
class IFilePackage;
|
||||
struct ZipPackageData;
|
||||
|
||||
class ZipPackage : public IFilePackage {
|
||||
boost::scoped_ptr<ZipPackageData> _data;
|
||||
public:
|
||||
ZipPackage(const std::string& archiveName);
|
||||
~ZipPackage(void);
|
||||
|
||||
void FindFiles(const std::string& dir, const std::string& extension, IFileList& result);
|
||||
InputStream GetFile(const std::string& filename);
|
||||
};
|
||||
|
||||
} // Namespace saracraft.
|
||||
} // Namespace filesystme.
|
||||
|
Loading…
Reference in New Issue
Block a user