From cc9827cdda5776a4fd540a2ab0fb8a08ec9f75a7 Mon Sep 17 00:00:00 2001 From: Tannin Date: Thu, 17 Jul 2014 22:02:15 +0200 Subject: normalized eol style (all files should now have windows line endings) --- src/dummybsa.cpp | 488 +++++++++++++++++++++++++++---------------------------- 1 file changed, 244 insertions(+), 244 deletions(-) (limited to 'src/dummybsa.cpp') diff --git a/src/dummybsa.cpp b/src/dummybsa.cpp index 3357dea6..df757139 100644 --- a/src/dummybsa.cpp +++ b/src/dummybsa.cpp @@ -1,244 +1,244 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Mod Organizer. If not, see . -*/ - -#include "dummybsa.h" -#include -#include -#define WIN32_LEAN_AND_MEAN -#include - - -static void writeUlong(unsigned char* buffer, int offset, unsigned long value) -{ - union { - unsigned long ulValue; - unsigned char cValue[4]; - }; - ulValue = value; - memcpy(buffer + offset, cValue, 4); -} - -static void writeUlonglong(unsigned char* buffer, int offset, unsigned long long value) -{ - union { - unsigned long long ullValue; - unsigned char cValue[8]; - }; - ullValue = value; - memcpy(buffer + offset, cValue, 8); -} -/* -static unsigned long long genHashInt(const char* pos, const char* end) -{ - unsigned long long hash2 = 0; - for (; pos < end; ++pos) { - hash2 *= 0x1003f; - hash2 += *pos; - } - return hash2; -} - - -static unsigned long long genHash(const char* fileName) -{ - char fileNameLower[MAX_PATH + 1]; - int i = 0; - for (; i < MAX_PATH && fileName[i] != '\0'; ++i) { - fileNameLower[i] = tolower(fileName[i]); - } - fileNameLower[i] = '\0'; - - char* ext = strrchr(fileNameLower, '.'); - if (ext == NULL) { - ext = fileNameLower + strlen(fileNameLower); - } - - int length = ext - fileNameLower; - - unsigned long long hash = 0ULL; - - if (length > 0) { - hash = *(ext - 1) | - ((length > 2 ? *(ext - 2) : 0) << 8) | - (length << 16) | - (fileNameLower[0] << 24); - } - - if (strcmp(ext + 1, "dds") == 0) { - hash |= 0x8080; - } // the rest is not supported currently - - hash |= genHashInt(fileNameLower + 1, ext - 2) << 0x32; - hash |= genHashInt(ext, ext + strlen(ext)) << 0x32; - - return hash; -}*/ - - -static unsigned long genHashInt(const unsigned char *pos, const unsigned char *end) -{ - unsigned long hash = 0; - for (; pos < end; ++pos) { - hash *= 0x1003f; - hash += *pos; - } - return hash; -} - - -static unsigned long long genHash(const char* fileName) -{ - char fileNameLower[MAX_PATH + 1]; - int i = 0; - for (; i < MAX_PATH && fileName[i] != '\0'; ++i) { - fileNameLower[i] = static_cast(tolower(fileName[i])); - if (fileNameLower[i] == '\\') { - fileNameLower[i] = '/'; - } - } - fileNameLower[i] = '\0'; - - unsigned char *fileNameLowerU = reinterpret_cast(fileNameLower); - - char* ext = strrchr(fileNameLower, '.'); - if (ext == NULL) { - ext = fileNameLower + strlen(fileNameLower); - } - unsigned char *extU = reinterpret_cast(ext); - - int length = ext - fileNameLower; - - unsigned long long hash = 0ULL; - - if (length > 0) { - hash = *(extU - 1) | - ((length > 2 ? *(ext - 2) : 0) << 8) | - (length << 16) | - (fileNameLowerU[0] << 24); - } - - if (strlen(ext) > 0) { - if (strcmp(ext + 1, "kf") == 0) { - hash |= 0x80; - } else if (strcmp(ext + 1, "nif") == 0) { - hash |= 0x8000; - } else if (strcmp(ext + 1, "dds") == 0) { - hash |= 0x8080; - } else if (strcmp(ext + 1, "wav") == 0) { - hash |= 0x80000000; - } - - unsigned long long temp = static_cast(genHashInt( - fileNameLowerU + 1, extU - 2)); - temp += static_cast(genHashInt( - extU, extU + strlen(ext))); - - hash |= (temp & 0xFFFFFFFF) << 32; - } - return hash; -} - - -DummyBSA::DummyBSA() - : m_Version(MOShared::GameInfo::instance().getBSAVersion()), m_FolderName(""), m_FileName("dummy.dds"), - m_TotalFileNameLength(0) -{ -} - - -void DummyBSA::writeHeader(QFile& file) -{ - unsigned char header[] = { - 'B', 'S', 'A', '\0', // magic string - 0xDE, 0xAD, 0xBE, 0xEF, // version - insert later - 0x24, 0x00, 0x00, 0x00, // offset to folder recors. header size is static - 0xDE, 0xAD, 0xBE, 0xEF, // archive flags - insert later - 0x01, 0x00, 0x00, 0x00, // folder count - 0x01, 0x00, 0x00, 0x00, // file count - 0xDE, 0xAD, 0xBE, 0xEF, // total folder names length - insert later - 0xDE, 0xAD, 0xBE, 0xEF, // total file names length - insert later - 0xDE, 0xAD, 0xBE, 0xEF // file flags - insert later - }; - - writeUlong(header, 4, MOShared::GameInfo::instance().getBSAVersion()); - writeUlong(header, 12, 0x01 | 0x02); // has directories and has files. - writeUlong(header, 24, m_FolderName.length() + 1); // empty folder name - writeUlong(header, 28, m_TotalFileNameLength); // single character file name - - writeUlong(header, 32, 2); // has dds - - file.write(reinterpret_cast(header), sizeof(header)); -} - - -void DummyBSA::writeFolderRecord(QFile& file, const std::string& folderName) -{ - unsigned char folderRecord[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, // folder hash - 0x01, 0x00, 0x00, 0x00, // file count - 0xDE, 0xAD, 0xBE, 0xEF, // offset to folder name - }; - // we'd usually have to sort folders be the hash value generated here - writeUlonglong(folderRecord, 0, genHash(folderName.c_str())); - writeUlong( folderRecord, 12, 0x34 + m_TotalFileNameLength); // TODO: this should be calculated properly - - file.write(reinterpret_cast(folderRecord), sizeof(folderRecord)); -} - - -void DummyBSA::writeFileRecord(QFile& file, const std::string& fileName) -{ - unsigned char fileRecord[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, // file name hash - 0xDE, 0xAD, 0xBE, 0xEF, // size - 0xDE, 0xAD, 0xBE, 0xEF, // offset to file data - }; - - // we'd usually have to sort files by the value generated here - writeUlonglong(fileRecord, 0, genHash(fileName.c_str())); - writeUlong( fileRecord, 8, 0); - writeUlong( fileRecord, 12, 0x44 + (fileName.length() + 1) + 4); // after this record we expect the filename and 4 bytes of file size - - file.write(reinterpret_cast(fileRecord), sizeof(fileRecord)); -} - - -void DummyBSA::writeFileRecordBlocks(QFile& file, const std::string& folderName) -{ - file.write(folderName.c_str(), folderName.length() + 1); - - writeFileRecord(file, m_FileName); -} - - -void DummyBSA::write(const QString& fileName) -{ - QFile file(fileName); - file.open(QIODevice::WriteOnly); - - m_TotalFileNameLength = m_FileName.length() + 1; - - writeHeader(file); - writeFolderRecord(file, m_FolderName); - writeFileRecordBlocks(file, m_FolderName); - file.write(m_FileName.c_str() , m_FileName.length() + 1); - char fileSize[] = { 0x00, 0x00, 0x00, 0x00 }; - file.write(fileSize, sizeof(fileSize)); - file.close(); -} +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#include "dummybsa.h" +#include +#include +#define WIN32_LEAN_AND_MEAN +#include + + +static void writeUlong(unsigned char* buffer, int offset, unsigned long value) +{ + union { + unsigned long ulValue; + unsigned char cValue[4]; + }; + ulValue = value; + memcpy(buffer + offset, cValue, 4); +} + +static void writeUlonglong(unsigned char* buffer, int offset, unsigned long long value) +{ + union { + unsigned long long ullValue; + unsigned char cValue[8]; + }; + ullValue = value; + memcpy(buffer + offset, cValue, 8); +} +/* +static unsigned long long genHashInt(const char* pos, const char* end) +{ + unsigned long long hash2 = 0; + for (; pos < end; ++pos) { + hash2 *= 0x1003f; + hash2 += *pos; + } + return hash2; +} + + +static unsigned long long genHash(const char* fileName) +{ + char fileNameLower[MAX_PATH + 1]; + int i = 0; + for (; i < MAX_PATH && fileName[i] != '\0'; ++i) { + fileNameLower[i] = tolower(fileName[i]); + } + fileNameLower[i] = '\0'; + + char* ext = strrchr(fileNameLower, '.'); + if (ext == NULL) { + ext = fileNameLower + strlen(fileNameLower); + } + + int length = ext - fileNameLower; + + unsigned long long hash = 0ULL; + + if (length > 0) { + hash = *(ext - 1) | + ((length > 2 ? *(ext - 2) : 0) << 8) | + (length << 16) | + (fileNameLower[0] << 24); + } + + if (strcmp(ext + 1, "dds") == 0) { + hash |= 0x8080; + } // the rest is not supported currently + + hash |= genHashInt(fileNameLower + 1, ext - 2) << 0x32; + hash |= genHashInt(ext, ext + strlen(ext)) << 0x32; + + return hash; +}*/ + + +static unsigned long genHashInt(const unsigned char *pos, const unsigned char *end) +{ + unsigned long hash = 0; + for (; pos < end; ++pos) { + hash *= 0x1003f; + hash += *pos; + } + return hash; +} + + +static unsigned long long genHash(const char* fileName) +{ + char fileNameLower[MAX_PATH + 1]; + int i = 0; + for (; i < MAX_PATH && fileName[i] != '\0'; ++i) { + fileNameLower[i] = static_cast(tolower(fileName[i])); + if (fileNameLower[i] == '\\') { + fileNameLower[i] = '/'; + } + } + fileNameLower[i] = '\0'; + + unsigned char *fileNameLowerU = reinterpret_cast(fileNameLower); + + char* ext = strrchr(fileNameLower, '.'); + if (ext == NULL) { + ext = fileNameLower + strlen(fileNameLower); + } + unsigned char *extU = reinterpret_cast(ext); + + int length = ext - fileNameLower; + + unsigned long long hash = 0ULL; + + if (length > 0) { + hash = *(extU - 1) | + ((length > 2 ? *(ext - 2) : 0) << 8) | + (length << 16) | + (fileNameLowerU[0] << 24); + } + + if (strlen(ext) > 0) { + if (strcmp(ext + 1, "kf") == 0) { + hash |= 0x80; + } else if (strcmp(ext + 1, "nif") == 0) { + hash |= 0x8000; + } else if (strcmp(ext + 1, "dds") == 0) { + hash |= 0x8080; + } else if (strcmp(ext + 1, "wav") == 0) { + hash |= 0x80000000; + } + + unsigned long long temp = static_cast(genHashInt( + fileNameLowerU + 1, extU - 2)); + temp += static_cast(genHashInt( + extU, extU + strlen(ext))); + + hash |= (temp & 0xFFFFFFFF) << 32; + } + return hash; +} + + +DummyBSA::DummyBSA() + : m_Version(MOShared::GameInfo::instance().getBSAVersion()), m_FolderName(""), m_FileName("dummy.dds"), + m_TotalFileNameLength(0) +{ +} + + +void DummyBSA::writeHeader(QFile& file) +{ + unsigned char header[] = { + 'B', 'S', 'A', '\0', // magic string + 0xDE, 0xAD, 0xBE, 0xEF, // version - insert later + 0x24, 0x00, 0x00, 0x00, // offset to folder recors. header size is static + 0xDE, 0xAD, 0xBE, 0xEF, // archive flags - insert later + 0x01, 0x00, 0x00, 0x00, // folder count + 0x01, 0x00, 0x00, 0x00, // file count + 0xDE, 0xAD, 0xBE, 0xEF, // total folder names length - insert later + 0xDE, 0xAD, 0xBE, 0xEF, // total file names length - insert later + 0xDE, 0xAD, 0xBE, 0xEF // file flags - insert later + }; + + writeUlong(header, 4, MOShared::GameInfo::instance().getBSAVersion()); + writeUlong(header, 12, 0x01 | 0x02); // has directories and has files. + writeUlong(header, 24, m_FolderName.length() + 1); // empty folder name + writeUlong(header, 28, m_TotalFileNameLength); // single character file name + + writeUlong(header, 32, 2); // has dds + + file.write(reinterpret_cast(header), sizeof(header)); +} + + +void DummyBSA::writeFolderRecord(QFile& file, const std::string& folderName) +{ + unsigned char folderRecord[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, // folder hash + 0x01, 0x00, 0x00, 0x00, // file count + 0xDE, 0xAD, 0xBE, 0xEF, // offset to folder name + }; + // we'd usually have to sort folders be the hash value generated here + writeUlonglong(folderRecord, 0, genHash(folderName.c_str())); + writeUlong( folderRecord, 12, 0x34 + m_TotalFileNameLength); // TODO: this should be calculated properly + + file.write(reinterpret_cast(folderRecord), sizeof(folderRecord)); +} + + +void DummyBSA::writeFileRecord(QFile& file, const std::string& fileName) +{ + unsigned char fileRecord[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, // file name hash + 0xDE, 0xAD, 0xBE, 0xEF, // size + 0xDE, 0xAD, 0xBE, 0xEF, // offset to file data + }; + + // we'd usually have to sort files by the value generated here + writeUlonglong(fileRecord, 0, genHash(fileName.c_str())); + writeUlong( fileRecord, 8, 0); + writeUlong( fileRecord, 12, 0x44 + (fileName.length() + 1) + 4); // after this record we expect the filename and 4 bytes of file size + + file.write(reinterpret_cast(fileRecord), sizeof(fileRecord)); +} + + +void DummyBSA::writeFileRecordBlocks(QFile& file, const std::string& folderName) +{ + file.write(folderName.c_str(), folderName.length() + 1); + + writeFileRecord(file, m_FileName); +} + + +void DummyBSA::write(const QString& fileName) +{ + QFile file(fileName); + file.open(QIODevice::WriteOnly); + + m_TotalFileNameLength = m_FileName.length() + 1; + + writeHeader(file); + writeFolderRecord(file, m_FolderName); + writeFileRecordBlocks(file, m_FolderName); + file.write(m_FileName.c_str() , m_FileName.length() + 1); + char fileSize[] = { 0x00, 0x00, 0x00, 0x00 }; + file.write(fileSize, sizeof(fileSize)); + file.close(); +} -- cgit v1.3.1