2381 lines
82 KiB
C++
2381 lines
82 KiB
C++
// ==============================================================
|
||
//This file is part of Glest Shared Library (www.glest.org)
|
||
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
|
||
|
||
//You can redistribute this code and/or modify it under
|
||
//the terms of the GNU General Public License as published by the Free Software
|
||
//Foundation; either version 2 of the License, or (at your option) any later
|
||
//version.
|
||
|
||
#ifdef WIN32
|
||
#include <winsock2.h>
|
||
#include <winsock.h>
|
||
#endif
|
||
|
||
#include "platform_common.h"
|
||
#include "cache_manager.h"
|
||
|
||
#ifdef WIN32
|
||
|
||
#include <io.h>
|
||
#include <dbghelp.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <direct.h>
|
||
|
||
#else
|
||
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <unistd.h>
|
||
|
||
#endif
|
||
|
||
#if __cplusplus > 199711L
|
||
#include <chrono>
|
||
#else
|
||
#include <time.h>
|
||
#endif
|
||
|
||
#ifdef WIN32
|
||
#define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR)
|
||
#elif defined(__GNUC__)
|
||
|
||
#else
|
||
#error "Your compiler needs to support S_IFDIR!"
|
||
#endif
|
||
|
||
#include <iostream>
|
||
#include <sstream>
|
||
#include <cassert>
|
||
|
||
#include <glob.h>
|
||
#include <errno.h>
|
||
#include <string.h>
|
||
|
||
#include <SDL.h>
|
||
|
||
#include "util.h"
|
||
#include "conversion.h"
|
||
#include "leak_dumper.h"
|
||
#include "sdl_private.h"
|
||
#include "window.h"
|
||
#include "noimpl.h"
|
||
|
||
#include "checksum.h"
|
||
#include "socket.h"
|
||
#include <algorithm>
|
||
#include <map>
|
||
#include "randomgen.h"
|
||
#include <algorithm>
|
||
#include "platform_util.h"
|
||
#include "utf8.h"
|
||
#include "byte_order.h"
|
||
|
||
#if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|
||
#include <unistd.h>
|
||
#include <sys/types.h>
|
||
#include <pwd.h>
|
||
#endif
|
||
|
||
#ifdef __APPLE__
|
||
#include <mach-o/dyld.h>
|
||
#include <sys/param.h>
|
||
#endif
|
||
|
||
#include "leak_dumper.h"
|
||
|
||
|
||
using namespace Shared::Platform;
|
||
using namespace Shared::Util;
|
||
using namespace std;
|
||
|
||
#define _DISABLE_MEMORY_VAULT_CHECKS 1
|
||
|
||
namespace Shared { namespace PlatformCommon {
|
||
|
||
const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24;
|
||
static string crcCachePath = "";
|
||
|
||
static string gameVersion = "";
|
||
static string gameGITVersion = "";
|
||
|
||
namespace Private {
|
||
|
||
bool shouldBeFullscreen = false;
|
||
int ScreenWidth = 800;
|
||
int ScreenHeight = 600;
|
||
|
||
}
|
||
|
||
/*
|
||
A thread safe localtime proxy
|
||
*/
|
||
tm threadsafe_localtime(const time_t &time) {
|
||
tm tm_snapshot;
|
||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||
localtime_s(&tm_snapshot, &time);
|
||
#else
|
||
localtime_r(&time, &tm_snapshot); // POSIX
|
||
#endif
|
||
return tm_snapshot;
|
||
}
|
||
|
||
// extracting std::time_t from std:chrono for "now"
|
||
time_t systemtime_now() {
|
||
#if __cplusplus > 199711L
|
||
system_time_point system_now = std::chrono::system_clock::now();
|
||
return std::chrono::system_clock::to_time_t(system_now);
|
||
#else
|
||
return time(NULL);
|
||
#endif
|
||
}
|
||
|
||
|
||
// =====================================
|
||
// PerformanceTimer
|
||
// =====================================
|
||
|
||
void PerformanceTimer::init(float fps, int maxTimes) {
|
||
this->times = 0;
|
||
this->maxTimes = maxTimes;
|
||
this->lastTicks = SDL_GetTicks();
|
||
this->updateTicks = static_cast<int>(1000.0f / fps);
|
||
}
|
||
|
||
bool PerformanceTimer::isTime() {
|
||
Uint32 thisTicks = SDL_GetTicks();
|
||
|
||
if((thisTicks - lastTicks) >= updateTicks &&
|
||
times < maxTimes) {
|
||
|
||
lastTicks += updateTicks;
|
||
times++;
|
||
return true;
|
||
}
|
||
times = 0;
|
||
return false;
|
||
}
|
||
|
||
void PerformanceTimer::reset() {
|
||
lastTicks = SDL_GetTicks();
|
||
}
|
||
|
||
// =====================================
|
||
// Chrono
|
||
// =====================================
|
||
|
||
Chrono::Chrono(bool autoStart) {
|
||
freq = 1000;
|
||
stopped = true;
|
||
accumCount = 0;
|
||
|
||
lastStartCount = 0;
|
||
lastTickCount = 0;
|
||
lastResult = 0;
|
||
lastMultiplier = 0;
|
||
lastStopped = false;
|
||
startCount = 0;
|
||
|
||
if(autoStart == true) {
|
||
start();
|
||
}
|
||
}
|
||
|
||
bool Chrono::isStarted() const {
|
||
return (stopped == false);
|
||
}
|
||
|
||
void Chrono::start() {
|
||
stopped = false;
|
||
startCount = SDL_GetTicks();
|
||
}
|
||
|
||
void Chrono::stop() {
|
||
Uint32 endCount = SDL_GetTicks();
|
||
accumCount += endCount - startCount;
|
||
stopped = true;
|
||
}
|
||
|
||
void Chrono::reset() {
|
||
accumCount = 0;
|
||
lastStartCount = 0;
|
||
lastTickCount = 0;
|
||
lastResult = 0;
|
||
lastMultiplier = 0;
|
||
|
||
startCount = SDL_GetTicks();
|
||
}
|
||
|
||
int64 Chrono::getMicros() {
|
||
return queryCounter(1000000);
|
||
}
|
||
|
||
int64 Chrono::getMillis() {
|
||
return queryCounter(1000);
|
||
}
|
||
|
||
int64 Chrono::getSeconds() {
|
||
return queryCounter(1);
|
||
}
|
||
|
||
int64 Chrono::queryCounter(int64 multiplier) {
|
||
|
||
if( multiplier == lastMultiplier &&
|
||
stopped == lastStopped &&
|
||
lastStartCount == startCount) {
|
||
|
||
if(stopped == true) {
|
||
return lastResult;
|
||
}
|
||
else {
|
||
Uint32 endCount = SDL_GetTicks();
|
||
if(lastTickCount == endCount) {
|
||
return lastResult;
|
||
}
|
||
}
|
||
}
|
||
|
||
int64 result = 0;
|
||
if(stopped == true) {
|
||
result = multiplier * accumCount / freq;
|
||
}
|
||
else {
|
||
Uint32 endCount = SDL_GetTicks();
|
||
result = multiplier * (accumCount + endCount - startCount) / freq;
|
||
lastTickCount = endCount;
|
||
}
|
||
|
||
lastStartCount = startCount;
|
||
lastResult = result;
|
||
lastMultiplier = multiplier;
|
||
lastStopped = stopped;
|
||
|
||
return result;
|
||
}
|
||
|
||
int64 Chrono::getCurMillis() {
|
||
return SDL_GetTicks();
|
||
}
|
||
int64 Chrono::getCurTicks() {
|
||
return SDL_GetTicks();
|
||
}
|
||
|
||
|
||
|
||
// =====================================
|
||
// Misc
|
||
// =====================================
|
||
|
||
void Tokenize(const string& str,vector<string>& tokens,const string& delimiters) {
|
||
|
||
/*
|
||
// Skip delimiters at beginning.
|
||
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
|
||
// Find first "non-delimiter".
|
||
string::size_type pos = str.find_first_of(delimiters, lastPos);
|
||
|
||
while (string::npos != pos || string::npos != lastPos) {
|
||
// Found a token, add it to the vector.
|
||
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||
// Skip delimiters. Note the "not_of"
|
||
lastPos = str.find_first_not_of(delimiters, pos);
|
||
// Find next "non-delimiter"
|
||
pos = str.find_first_of(delimiters, lastPos);
|
||
}
|
||
*/
|
||
|
||
// Assume textLine contains the line of text to parse.
|
||
string textLine = str;
|
||
|
||
size_t pos = 0;
|
||
while( true ) {
|
||
size_t nextPos = textLine.find( delimiters, pos );
|
||
if( nextPos == textLine.npos ) {
|
||
tokens.push_back(textLine.substr(pos, textLine.length( )));
|
||
break;
|
||
}
|
||
tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) );
|
||
pos = nextPos + delimiters.size();
|
||
}
|
||
|
||
}
|
||
|
||
void findDirs(string path, vector<string> &results, bool errorOnNotFound,bool keepDuplicates) {
|
||
results.clear();
|
||
string currentPath = path;
|
||
endPathWithSlash(currentPath);
|
||
|
||
string searchpath = currentPath + "*.";
|
||
vector<string> current_results;
|
||
findAll(searchpath, current_results, false, errorOnNotFound);
|
||
if(current_results.empty() == false) {
|
||
for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
|
||
const string current_folder = current_results[folder_index];
|
||
const string current_folder_path = currentPath + current_folder;
|
||
|
||
if(isdir(current_folder_path.c_str()) == true) {
|
||
if(keepDuplicates == true || std::find(results.begin(),results.end(),current_folder) == results.end()) {
|
||
results.push_back(current_folder);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
std::sort(results.begin(),results.end());
|
||
}
|
||
|
||
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound,bool keepDuplicates) {
|
||
results.clear();
|
||
size_t pathCount = paths.size();
|
||
for(unsigned int idx = 0; idx < pathCount; idx++) {
|
||
string currentPath = paths[idx];
|
||
endPathWithSlash(currentPath);
|
||
string path = currentPath + "*.";
|
||
vector<string> current_results;
|
||
findAll(path, current_results, false, errorOnNotFound);
|
||
if(current_results.empty() == false) {
|
||
for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
|
||
const string current_folder = current_results[folder_index];
|
||
const string current_folder_path = currentPath + current_folder;
|
||
|
||
if(isdir(current_folder_path.c_str()) == true) {
|
||
if(keepDuplicates == true || std::find(results.begin(),results.end(),current_folder) == results.end()) {
|
||
results.push_back(current_folder);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
std::sort(results.begin(),results.end());
|
||
}
|
||
|
||
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension, bool errorOnNotFound, bool keepDuplicates) {
|
||
results.clear();
|
||
size_t pathCount = paths.size();
|
||
for(unsigned int idx = 0; idx < pathCount; idx++) {
|
||
string currentPath = paths[idx];
|
||
endPathWithSlash(currentPath);
|
||
|
||
string path = currentPath + fileFilter;
|
||
vector<string> current_results;
|
||
findAll(path, current_results, cutExtension, errorOnNotFound);
|
||
if(current_results.empty() == false) {
|
||
for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
|
||
string current_file = current_results[folder_index];
|
||
if(keepDuplicates == true || std::find(results.begin(),results.end(),current_file) == results.end()) {
|
||
results.push_back(current_file);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
std::sort(results.begin(),results.end());
|
||
}
|
||
|
||
//finds all filenames like path and stores them in results
|
||
void findAll(const string &path, vector<string> &results, bool cutExtension, bool errorOnNotFound) {
|
||
results.clear();
|
||
|
||
std::string mypath = path;
|
||
/** Stupid win32 is searching for all files without extension when *. is
|
||
* specified as wildcard
|
||
*/
|
||
if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
|
||
mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
|
||
mypath += "*";
|
||
}
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,mypath.c_str());
|
||
|
||
glob_t globbuf;
|
||
|
||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||
if(res < 0 && errorOnNotFound == true) {
|
||
if(errorOnNotFound) {
|
||
std::stringstream msg;
|
||
msg << "#1 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
}
|
||
else {
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
const char* p = globbuf.gl_pathv[i];
|
||
const char* begin = p;
|
||
for( ; *p != 0; ++p) {
|
||
// strip the path component
|
||
if(*p == '/')
|
||
begin = p+1;
|
||
}
|
||
if(!(strcmp(".", begin)==0 || strcmp("..", begin)==0 || strcmp(".git", begin)==0)) {
|
||
results.push_back(begin);
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SKIPPED SPECIAL FILENAME [%s]\n",__FILE__,__FUNCTION__,__LINE__,begin);
|
||
}
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
if(results.empty() == true && errorOnNotFound == true) {
|
||
throw megaglest_runtime_error("No files found in: " + mypath);
|
||
}
|
||
|
||
if(cutExtension) {
|
||
for (size_t i=0; i<results.size(); ++i){
|
||
results.at(i)=cutLastExt(results.at(i));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
bool isdir(const char *path)
|
||
{
|
||
string friendly_path = path;
|
||
|
||
#ifdef WIN32
|
||
replaceAll(friendly_path, "/", "\\");
|
||
if(EndsWith(friendly_path, "\\") == true) {
|
||
friendly_path.erase(friendly_path.begin() + friendly_path.length() -1);
|
||
}
|
||
#endif
|
||
|
||
#ifdef WIN32
|
||
#if defined(__MINGW32__)
|
||
struct _stat stats;
|
||
#else
|
||
struct _stat64i32 stats;
|
||
#endif
|
||
int result = _wstat(utf8_decode(friendly_path).c_str(), &stats);
|
||
#else
|
||
struct stat stats;
|
||
int result = stat(friendly_path.c_str(), &stats);
|
||
#endif
|
||
bool ret = (result == 0);
|
||
if(ret == true) {
|
||
ret = S_ISDIR(stats.st_mode); // #define S_ISDIR(mode) ((mode) & _S_IFDIR)
|
||
|
||
if(ret == false) {
|
||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] ret = %d\n",__FILE__,__FUNCTION__,__LINE__,friendly_path.c_str(),ret);
|
||
}
|
||
}
|
||
else {
|
||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] ret = %d, result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,friendly_path.c_str(),ret,result,errno);
|
||
}
|
||
//if(ret == false) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] NOT a path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path);
|
||
|
||
return ret;
|
||
}
|
||
|
||
bool fileExists(const string &path) {
|
||
if (path.size() == 0) return false;
|
||
|
||
#ifdef WIN32
|
||
wstring wstr = utf8_decode(path);
|
||
FILE* file= _wfopen(wstr.c_str(), L"rb");
|
||
#else
|
||
FILE* file= fopen(path.c_str(), "rb");
|
||
#endif
|
||
if(file != NULL) {
|
||
fclose(file);
|
||
return true;
|
||
}
|
||
// else {
|
||
//int fileErrno = errno;
|
||
//#ifdef WIN32
|
||
//int fileErrno = errno;
|
||
//DWORD error = GetLastError();
|
||
//string strError = "[#6] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " " + strerror(fileErrno) + " [" + path + "]";
|
||
//#endif
|
||
// }
|
||
return false;
|
||
}
|
||
|
||
void removeFolder(const string &path) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str());
|
||
|
||
string deletePath = path;
|
||
endPathWithSlash(deletePath);
|
||
deletePath += "{,.}*";
|
||
vector<string> results = getFolderTreeContentsListRecursively(deletePath, "", true);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] results.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),results.size());
|
||
|
||
// First delete files
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DELETE FILES\n",__FILE__,__FUNCTION__,__LINE__);
|
||
|
||
for(int i = (int)results.size() -1; i >= 0; --i) {
|
||
string item = results[i];
|
||
|
||
//if(item.find(".git") != string::npos) {
|
||
// printf("!!!!!!!!!!!!!!!!!! FOUND SPECIAL FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
|
||
//}
|
||
|
||
if(isdir(item.c_str()) == false) {
|
||
bool result = removeFile(item);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result);
|
||
}
|
||
}
|
||
// Now delete folders
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DELETE FOLDERS\n",__FILE__,__FUNCTION__,__LINE__);
|
||
|
||
for(int i = (int)results.size() -1; i >= 0; --i) {
|
||
string item = results[i];
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] isdir(item.c_str()) = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(), isdir(item.c_str()));
|
||
if(isdir(item.c_str()) == true) {
|
||
|
||
//printf("~~~~~ REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
|
||
|
||
#ifdef WIN32
|
||
//int result = _rmdir(item.c_str());
|
||
int result = _wrmdir(utf8_decode(item).c_str());
|
||
#else
|
||
int result = rmdir(item.c_str());
|
||
#endif
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result);
|
||
|
||
if(result != 0 && item != path) {
|
||
printf("CANNOT REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
|
||
removeFolder(item);
|
||
}
|
||
}
|
||
}
|
||
|
||
#ifdef WIN32
|
||
//int result = _rmdir(path.c_str());
|
||
int result = _wrmdir(utf8_decode(path).c_str());
|
||
#else
|
||
int result = rmdir(path.c_str());
|
||
#endif
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),result);
|
||
}
|
||
|
||
bool StartsWith(const std::string &str, const std::string &key) {
|
||
return str.find(key) == 0;
|
||
}
|
||
|
||
bool EndsWith(const string &str, const string& key)
|
||
{
|
||
bool result = false;
|
||
if (str.length() >= key.length()) {
|
||
result = (0 == str.compare(max((int)0,(int)str.length() - (int)key.length()), key.length(), key));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
void endPathWithSlash(string &path,bool requireOSSlash) {
|
||
if(EndsWith(path, "/") == false && EndsWith(path, "\\") == false) {
|
||
string seperator = "/";
|
||
if(requireOSSlash == true) {
|
||
#if defined(WIN32)
|
||
seperator = "\\";
|
||
#endif
|
||
}
|
||
path += seperator;
|
||
}
|
||
}
|
||
|
||
string formatPath(string path) {
|
||
replaceAll(path, "\"", "");
|
||
replaceAll(path, "//", "/");
|
||
|
||
return path;
|
||
}
|
||
|
||
void trimPathWithStartingSlash(string &path) {
|
||
if(StartsWith(path, "/") == true || StartsWith(path, "\\") == true) {
|
||
path.erase(path.begin(),path.begin()+1);
|
||
//printf("************* trimPathWithStartingSlash changed path [%s]\n",path.c_str());
|
||
}
|
||
}
|
||
|
||
void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck) {
|
||
// Update paths with /./
|
||
string::size_type pos = path.find("/./");
|
||
if(pos != string::npos && pos != 0) {
|
||
string orig = path;
|
||
path.erase(pos,2);
|
||
//pos--;
|
||
|
||
//printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
|
||
pos = path.find("/./");
|
||
if(pos != string::npos && pos != 0) {
|
||
updatePathClimbingParts(path, processPreviousDirTokenCheck);
|
||
}
|
||
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
}
|
||
pos = path.find("\\.\\");
|
||
if(pos != string::npos && pos != 0) {
|
||
string orig = path;
|
||
path.erase(pos,2);
|
||
//pos--;
|
||
//printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
|
||
pos = path.find("\\.\\");
|
||
if(pos != string::npos && pos != 0) {
|
||
updatePathClimbingParts(path, processPreviousDirTokenCheck);
|
||
}
|
||
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
}
|
||
|
||
// Update paths with ..
|
||
if(processPreviousDirTokenCheck) {
|
||
pos = path.find("..");
|
||
if(pos != string::npos && pos != 0) {
|
||
|
||
string orig = path;
|
||
if(path[pos-1] != ' ' || (path.length() > 2 && path[pos+2] != ' ')) {
|
||
path.erase(pos,2);
|
||
|
||
//printf("#3 [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,orig.c_str(),path.c_str());
|
||
|
||
pos--;
|
||
//pos = pos -1;
|
||
|
||
//printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3b [%d]\n",(int)pos);
|
||
|
||
if(path[pos] == '/' || path[pos] == '\\') {
|
||
path.erase(pos,1);
|
||
|
||
//printf("#4 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
}
|
||
|
||
for(int x = (int)pos; x >= 0; --x) {
|
||
//printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
|
||
|
||
if((path[x] == '/' || path[x] == '\\') && x != (int)pos) {
|
||
//string origLoop = path;
|
||
path.erase(x,(int)pos-x);
|
||
|
||
//printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str());
|
||
break;
|
||
}
|
||
}
|
||
pos = path.find("..");
|
||
}
|
||
else {
|
||
//printf("#6a [%d]\n",(int)pos);
|
||
|
||
//pos = path.find("..",pos+1);
|
||
pos = string::npos;
|
||
|
||
//printf("#6b [%d]\n",(int)pos);
|
||
}
|
||
if(pos != string::npos && pos != 0) {
|
||
updatePathClimbingParts(path,processPreviousDirTokenCheck);
|
||
}
|
||
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
}
|
||
}
|
||
|
||
/*
|
||
string::size_type pos = path.rfind("..");
|
||
if(pos != string::npos && pos != 0) {
|
||
string orig = path;
|
||
path.erase(pos,2);
|
||
pos--;
|
||
if(path[pos] == '/' || path[pos] == '\\') {
|
||
path.erase(pos,1);
|
||
}
|
||
|
||
for(int x = pos; x >= 0; --x) {
|
||
//printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
|
||
|
||
if((path[x] == '/' || path[x] == '\\') && x != pos) {
|
||
path.erase(x,pos-x);
|
||
break;
|
||
}
|
||
}
|
||
|
||
printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||
}
|
||
*/
|
||
}
|
||
|
||
string getCRCCacheFilePath() {
|
||
return crcCachePath;
|
||
}
|
||
|
||
void setCRCCacheFilePath(string path) {
|
||
crcCachePath = path;
|
||
}
|
||
|
||
string getGameVersion() {
|
||
return gameVersion;
|
||
}
|
||
string getGameGITVersion() {
|
||
return gameGITVersion;
|
||
}
|
||
void setGameVersion(string version) {
|
||
gameVersion = version;
|
||
}
|
||
void setGameGITVersion(string git) {
|
||
gameGITVersion = git;
|
||
}
|
||
|
||
string getCRCCacheFileName(std::pair<string,string> cacheKeys) {
|
||
string crcCacheFile = cacheKeys.first + cacheKeys.second;
|
||
return crcCacheFile;
|
||
}
|
||
string getFormattedCRCCacheFileName(std::pair<string,string> cacheKeys) {
|
||
string crcCacheFile = getCRCCacheFileName(cacheKeys);
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] cacheKeys.first = [%s] cacheKeys.second [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,cacheKeys.first.c_str(),cacheKeys.second.c_str());
|
||
|
||
Checksum checksum;
|
||
checksum.addString(crcCacheFile);
|
||
string result = getCRCCacheFilePath() + "CRC_CACHE_" + uIntToStr(checksum.getSum());
|
||
return result;
|
||
}
|
||
std::pair<string,string> getFolderTreeContentsCheckSumCacheKey(vector<string> paths, string pathSearchString, const string &filterFileExt) {
|
||
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1;
|
||
|
||
string cacheKey = "";
|
||
for(unsigned int idx = 0; idx < paths.size(); ++idx) {
|
||
string path = paths[idx] + pathSearchString;
|
||
cacheKey += path + "_" + filterFileExt + "_";
|
||
}
|
||
return make_pair(cacheLookupId,cacheKey);
|
||
}
|
||
|
||
pair<bool,time_t> hasCachedFileCRCValue(string crcCacheFile, uint32 &value) {
|
||
//bool result = false;
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str());
|
||
}
|
||
|
||
pair<bool,time_t> result = make_pair(false,0);
|
||
if(fileExists(crcCacheFile) == true) {
|
||
#ifdef WIN32
|
||
FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"r");
|
||
#else
|
||
FILE *fp = fopen(crcCacheFile.c_str(),"r");
|
||
#endif
|
||
if(fp != NULL) {
|
||
time_t refreshDate = 0;
|
||
uint32 crcValue = 0;
|
||
time_t lastUpdateDate = 0;
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str());
|
||
}
|
||
|
||
char gameVer[500]="";
|
||
char gitVer[500]="";
|
||
char actualFilePath[8096]="";
|
||
int readbytes = fscanf(fp,"%20ld,%20u,%20ld\n%499s\n%499s\n%8095s",
|
||
&refreshDate,
|
||
&crcValue,
|
||
&lastUpdateDate,
|
||
&gameVer[0],
|
||
&gitVer[0],
|
||
&actualFilePath[0]);
|
||
refreshDate = Shared::PlatformByteOrder::fromCommonEndian(refreshDate);
|
||
crcValue = Shared::PlatformByteOrder::fromCommonEndian(crcValue);
|
||
lastUpdateDate = Shared::PlatformByteOrder::fromCommonEndian(lastUpdateDate);
|
||
string readGameVer = Shared::PlatformByteOrder::fromCommonEndian(string(gameVer));
|
||
string readGitVer = Shared::PlatformByteOrder::fromCommonEndian(string(gitVer));
|
||
string readActualFilePath = Shared::PlatformByteOrder::fromCommonEndian(string(actualFilePath));
|
||
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CRC readGameVer [%s] [%s]\n%s\n",readGameVer.c_str(),readGitVer.c_str(),readActualFilePath.c_str());
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s] readbytes = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),readbytes);
|
||
}
|
||
|
||
fclose(fp);
|
||
|
||
struct tm future; /* as in future date */
|
||
future.tm_sec = 0;
|
||
future.tm_min = 0;
|
||
future.tm_hour = 0;
|
||
future.tm_mday = 6; /* 1st */
|
||
future.tm_mon = 6; /* July */
|
||
future.tm_year = 2012 - 1900; /* 2038 in years since 1900 */
|
||
future.tm_isdst = 0; /* Daylight Saving not in affect (UTC) */
|
||
#ifdef _BSD_SOURCE
|
||
future.tm_zone = "UTC";
|
||
#endif
|
||
|
||
time_t tBadCRCDate = mktime( &future );
|
||
|
||
result.second = lastUpdateDate;
|
||
if( readGameVer != "" && readGitVer != "" &&
|
||
refreshDate > 0 &&
|
||
refreshDate > tBadCRCDate &&
|
||
time(NULL) < refreshDate) {
|
||
|
||
result.first = true;
|
||
value = crcValue;
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
//struct tm *loctime = localtime (&refreshDate);
|
||
struct tm loctime = threadsafe_localtime(refreshDate);
|
||
char szBuf1[100]="";
|
||
strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
|
||
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,
|
||
"=-=-=-=- READ CACHE for Cache file [%s] refreshDate = %ld [%s], crcValue = %u\n",
|
||
crcCacheFile.c_str(),refreshDate, szBuf1, crcValue);
|
||
}
|
||
}
|
||
else {
|
||
//time_t now = time(NULL);
|
||
//struct tm *loctime = localtime (&now);
|
||
struct tm loctime = threadsafe_localtime(systemtime_now());
|
||
char szBuf1[100]="";
|
||
strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
|
||
|
||
loctime = threadsafe_localtime(refreshDate);
|
||
char szBuf2[100]="";
|
||
strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime);
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,
|
||
"=-=-=-=- NEED TO CALCULATE CRC for Cache file [%s] now = %ld [%s], refreshDate = %ld [%s], crcValue = %u\n",
|
||
crcCacheFile.c_str(), systemtime_now(), szBuf1, refreshDate, szBuf2, crcValue);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE NOT FOUND(1) for Cache file [%s]\n",crcCacheFile.c_str());
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE NOT FOUND(2) for Cache file [%s]\n",crcCacheFile.c_str());
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
void writeCachedFileCRCValue(string crcCacheFile, uint32 &crcValue, string actualFileName) {
|
||
#ifdef WIN32
|
||
FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"w");
|
||
#else
|
||
FILE *fp = fopen(crcCacheFile.c_str(),"w");
|
||
#endif
|
||
if(fp != NULL) {
|
||
//RandomGen random;
|
||
//int offset = random.randRange(5, 15);
|
||
srand((unsigned int)time(NULL) + (unsigned long)crcCacheFile.length());
|
||
int offset = rand() % 15;
|
||
if(offset == 0) {
|
||
offset = 3;
|
||
}
|
||
time_t now = time(NULL);
|
||
time_t refreshDate = now + (REFRESH_CRC_DAY_SECONDS * offset);
|
||
|
||
//struct tm *loctime = localtime (&refreshDate);
|
||
struct tm loctime = threadsafe_localtime(refreshDate);
|
||
char szBuf1[100]="";
|
||
strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
|
||
|
||
string writeGameVer = Shared::PlatformByteOrder::toCommonEndian(gameVersion);
|
||
string writeGameGITVersion = Shared::PlatformByteOrder::toCommonEndian(gameGITVersion);
|
||
string writeActualFileName = Shared::PlatformByteOrder::toCommonEndian(actualFileName);
|
||
|
||
fprintf(fp,"%20ld,%20u,%20ld",
|
||
Shared::PlatformByteOrder::toCommonEndian(refreshDate),
|
||
Shared::PlatformByteOrder::toCommonEndian(crcValue),
|
||
Shared::PlatformByteOrder::toCommonEndian(now));
|
||
|
||
fprintf(fp,"\n%s\n%s\n%s",
|
||
writeGameVer.c_str(),
|
||
writeGameGITVersion.c_str(),
|
||
writeActualFileName.c_str());
|
||
|
||
fclose(fp);
|
||
|
||
//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"========== Writing CRC Cache offset [%d] refreshDate = %ld [%s], crcValue = %u, file [%s]\n",offset,refreshDate,szBuf1,crcValue,crcCacheFile.c_str());
|
||
}
|
||
}
|
||
|
||
void clearFolderTreeContentsCheckSum(vector<string> paths, string pathSearchString, const string &filterFileExt) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
crcTreeCache.erase(cacheKey);
|
||
}
|
||
for(unsigned int idx = 0; idx < paths.size(); ++idx) {
|
||
string path = paths[idx];
|
||
clearFolderTreeContentsCheckSum(path, filterFileExt);
|
||
}
|
||
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
if(fileExists(crcCacheFile) == true) {
|
||
|
||
bool result = removeFile(crcCacheFile);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
|
||
}
|
||
}
|
||
|
||
time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(vector<string> paths, string pathSearchString, const string &filterFileExt) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,pathSearchString.c_str());
|
||
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt);
|
||
//string cacheLookupId = cacheKeys.first;
|
||
//std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),pathSearchString.c_str());
|
||
|
||
uint32 crcValue = 0;
|
||
pair<bool,time_t> crcResult = hasCachedFileCRCValue(crcCacheFile, crcValue);
|
||
if(crcResult.first == true) {
|
||
//struct tm *loctime = localtime (&crcResult.second);
|
||
struct tm loctime = threadsafe_localtime(crcResult.second);
|
||
char szBuf1[100]="";
|
||
strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1);
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1);
|
||
|
||
return crcResult.second;
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str());
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str());
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
//finds all filenames like path and gets their checksum of all files combined
|
||
uint32 getFolderTreeContentsCheckSumRecursively(vector<string> paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,pathSearchString.c_str());
|
||
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str());
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str());
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str());
|
||
|
||
if(recursiveChecksum == NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),pathSearchString.c_str(),forceNoCache);
|
||
}
|
||
|
||
uint32 crcValue = 0;
|
||
if(forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) {
|
||
crcTreeCache[cacheKey] = crcValue;
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
|
||
if(recursiveChecksum == NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
|
||
}
|
||
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
|
||
if(recursiveChecksum == NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
|
||
}
|
||
}
|
||
|
||
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
|
||
for(unsigned int idx = 0; idx < paths.size(); ++idx) {
|
||
string path = paths[idx] + pathSearchString;
|
||
|
||
getFolderTreeContentsCheckSumRecursively(path, filterFileExt, &checksum, forceNoCache);
|
||
}
|
||
|
||
if(recursiveChecksum != NULL) {
|
||
*recursiveChecksum = checksum;
|
||
}
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Final CRC file count: %d\n",__FILE__,__FUNCTION__,__LINE__,checksum.getFileCount());
|
||
|
||
uint32 result = checksum.getFinalFileListSum();
|
||
//if(forceNoCache == false) {
|
||
crcTreeCache[cacheKey] = result;
|
||
writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey],getCRCCacheFileName(cacheKeys));
|
||
//}
|
||
return result;
|
||
}
|
||
|
||
std::pair<string,string> getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt) {
|
||
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2;
|
||
|
||
string cacheKey = path + "_" + filterFileExt;
|
||
return make_pair(cacheLookupId,cacheKey);
|
||
}
|
||
|
||
void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(path,filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
crcTreeCache.erase(cacheKey);
|
||
}
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
if(fileExists(crcCacheFile) == true) {
|
||
bool result = removeFile(crcCacheFile);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
|
||
}
|
||
}
|
||
|
||
//finds all filenames like path and gets their checksum of all files combined
|
||
uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(path, filterFileExt);
|
||
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str());
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str());
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str());
|
||
|
||
if(recursiveChecksum == NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),path.c_str(),forceNoCache);
|
||
}
|
||
|
||
uint32 crcValue = 0;
|
||
if(forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) {
|
||
crcTreeCache[cacheKey] = crcValue;
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
|
||
if(recursiveChecksum == NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
|
||
}
|
||
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
|
||
if(recursiveChecksum == NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
|
||
}
|
||
}
|
||
|
||
bool topLevelCaller = (recursiveChecksum == NULL);
|
||
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
|
||
|
||
std::string mypath = path;
|
||
// Stupid win32 is searching for all files without extension when *. is
|
||
// specified as wildcard
|
||
//
|
||
if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
|
||
mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
|
||
mypath += "*";
|
||
}
|
||
|
||
glob_t globbuf;
|
||
|
||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||
if(res < 0) {
|
||
std::stringstream msg;
|
||
msg << "#2 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
#endif
|
||
|
||
int fileLoopCount = 0;
|
||
int fileMatchCount = 0;
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
const char* p = globbuf.gl_pathv[i];
|
||
//printf("Line: %d p [%s]\n",__LINE__,p);
|
||
|
||
if(isdir(p) == false) {
|
||
bool addFile = true;
|
||
if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) {
|
||
addFile = false;
|
||
}
|
||
else if(filterFileExt != "") {
|
||
addFile = EndsWith(p, filterFileExt);
|
||
}
|
||
|
||
if(addFile) {
|
||
checksum.addFile(p);
|
||
fileMatchCount++;
|
||
}
|
||
}
|
||
fileLoopCount++;
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
// Look recursively for sub-folders
|
||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||
res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||
#else
|
||
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
|
||
#endif
|
||
|
||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||
if(res < 0) {
|
||
std::stringstream msg;
|
||
msg << "#3 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
#endif
|
||
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||
struct stat statStruct;
|
||
// only process if dir..
|
||
int actStat = lstat( globbuf.gl_pathv[i], &statStruct);
|
||
if( S_ISDIR(statStruct.st_mode) == 0)
|
||
continue;
|
||
#endif
|
||
const char *p = globbuf.gl_pathv[i];
|
||
//printf("Line: %d p [%s]\n",__LINE__,p);
|
||
|
||
string currentPath = p;
|
||
endPathWithSlash(currentPath);
|
||
|
||
getFolderTreeContentsCheckSumRecursively(currentPath + "*", filterFileExt, &checksum, forceNoCache);
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
if(recursiveChecksum != NULL) {
|
||
*recursiveChecksum = checksum;
|
||
}
|
||
|
||
if(topLevelCaller == true) {
|
||
//printf("In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount());
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount());
|
||
|
||
uint32 result = checksum.getFinalFileListSum();
|
||
//if(forceNoCache == false) {
|
||
crcTreeCache[cacheKey] = result;
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] ending checksum = %d for cacheKey [%s] fileMatchCount = %d, fileLoopCount = %d\n",__FILE__,__FUNCTION__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str(),fileMatchCount,fileLoopCount);
|
||
writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey],getCRCCacheFileName(cacheKeys));
|
||
//}
|
||
|
||
return result;
|
||
}
|
||
else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
std::pair<string,string> getFolderTreeContentsCheckSumListCacheKey(vector<string> paths, string pathSearchString, const string &filterFileExt) {
|
||
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1;
|
||
|
||
string cacheKey = "";
|
||
for(unsigned int idx = 0; idx < paths.size(); ++idx) {
|
||
string path = paths[idx] + pathSearchString;
|
||
cacheKey += path + "_" + filterFileExt + "_";
|
||
}
|
||
return make_pair(cacheLookupId,cacheKey);
|
||
}
|
||
|
||
void clearFolderTreeContentsCheckSumList(vector<string> paths, string pathSearchString, const string &filterFileExt) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
crcTreeCache.erase(cacheKey);
|
||
}
|
||
for(unsigned int idx = 0; idx < paths.size(); ++idx) {
|
||
string path = paths[idx];
|
||
clearFolderTreeContentsCheckSumList(path, filterFileExt);
|
||
}
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
if(fileExists(crcCacheFile) == true) {
|
||
bool result = removeFile(crcCacheFile);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
|
||
}
|
||
}
|
||
|
||
vector<std::pair<string,uint32> > getFolderTreeContentsCheckSumListRecursively(vector<string> paths, string pathSearchString, const string &filterFileExt, vector<std::pair<string,uint32> > *recursiveMap) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str());
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
else {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders, NO CACHE found result for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str());
|
||
}
|
||
|
||
bool topLevelCaller = (recursiveMap == NULL);
|
||
|
||
vector<std::pair<string,uint32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,uint32> >() : *recursiveMap);
|
||
for(unsigned int idx = 0; idx < paths.size(); ++idx) {
|
||
string path = paths[idx] + pathSearchString;
|
||
checksumFiles = getFolderTreeContentsCheckSumListRecursively(path, filterFileExt, &checksumFiles);
|
||
}
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size());
|
||
|
||
if(topLevelCaller == true) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size());
|
||
}
|
||
|
||
crcTreeCache[cacheKey] = checksumFiles;
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
|
||
//finds all filenames like path and gets the checksum of each file
|
||
vector<string> getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders, vector<string> *recursiveMap) {
|
||
bool topLevelCaller = (recursiveMap == NULL);
|
||
vector<string> resultFiles = (recursiveMap == NULL ? vector<string>() : *recursiveMap);
|
||
|
||
std::string mypath = path;
|
||
/** Stupid win32 is searching for all files without extension when *. is
|
||
* specified as wildcard
|
||
*/
|
||
if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
|
||
mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
|
||
mypath += "*";
|
||
}
|
||
|
||
glob_t globbuf;
|
||
|
||
int globFlags = 0;
|
||
if(EndsWith(mypath,"{,.}*") == true) {
|
||
#ifndef WIN32
|
||
globFlags = GLOB_BRACE;
|
||
#else
|
||
// Windows glob source cannot handle GLOB_BRACE
|
||
// but that should be ok for win32 platform
|
||
replaceAll(mypath,"{,.}*","*");
|
||
#endif
|
||
}
|
||
|
||
int res = glob(mypath.c_str(), globFlags, 0, &globbuf);
|
||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||
if(res < 0) {
|
||
std::stringstream msg;
|
||
msg << "#4 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
#endif
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
const char* p = globbuf.gl_pathv[i];
|
||
|
||
bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"~~~~~~~~~~~ Glob file [%s] skipItem = %d\n",p,skipItem);
|
||
|
||
if(skipItem == false) {
|
||
if(isdir(p) == false) {
|
||
bool addFile = true;
|
||
if(filterFileExt != "") {
|
||
addFile = EndsWith(p, filterFileExt);
|
||
}
|
||
|
||
if(addFile) {
|
||
resultFiles.push_back(p);
|
||
}
|
||
}
|
||
else if(includeFolders == true) {
|
||
resultFiles.push_back(p);
|
||
}
|
||
}
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
// Look recursively for sub-folders
|
||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||
res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||
#else //APPLE doesn't have the GLOB_ONLYDIR definition..
|
||
globFlags |= GLOB_ONLYDIR;
|
||
res = glob(mypath.c_str(), globFlags, 0, &globbuf);
|
||
#endif
|
||
|
||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||
if(res < 0) {
|
||
std::stringstream msg;
|
||
msg << "#5 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
#endif
|
||
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||
struct stat statStruct;
|
||
// only get if dir..
|
||
int actStat = lstat( globbuf.gl_pathv[ i], &statStruct);
|
||
if( S_ISDIR(statStruct.st_mode) == 0)
|
||
continue;
|
||
#endif
|
||
const char* p = globbuf.gl_pathv[i];
|
||
|
||
bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"~~~~~~~~~~~ Glob folder [%s] skipItem = %d\n",p,skipItem);
|
||
|
||
if(skipItem == false) {
|
||
if(includeFolders == true) {
|
||
resultFiles.push_back(p);
|
||
}
|
||
|
||
string currentPath = p;
|
||
endPathWithSlash(currentPath);
|
||
|
||
if(EndsWith(mypath,"{,.}*") == true) {
|
||
currentPath += "{,.}*";
|
||
}
|
||
else {
|
||
currentPath += "*";
|
||
}
|
||
resultFiles = getFolderTreeContentsListRecursively(currentPath, filterFileExt, includeFolders,&resultFiles);
|
||
}
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
|
||
|
||
if(topLevelCaller == true) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION\n",__FILE__,__FUNCTION__,__LINE__);
|
||
}
|
||
|
||
return resultFiles;
|
||
}
|
||
|
||
std::pair<string,string> getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt) {
|
||
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2;
|
||
|
||
string cacheKey = path + "_" + filterFileExt;
|
||
return make_pair(cacheLookupId,cacheKey);
|
||
}
|
||
|
||
void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path,filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
crcTreeCache.erase(cacheKey);
|
||
}
|
||
string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
|
||
if(fileExists(crcCacheFile) == true) {
|
||
bool result = removeFile(crcCacheFile);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
|
||
}
|
||
}
|
||
|
||
//finds all filenames like path and gets the checksum of each file
|
||
vector<std::pair<string,uint32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,uint32> > *recursiveMap) {
|
||
std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path, filterFileExt);
|
||
string cacheLookupId = cacheKeys.first;
|
||
std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
|
||
|
||
string cacheKey = cacheKeys.second;
|
||
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] FOUND CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str());
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
|
||
bool topLevelCaller = (recursiveMap == NULL);
|
||
vector<std::pair<string,uint32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,uint32> >() : *recursiveMap);
|
||
|
||
std::string mypath = path;
|
||
/** Stupid win32 is searching for all files without extension when *. is
|
||
* specified as wildcard
|
||
*/
|
||
if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
|
||
mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
|
||
mypath += "*";
|
||
}
|
||
|
||
glob_t globbuf;
|
||
|
||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||
|
||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||
if(res < 0) {
|
||
std::stringstream msg;
|
||
msg << "#6 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
#endif
|
||
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
const char* p = globbuf.gl_pathv[i];
|
||
|
||
if(isdir(p) == false) {
|
||
bool addFile = true;
|
||
if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) {
|
||
addFile = false;
|
||
}
|
||
else if(filterFileExt != "") {
|
||
addFile = EndsWith(p, filterFileExt);
|
||
}
|
||
|
||
if(addFile) {
|
||
Checksum checksum;
|
||
checksum.addFile(p);
|
||
|
||
checksumFiles.push_back(std::pair<string,uint32>(p,checksum.getSum()));
|
||
}
|
||
}
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
// Look recursively for sub-folders
|
||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||
res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||
#else //APPLE doesn't have the GLOB_ONLYDIR definition..
|
||
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
|
||
#endif
|
||
|
||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||
if(res < 0) {
|
||
std::stringstream msg;
|
||
msg << "#7 Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||
throw megaglest_runtime_error(msg.str());
|
||
}
|
||
#endif
|
||
|
||
for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
|
||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||
struct stat statStruct;
|
||
// only get if dir..
|
||
int actStat = lstat( globbuf.gl_pathv[ i], &statStruct);
|
||
if( S_ISDIR(statStruct.st_mode) == 0)
|
||
continue;
|
||
#endif
|
||
const char *p = globbuf.gl_pathv[i];
|
||
|
||
string currentPath = p;
|
||
endPathWithSlash(currentPath);
|
||
|
||
checksumFiles = getFolderTreeContentsCheckSumListRecursively(currentPath + "*", filterFileExt, &checksumFiles);
|
||
}
|
||
|
||
globfree(&globbuf);
|
||
|
||
crcTreeCache[cacheKey] = checksumFiles;
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] cacheKey [%s] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str(),checksumFiles.size());
|
||
|
||
if(topLevelCaller == true) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size());
|
||
}
|
||
|
||
return crcTreeCache[cacheKey];
|
||
}
|
||
|
||
string extractFileFromDirectoryPath(string filename) {
|
||
size_t lastDirectory = filename.find_last_of("/\\");
|
||
if (lastDirectory == string::npos) {
|
||
return filename;
|
||
}
|
||
|
||
return filename.erase( 0, lastDirectory + 1);
|
||
}
|
||
|
||
string extractDirectoryPathFromFile(string filename) {
|
||
size_t lastDirectory = filename.find_last_of("/\\");
|
||
string path = "";
|
||
if (lastDirectory != string::npos) {
|
||
path = filename.substr( 0, lastDirectory + 1);
|
||
}
|
||
|
||
return path;
|
||
}
|
||
|
||
string extractLastDirectoryFromPath(string Path) {
|
||
string result = Path;
|
||
size_t lastDirectory = Path.find_last_of("/\\");
|
||
if (lastDirectory == string::npos) {
|
||
result = Path;
|
||
}
|
||
else {
|
||
if(Path.length() > lastDirectory + 1) {
|
||
result = Path.erase( 0, lastDirectory + 1);
|
||
}
|
||
else {
|
||
for(int i = (int)lastDirectory-1; i >= 0; --i) {
|
||
if((Path[i] == '/' || Path[i] == '\\') && i > 0) {
|
||
result = Path.erase( 0, i);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
string extractExtension(const string& filepath) {
|
||
size_t lastPoint = filepath.find_last_of('.');
|
||
size_t lastDirectory = filepath.find_last_of("/\\");
|
||
|
||
if (lastPoint == string::npos || (lastDirectory != string::npos && lastDirectory > lastPoint)) {
|
||
return "";
|
||
}
|
||
return filepath.substr(lastPoint+1);
|
||
}
|
||
|
||
void createDirectoryPaths(string Path) {
|
||
char DirName[256]="";
|
||
const char *path = Path.c_str();
|
||
char *dirName = DirName;
|
||
while(*path) {
|
||
//if (('\\' == *path) || ('/' == *path))
|
||
if ('/' == *path) {
|
||
if(isdir(DirName) == false) {
|
||
#ifdef WIN32
|
||
int result = _wmkdir(utf8_decode(DirName).c_str());
|
||
//int result = _mkdir(DirName);
|
||
#elif defined(__GNUC__)
|
||
int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
|
||
#else
|
||
#error "Your compiler needs to support mkdir!"
|
||
#endif
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno);
|
||
}
|
||
}
|
||
*dirName++ = *path++;
|
||
*dirName = '\0';
|
||
}
|
||
#ifdef WIN32
|
||
//int result = _mkdir(DirName);
|
||
int result = _wmkdir(utf8_decode(DirName).c_str());
|
||
#elif defined(__GNUC__)
|
||
int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
|
||
#else
|
||
#error "Your compiler needs to support mkdir!"
|
||
#endif
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno);
|
||
}
|
||
|
||
void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen) {
|
||
// TTSDL What does this method do ? I have no clue...
|
||
//
|
||
// // Get the current video hardware information
|
||
// //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
|
||
// //colorBits = vidInfo->vfmt->BitsPerPixel;
|
||
// //screenWidth = vidInfo->current_w;
|
||
// //screenHeight = vidInfo->current_h;
|
||
//
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||
//
|
||
// /* Get available fullscreen/hardware modes */
|
||
//
|
||
// #if defined(WIN32) || defined(__APPLE__)
|
||
//
|
||
// int flags = 0;
|
||
//
|
||
// #else
|
||
//
|
||
// int flags = SDL_WINDOW_RESIZABLE;
|
||
//
|
||
// #endif
|
||
// if(isFullscreen) flags = SDL_WINDOW_FULLSCREEN;
|
||
// SDL_Rect**modes = SDL_ListModes(NULL, SDL_OPENGL|flags);
|
||
//
|
||
// /* Check if there are any modes available */
|
||
// if (modes == (SDL_Rect**)0) {
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] no hardware modes available.\n",__FILE__,__FUNCTION__,__LINE__);
|
||
//
|
||
// const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
|
||
// colorBits = vidInfo->vfmt->BitsPerPixel;
|
||
// screenWidth = vidInfo->current_w;
|
||
// screenHeight = vidInfo->current_h;
|
||
//
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
|
||
// }
|
||
// /* Check if our resolution is restricted */
|
||
// else if (modes == (SDL_Rect**)-1) {
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] all resolutions available.\n",__FILE__,__FUNCTION__,__LINE__);
|
||
//
|
||
// const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
|
||
// colorBits = vidInfo->vfmt->BitsPerPixel;
|
||
// screenWidth = vidInfo->current_w;
|
||
// screenHeight = vidInfo->current_h;
|
||
//
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
|
||
// }
|
||
// else{
|
||
// /* Print valid modes */
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] available Modes are:\n",__FILE__,__FUNCTION__,__LINE__);
|
||
//
|
||
// int bestW = -1;
|
||
// int bestH = -1;
|
||
// for(int i=0; modes[i]; ++i) {
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",modes[i]->w, modes[i]->h);
|
||
//
|
||
// if(bestW < modes[i]->w) {
|
||
// bestW = modes[i]->w;
|
||
// bestH = modes[i]->h;
|
||
// }
|
||
// }
|
||
//
|
||
// if(bestW > screenWidth) {
|
||
// screenWidth = bestW;
|
||
// screenHeight = bestH;
|
||
// }
|
||
//
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
|
||
// }
|
||
}
|
||
|
||
|
||
void getFullscreenVideoModes(vector<ModeInfo> *modeinfos, bool isFullscreen) {
|
||
// Get the current video hardware information
|
||
//const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
|
||
//colorBits = vidInfo->vfmt->BitsPerPixel;
|
||
//screenWidth = vidInfo->current_w;
|
||
//screenHeight = vidInfo->current_h;
|
||
|
||
if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled)
|
||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||
|
||
//SDL_PixelFormat format;
|
||
//SDL_Rect **modes;
|
||
//int loops(0);
|
||
//int bpp(0);
|
||
std::map<std::string,bool> uniqueResList;
|
||
|
||
///////////////////////////
|
||
vector<pair<int,int> > allResoltuions;
|
||
SDL_DisplayMode mode = {SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0};
|
||
int max=SDL_GetNumDisplayModes(0);
|
||
for (int i = 0; i < max; ++i) {
|
||
if(0==SDL_GetDisplayMode(0,i,&mode)) {
|
||
int bpp;
|
||
Uint32 Rmask;
|
||
Uint32 Gmask;
|
||
Uint32 Bmask;
|
||
Uint32 Amask;
|
||
SDL_PixelFormatEnumToMasks(mode.format,&bpp,&Rmask,&Gmask,&Bmask,&Amask);
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",allResoltuions[i].first, allResoltuions[i].second,bpp);
|
||
string lookupKey = intToStr(mode.w) + "_" + intToStr(mode.h) + "_" + intToStr(bpp);
|
||
if(uniqueResList.find(lookupKey) == uniqueResList.end()) {
|
||
uniqueResList[lookupKey] = true;
|
||
modeinfos->push_back(ModeInfo(mode.w,mode.h,bpp));
|
||
}
|
||
}
|
||
}
|
||
//////////////////////////////////
|
||
std::sort(modeinfos->begin(),modeinfos->end());
|
||
}
|
||
|
||
|
||
|
||
void changeVideoModeFullScreen(bool value) {
|
||
Private::shouldBeFullscreen = value;
|
||
}
|
||
|
||
void restoreVideoMode(SDL_Window *sdlWindow,bool exitingApp) {
|
||
//SDL_Quit();
|
||
if(exitingApp == true && SDL_WasInit(SDL_INIT_VIDEO)) {
|
||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||
SDL_SetWindowBrightness(sdlWindow, 1.0f);
|
||
}
|
||
}
|
||
|
||
//int getScreenW() {
|
||
// return SDL_GetVideoSurface()->w; //SDL_GetWindowSurface()
|
||
//}
|
||
//
|
||
//int getScreenH() {
|
||
// return SDL_GetVideoSurface()->h;
|
||
//}
|
||
|
||
void sleep(int millis) {
|
||
SDL_Delay(millis);
|
||
}
|
||
|
||
bool isCursorShowing() {
|
||
int state = SDL_ShowCursor(SDL_QUERY);
|
||
return (state == SDL_ENABLE);
|
||
}
|
||
|
||
void showCursor(bool b) {
|
||
//printf("In showCursor, b: %d, isCursorShowing(): %d\n",b,isCursorShowing());
|
||
|
||
|
||
if(isCursorShowing() == b) {
|
||
return;
|
||
}
|
||
//printf("showCursor(bool b) b=%d\n",b);
|
||
SDL_ShowCursor(b == true ? SDL_ENABLE : SDL_DISABLE);
|
||
}
|
||
|
||
//bool isKeyDown(SDLKey key) {
|
||
// const Uint8* keystate = SDL_GetKeyboardState(0);
|
||
//
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key);
|
||
//
|
||
// if(key >= 0) {
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[key]);
|
||
//
|
||
// return (keystate[key] != 0);
|
||
// }
|
||
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__);
|
||
// return false;
|
||
//
|
||
//}
|
||
|
||
bool isKeyDown(int virtualKey) {
|
||
char key = static_cast<char> (virtualKey);
|
||
const Uint8* keystate = SDL_GetKeyboardState(0);
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key);
|
||
|
||
if(key >= 0) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[(unsigned char)key]);
|
||
|
||
return (keystate[(unsigned char)key] != 0);
|
||
}
|
||
switch(key) {
|
||
//SDLTT case vkAdd:
|
||
// return (keystate[SDL_SCANCODE_PLUS] != 0 || keystate[SDL_SCANCODE_KP_PLUS] != 0);
|
||
case vkSubtract:
|
||
return (keystate[SDL_SCANCODE_MINUS] != 0 || keystate[SDL_SCANCODE_KP_MINUS] != 0);
|
||
case vkAlt:
|
||
return (keystate[SDL_SCANCODE_LALT] != 0 || keystate[SDL_SCANCODE_RALT] != 0);
|
||
case vkControl:
|
||
return (keystate[SDL_SCANCODE_LCTRL] != 0 || keystate[SDL_SCANCODE_RCTRL] != 0);
|
||
case vkShift:
|
||
return (keystate[SDL_SCANCODE_LSHIFT] != 0 || keystate[SDL_SCANCODE_RSHIFT] != 0);
|
||
case vkEscape:
|
||
return (keystate[SDL_SCANCODE_ESCAPE] != 0);
|
||
case vkUp:
|
||
return (keystate[SDL_SCANCODE_UP] != 0);
|
||
case vkLeft:
|
||
return (keystate[SDL_SCANCODE_LEFT] != 0);
|
||
case vkRight:
|
||
return (keystate[SDL_SCANCODE_RIGHT] != 0);
|
||
case vkDown:
|
||
return (keystate[SDL_SCANCODE_DOWN] != 0);
|
||
case vkReturn:
|
||
return (keystate[SDL_SCANCODE_RETURN] != 0 || keystate[SDL_SCANCODE_KP_ENTER] != 0);
|
||
case vkBack:
|
||
return (keystate[SDL_SCANCODE_BACKSPACE] != 0);
|
||
case vkDelete:
|
||
return (keystate[SDL_SCANCODE_DELETE] != 0);
|
||
case vkPrint:
|
||
return (keystate[SDL_SCANCODE_PRINTSCREEN] != 0);
|
||
case vkPause:
|
||
return (keystate[SDL_SCANCODE_PAUSE] != 0);
|
||
default:
|
||
std::cerr << "isKeyDown called with unknown key.\n";
|
||
break;
|
||
}
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__);
|
||
return false;
|
||
}
|
||
|
||
string replaceAllHTMLEntities(string& context) {
|
||
replaceAll(context,""","\"");
|
||
replaceAll(context,"&","&");
|
||
replaceAll(context,"<","<");
|
||
replaceAll(context,">",">");
|
||
//replaceAll(context,"Œ","Œ");
|
||
replaceAll(context,"Œ","\xC5\x92\0");
|
||
//replaceAll(context,"œ","œ");
|
||
replaceAll(context,"œ","\xC5\x93\0");
|
||
//replaceAll(context,"Š","Š");
|
||
replaceAll(context,"Š","\xC5\xA0\0");
|
||
//replaceAll(context,"š","š");
|
||
replaceAll(context,"š","\xC5\xA1\0");
|
||
//replaceAll(context,"Ÿ","Ÿ");
|
||
replaceAll(context,"Ÿ","\xC5\xB8\0");
|
||
replaceAll(context,"ˆ","ˆ");
|
||
replaceAll(context,"˜","˜");
|
||
replaceAll(context," "," ");
|
||
replaceAll(context," "," ");
|
||
replaceAll(context," "," ");
|
||
replaceAll(context,"–","-");
|
||
replaceAll(context,"—","-");
|
||
//replaceAll(context,"‘","‘");
|
||
replaceAll(context,"‘","\xE2\x80\x98\0");
|
||
//replaceAll(context,"’","’");
|
||
replaceAll(context,"’","\xE2\x80\x99\0");
|
||
//replaceAll(context,"‚","‚");
|
||
replaceAll(context,"‚","\xE2\x80\x9A\0");
|
||
//replaceAll(context,"“","“");
|
||
replaceAll(context,"“","\xE2\x80\x9C\0");
|
||
//replaceAll(context,"”","”");
|
||
replaceAll(context,"”","\xE2\x80\x9D\0");
|
||
//replaceAll(context,"„","„");
|
||
replaceAll(context,"„","\xE2\x80\x9E\0");
|
||
//replaceAll(context,"†","†");
|
||
replaceAll(context,"†","\xE2\x80\xA0\0");
|
||
//replaceAll(context,"‡","‡");
|
||
replaceAll(context,"‡","\xE2\x80\xA1\0");
|
||
//replaceAll(context,"‰","‰");
|
||
replaceAll(context,"‰","\xE2\x80\xB0\0");
|
||
//replaceAll(context,"‹","‹");
|
||
replaceAll(context,"‹","\xE2\x80\xB9\0");
|
||
//replaceAll(context,"›","›");
|
||
replaceAll(context,"›","\xE2\x80\xBA\0");
|
||
//replaceAll(context,"€","€");
|
||
replaceAll(context,"€","\xE2\x82\xAC\0");
|
||
|
||
return context;
|
||
}
|
||
|
||
string replaceAll(string& context, const string& from, const string& to) {
|
||
size_t lookHere = 0;
|
||
size_t foundHere = 0;
|
||
if((foundHere = context.find(from, lookHere)) != string::npos) {
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str());
|
||
|
||
while((foundHere = context.find(from, lookHere)) != string::npos) {
|
||
context.replace(foundHere, from.size(), to);
|
||
lookHere = foundHere + to.size();
|
||
}
|
||
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str());
|
||
}
|
||
return context;
|
||
}
|
||
|
||
vector<char> replaceAllBetweenTokens(vector<char>& context,
|
||
const string &startToken, const string &endToken, const string &newText,
|
||
bool removeTokens) {
|
||
string newValue(context.begin(),context.end());
|
||
replaceAllBetweenTokens(newValue,startToken,endToken,newText,removeTokens);
|
||
context = vector<char>(newValue.begin(),newValue.end());
|
||
return context;
|
||
}
|
||
|
||
string replaceAllBetweenTokens(string& context, const string &startToken,
|
||
const string &endToken, const string &newText, bool removeTokens) {
|
||
size_t lookHere = 0;
|
||
size_t foundHere = 0;
|
||
if((foundHere = context.find(startToken, lookHere)) != string::npos) {
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str());
|
||
|
||
while((foundHere = context.find(startToken, lookHere)) != string::npos) {
|
||
size_t foundHereEnd = context.find(endToken, foundHere+1);
|
||
if(foundHereEnd == string::npos) {
|
||
break;
|
||
}
|
||
if(removeTokens == true) {
|
||
foundHereEnd += endToken.size();
|
||
|
||
context.replace(foundHere, foundHereEnd-foundHere+1, newText);
|
||
lookHere = foundHere + newText.size();
|
||
}
|
||
else {
|
||
foundHere += startToken.size();
|
||
foundHereEnd -= 1;
|
||
|
||
context.replace(foundHere, foundHereEnd-foundHere+1, newText);
|
||
lookHere = foundHere + newText.size();
|
||
}
|
||
}
|
||
|
||
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str());
|
||
}
|
||
return context;
|
||
}
|
||
|
||
string getFullFileArchiveExtractCommand(string fileArchiveExtractCommand,
|
||
string fileArchiveExtractCommandParameters, string outputpath, string archivename) {
|
||
string parsedOutputpath = outputpath;
|
||
string parsedArchivename = archivename;
|
||
|
||
// This is required for execution on win32
|
||
#if defined(WIN32)
|
||
replaceAll(parsedOutputpath, "\\\\", "\\");
|
||
replaceAll(parsedOutputpath, "/", "\\");
|
||
replaceAll(parsedArchivename, "\\\\", "\\");
|
||
replaceAll(parsedArchivename, "/", "\\");
|
||
#endif
|
||
|
||
string result = fileArchiveExtractCommand;
|
||
result += " ";
|
||
string args = replaceAll(fileArchiveExtractCommandParameters, "{outputpath}", parsedOutputpath);
|
||
args = replaceAll(args, "{archivename}", parsedArchivename);
|
||
result += args;
|
||
|
||
return result;
|
||
}
|
||
|
||
string getFullFileArchiveCompressCommand(string fileArchiveCompressCommand,
|
||
string fileArchiveCompressCommandParameters,
|
||
string archivename, string archivefiles) {
|
||
string parsedArchivename = archivename;
|
||
string parsedArchivefiles = archivefiles;
|
||
|
||
// This is required for execution on win32
|
||
#if defined(WIN32)
|
||
replaceAll(parsedArchivename, "\\\\", "\\");
|
||
replaceAll(parsedArchivename, "/", "\\");
|
||
replaceAll(parsedArchivefiles, "\\\\", "\\");
|
||
replaceAll(parsedArchivefiles, "/", "\\");
|
||
|
||
#endif
|
||
|
||
string result = fileArchiveCompressCommand;
|
||
result += " ";
|
||
string args = replaceAll(fileArchiveCompressCommandParameters, "{archivename}", parsedArchivename);
|
||
args = replaceAll(args, "{archivefiles}", parsedArchivefiles);
|
||
result += args;
|
||
|
||
return result;
|
||
}
|
||
|
||
bool executeShellCommand(string cmd, int expectedResult, ShellCommandOutputCallbackInterface *cb) {
|
||
bool result = false;
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"About to run [%s]", cmd.c_str());
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("About to run [%s]", cmd.c_str());
|
||
|
||
#ifdef WIN32
|
||
FILE *file = _wpopen(utf8_decode(cmd).c_str(),L"r");
|
||
#else
|
||
FILE *file = popen(cmd.c_str(),"r");
|
||
#endif
|
||
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"file = [%p]", file);
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("file = [%p]", file);
|
||
|
||
if(file != NULL) {
|
||
char szBuf[4096]="";
|
||
while(feof(file) == false) {
|
||
if(fgets( szBuf, 4095, file) != NULL) {
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf);
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf);
|
||
|
||
if(cb != NULL) {
|
||
cb->ShellCommandOutput_CallbackEvent(cmd,szBuf,cb->getShellCommandOutput_UserData(cmd));
|
||
}
|
||
}
|
||
}
|
||
#ifdef WIN32
|
||
int cmdRet = _pclose(file);
|
||
#else
|
||
int cmdRet = pclose(file);
|
||
#endif
|
||
|
||
/* Close pipe and print return value. */
|
||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"Process returned %d\n", cmdRet);
|
||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Process returned %d\n", cmdRet);
|
||
result = (expectedResult == IGNORE_CMD_RESULT_VALUE || expectedResult == cmdRet);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
bool removeFile(string file) {
|
||
#ifdef WIN32
|
||
int result = _unlink(file.c_str());
|
||
#else
|
||
int result = unlink(file.c_str());
|
||
#endif
|
||
|
||
return (result == 0);
|
||
}
|
||
|
||
bool renameFile(string oldFile, string newFile) {
|
||
int result = rename(oldFile.c_str(),newFile.c_str());
|
||
return (result == 0);
|
||
}
|
||
|
||
off_t getFileSize(string filename) {
|
||
#ifdef WIN32
|
||
#if defined(__MINGW32__)
|
||
struct _stat stbuf;
|
||
#else
|
||
struct _stat64i32 stbuf;
|
||
#endif
|
||
if(_wstat(utf8_decode(filename).c_str(), &stbuf) != -1) {
|
||
#else
|
||
struct stat stbuf;
|
||
if(stat(filename.c_str(), &stbuf) != -1) {
|
||
#endif
|
||
return stbuf.st_size;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
string executable_path(string exeName, bool includeExeNameInPath) {
|
||
string value = "";
|
||
#ifdef _WIN32
|
||
char path[MAX_PATH]="";
|
||
if( GetModuleFileNameA(NULL,path,MAX_PATH) == 0 ) {
|
||
if(includeExeNameInPath == true) {
|
||
value = exeName;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(exeName);
|
||
}
|
||
}
|
||
else {
|
||
if(includeExeNameInPath == true) {
|
||
value = path;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(path);
|
||
}
|
||
}
|
||
#elif __APPLE__
|
||
char path[MAXPATHLEN+1]="";
|
||
uint32_t path_len = MAXPATHLEN;
|
||
if ( _NSGetExecutablePath(path, &path_len) ) {
|
||
if(includeExeNameInPath == true) {
|
||
value = exeName;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(exeName);
|
||
}
|
||
}
|
||
else {
|
||
if(includeExeNameInPath == true) {
|
||
value = path;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(path);
|
||
}
|
||
}
|
||
#else
|
||
char exe_link_path[200]="";
|
||
int length = readlink("/proc/self/exe", exe_link_path, sizeof(exe_link_path));
|
||
if(length < 0 || length >= 200 ) {
|
||
char *argv0_path = realpath(exeName.c_str(),NULL);
|
||
if(argv0_path != NULL) {
|
||
if(includeExeNameInPath == true) {
|
||
value = argv0_path;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(argv0_path);
|
||
}
|
||
free(argv0_path);
|
||
argv0_path = NULL;
|
||
}
|
||
else {
|
||
const char *shell_path = getenv("_");
|
||
if(shell_path != NULL) {
|
||
if(includeExeNameInPath == true) {
|
||
value = shell_path;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(shell_path);
|
||
}
|
||
}
|
||
else {
|
||
if(includeExeNameInPath == true) {
|
||
value = exeName;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(exeName);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
exe_link_path[length] = '\0';
|
||
if(includeExeNameInPath == true) {
|
||
value = exe_link_path;
|
||
}
|
||
else {
|
||
value = extractDirectoryPathFromFile(exe_link_path);
|
||
}
|
||
}
|
||
#endif
|
||
return value;
|
||
}
|
||
|
||
bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly) {
|
||
bool replacedText = false;
|
||
const int MAX_LEN_SINGLE_LINE = 4096;
|
||
char buffer[MAX_LEN_SINGLE_LINE+2];
|
||
char *buff_ptr, *find_ptr;
|
||
FILE *fp1, *fp2;
|
||
size_t find_len = findText.length();
|
||
|
||
string tempfileName = fileName + "_tmp";
|
||
#ifdef WIN32
|
||
fp1 = _wfopen(utf8_decode(fileName).c_str(), L"r");
|
||
fp2 = _wfopen(utf8_decode(tempfileName).c_str(), L"w");
|
||
#else
|
||
fp1 = fopen(fileName.c_str(),"r");
|
||
fp2 = fopen(tempfileName.c_str(),"w");
|
||
#endif
|
||
|
||
if(fp1 == NULL) {
|
||
if(fp2) fclose(fp2);
|
||
|
||
throw megaglest_runtime_error("cannot open input file [" + fileName + "]");
|
||
}
|
||
if(fp2 == NULL) {
|
||
if(fp1) fclose(fp1);
|
||
|
||
throw megaglest_runtime_error("cannot open output file [" + tempfileName + "]");
|
||
}
|
||
|
||
while(fgets(buffer,MAX_LEN_SINGLE_LINE + 2,fp1)) {
|
||
buff_ptr = buffer;
|
||
if(findText != "") {
|
||
while ((find_ptr = strstr(buff_ptr,findText.c_str()))) {
|
||
//printf("Replacing text [%s] with [%s] in file [%s]\n",findText.c_str(),replaceText.c_str(),fileName.c_str());
|
||
|
||
while(buff_ptr < find_ptr) {
|
||
fputc((int)*buff_ptr++,fp2);
|
||
}
|
||
fputs(replaceText.c_str(),fp2);
|
||
|
||
buff_ptr += find_len;
|
||
replacedText = true;
|
||
}
|
||
}
|
||
fputs(buff_ptr,fp2);
|
||
}
|
||
|
||
fclose(fp2);
|
||
fclose(fp1);
|
||
|
||
if(replacedText == true && simulateOnly == false) {
|
||
removeFile(fileName);
|
||
renameFile(tempfileName,fileName);
|
||
}
|
||
else {
|
||
removeFile(tempfileName);
|
||
}
|
||
//removeFile(tempfileName);
|
||
return replacedText;
|
||
}
|
||
|
||
void saveDataToFile(string filename, string data) {
|
||
//Open an input and output stream in binary mode
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
FILE *fp2 = _wfopen(utf8_decode(filename).c_str(), L"wb");
|
||
ofstream out(fp2);
|
||
#else
|
||
ofstream out(filename.c_str(),ios::binary);
|
||
#endif
|
||
|
||
if(out.is_open()) {
|
||
out<< data;
|
||
}
|
||
else if(out.is_open() == false) {
|
||
throw megaglest_runtime_error("cannot open input file [" + filename + "]");
|
||
}
|
||
|
||
//Close file
|
||
out.close();
|
||
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
if(fp2) {
|
||
fclose(fp2);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void copyFileTo(string fromFileName, string toFileName) {
|
||
//Open an input and output stream in binary mode
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
FILE *fp1 = _wfopen(utf8_decode(fromFileName).c_str(), L"rb");
|
||
ifstream in(fp1);
|
||
FILE *fp2 = _wfopen(utf8_decode(toFileName).c_str(), L"wb");
|
||
ofstream out(fp2);
|
||
#else
|
||
ifstream in(fromFileName.c_str(),ios::binary);
|
||
ofstream out(toFileName.c_str(),ios::binary);
|
||
#endif
|
||
|
||
if(in.is_open() && out.is_open()) {
|
||
while(in.eof() == false) {
|
||
out.put(in.get());
|
||
}
|
||
}
|
||
else if(in.is_open() == false) {
|
||
throw megaglest_runtime_error("cannot open input file [" + fromFileName + "]");
|
||
}
|
||
else if(out.is_open() == false) {
|
||
throw megaglest_runtime_error("cannot open input file [" + toFileName + "]");
|
||
}
|
||
|
||
//Close both files
|
||
in.close();
|
||
out.close();
|
||
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
if(fp1) {
|
||
fclose(fp1);
|
||
}
|
||
if(fp2) {
|
||
fclose(fp2);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
bool valid_utf8_file(const char* file_name) {
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
wstring wstr = utf8_decode(file_name);
|
||
FILE *fp = _wfopen(wstr.c_str(), L"r");
|
||
ifstream ifs(fp);
|
||
#else
|
||
ifstream ifs(file_name);
|
||
#endif
|
||
|
||
if (!ifs) {
|
||
return false; // even better, throw here
|
||
}
|
||
istreambuf_iterator<char> it(ifs.rdbuf());
|
||
istreambuf_iterator<char> eos;
|
||
|
||
bool result = utf8::is_valid(it, eos);
|
||
|
||
ifs.close();
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
if(fp) {
|
||
fclose(fp);
|
||
}
|
||
#endif
|
||
|
||
return result;
|
||
}
|
||
|
||
string getFileTextContents(string path) {
|
||
#if defined(WIN32) && !defined(__MINGW32__)
|
||
FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb");
|
||
ifstream xmlFile(fp);
|
||
#else
|
||
ifstream xmlFile(path.c_str(),ios::binary);
|
||
#endif
|
||
if(xmlFile.is_open() == false) {
|
||
throw megaglest_runtime_error("Can not open file: [" + path + "]");
|
||
}
|
||
|
||
xmlFile.unsetf(ios::skipws);
|
||
|
||
// Determine stream size
|
||
xmlFile.seekg(0, ios::end);
|
||
streampos size = xmlFile.tellg();
|
||
xmlFile.seekg(0);
|
||
|
||
// Load data and add terminating 0
|
||
vector<char> buffer;
|
||
buffer.resize((unsigned int)size + 1);
|
||
xmlFile.read(&buffer.front(), static_cast<streamsize>(size));
|
||
buffer[(unsigned int)size] = 0;
|
||
|
||
return &buffer.front();
|
||
}
|
||
|
||
// =====================================
|
||
// ModeInfo
|
||
// =====================================
|
||
|
||
ModeInfo::ModeInfo(int w, int h, int d) {
|
||
width=w;
|
||
height=h;
|
||
depth=d;
|
||
}
|
||
|
||
string ModeInfo::getString() const{
|
||
return intToStr(width)+"x"+intToStr(height)+"-"+intToStr(depth);
|
||
}
|
||
|
||
void ValueCheckerVault::addItemToVault(const void *ptr,int value) {
|
||
#ifndef _DISABLE_MEMORY_VAULT_CHECKS
|
||
|
||
Checksum checksum;
|
||
vaultList[ptr] = checksum.addInt(value);
|
||
|
||
#endif
|
||
|
||
// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value);
|
||
}
|
||
|
||
void ValueCheckerVault::checkItemInVault(const void *ptr,int value) const {
|
||
#ifndef _DISABLE_MEMORY_VAULT_CHECKS
|
||
|
||
map<const void *,uint32>::const_iterator iterFind = vaultList.find(ptr);
|
||
if(iterFind == vaultList.end()) {
|
||
// if(SystemFlags::VERBOSE_MODE_ENABLED) {
|
||
// printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value);
|
||
// for(map<const void *,string>::const_iterator iterFind = vaultList.begin();
|
||
// iterFind != vaultList.end(); iterFind++) {
|
||
// printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str());
|
||
// }
|
||
// }
|
||
throw std::runtime_error("memory value has been unexpectedly modified (not found)!");
|
||
}
|
||
Checksum checksum;
|
||
if(iterFind->second != checksum.addInt(value)) {
|
||
// if(SystemFlags::VERBOSE_MODE_ENABLED) {
|
||
// printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value);
|
||
// for(map<const void *,string>::const_iterator iterFind = vaultList.begin();
|
||
// iterFind != vaultList.end(); iterFind++) {
|
||
// printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str());
|
||
// }
|
||
// }
|
||
throw std::runtime_error("memory value has been unexpectedly modified (changed)!");
|
||
}
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
string getUserHome() {
|
||
string home_folder;
|
||
home_folder = safeCharPtrCopy(getenv("HOME"),8095);
|
||
if(home_folder == "") {
|
||
#if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|
||
struct passwd *pw = getpwuid(getuid());
|
||
home_folder = safeCharPtrCopy(pw->pw_dir,8095);
|
||
#endif
|
||
}
|
||
return home_folder;
|
||
}
|
||
|
||
string safeCharPtrCopy(const char *ptr,int maxLength) {
|
||
string result = "";
|
||
if(ptr == NULL) {
|
||
return result;
|
||
}
|
||
if(maxLength <= 0) {
|
||
maxLength = 8096;
|
||
}
|
||
|
||
int ptrLength = (int)strlen(ptr);
|
||
if(ptrLength >= maxLength) {
|
||
char *pBuffer = new char[maxLength+1];
|
||
memset(pBuffer,0,maxLength+1);
|
||
#ifdef WIN32
|
||
memcpy(pBuffer,ptr,min((int)strlen(ptr),maxLength));
|
||
#else
|
||
memcpy(pBuffer,ptr,std::min((int)strlen(ptr),maxLength));
|
||
#endif
|
||
|
||
result = pBuffer;
|
||
delete [] pBuffer;
|
||
}
|
||
else {
|
||
result = ptr;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
|
||
}}//end namespace
|