This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: gcc C++ app: need a double, but gcc converts back to long
On 4/18/07, Jack Andrews <effbiae@gmail.com> wrote:
> problem to solve: the app fails on all files larger than 4.2GB. The
4.2GB is around 2^32B. ie, you probably have an overflow problem
Yup.
you want FileSize to return an unsigned long long (a 64 bit value),
so declare fileSize as an unsigned long long.
Done.
however, i get the impression that FileSize only returns a 32 bit
value, so you need to change this. post the source for FileSize and
i'll see if i can help.
Done. Other things that may be of interest:
* I'm compiling with -D_FILE_OFFSET_BITS for large file support.
* Another potential cause fileList (see FSutils.cpp) somehow ignoring
large files - I can't see why but as I mentioned I'm not much of a C++
programmer.
Thanks very much,
Mike
/***************************************************************************
* Made by Zotty *
* January 2007 *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <string>
#include <fstream>
#include <exception>
#include <algorithm> // tokenizer
#include "utils.h"
using namespace std;
/**
*
*/
Utils::Utils()
{
// start logfile
// do this here since Utils is used in almost every class
cout << "*** Starting logfile ***" << endl;
log.open("aca_decrypter.log");
if (!log)
cerr << "Error starting logfile. Continueing, but not logging." << endl;
}
/**
*
*/
Utils::~Utils()
{
if (log)
log.close();
}
/**
* Convert unsigned char to string of length 2
*/
void Utils::Char2Hex(unsigned char ch, char* szHex)
{
unsigned char byte[2];
byte[0] = ch/16;
byte[1] = ch%16;
for(int i=0; i<2; i++)
{
if(byte[i] >= 0 && byte[i] <= 9)
szHex[i] = '0' + byte[i];
else
szHex[i] = 'A' + byte[i] - 10;
}
szHex[2] = 0;
}
/**
* Convert string of length 2 to unsigned char
*/
void Utils::Hex2Char(char const* szHex, unsigned char& rch)
{
rch = 0;
for(int i=0; i<2; i++)
{
if(*(szHex + i) >='0' && *(szHex + i) <= '9')
rch = (rch << 4) + (*(szHex + i) - '0');
else if(*(szHex + i) >='A' && *(szHex + i) <= 'F')
rch = (rch << 4) + (*(szHex + i) - 'A' + 10);
else
break;
}
}
/**
* Convert string of unsigned chars to string of chars
*/
void Utils::toHexString(unsigned char const* pucCharStr, char* pszHexStr, int iSize)
{
int i;
char szHex[3];
pszHexStr[0] = 0;
for(i=0; i<iSize; i++)
{
Char2Hex(pucCharStr[i], szHex);
strcat(pszHexStr, szHex);
}
}
/**
* Convert string of chars to string of unsigned chars
*/
void Utils::hexStringToByteArray(char const* pszHexStr, unsigned char* pucCharStr, int iSize)
{
int i;
unsigned char ch;
for(i=0; i<iSize; i++)
{
Hex2Char(pszHexStr+2*i, ch);
pucCharStr[i] = ch;
}
}
/**
* XOR
*/
void Utils::Xor(char (&buff)[16], char const* chain)
{
for (int i=0; i<sizeof(buff); i++)
buff[i] ^= *(chain++);
}
/**
* Strip leading/trailing spaces
*/
void Utils::Trim(string& str)
{
string::size_type pos = str.find_last_not_of(' ');
pos = str.find_last_not_of('\t', pos); // filter tabs (keydb.cfg)
if( pos != string::npos )
{
str.erase(pos + 1);
pos = str.find_first_not_of(' ');
if(pos != string::npos) str.erase(0, pos);
}
else
str.erase(str.begin(), str.end());
}
/**
* Tokenize string
* leading/trailing spaces are trimmed
*/
void Utils::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, trim and add it to the vector.
string tmp = str.substr(lastPos, pos - lastPos);
Trim(tmp);
tokens.push_back(tmp);
// 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);
}
}
/**
* get filesize, OS independant
*/
unsigned long long Utils::FileSize(string fileName)
{
ifstream f;
f.open(fileName.c_str(), ios_base::binary | ios_base::in);
if (!f.good() || f.eof() || !f.is_open()) { return 0; }
f.seekg(0, std::ios_base::beg);
ifstream::pos_type begin_pos = f.tellg();
f.seekg(0, ios_base::end);
return static_cast<int>(f.tellg() - begin_pos);
}
/**
* load entire file into buffer
*/
byte * Utils::loadAFile(string fileName)
{
unsigned long long fileSize = FileSize(fileName);
try {
byte * buffer = new byte[fileSize];
ifstream fis(fileName.c_str());
if (!fis) {
cerr << fileName << " not found" << endl;
}
fis.read((char *)buffer, fileSize);
fis.close();
return buffer;
}
catch (exception e){
e.what();
}
return NULL;
}
/**
* Write message to logfile
*/
void Utils::LogMsg(string msg)
{
msg += "\n";
if (log) {
log.write(msg.c_str(), msg.length());
log.flush();
}
else
cerr << "Error writing to logfile!" << endl;
}
/***************************************************************************
* Made by Zotty *
* January 2007 *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/*
Simple filesystem stuff. Quickly made because I find the M$ API crap. This
gets the job done, but doesn't win a beautycontest ;)
*/
#ifdef __WIN32__
#include <dir.h>
#else
#include <sys/dir.h>
#endif
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <vector>
#include <algorithm> // transform
#include <cctype> // tolower
#include "FSUtils.h"
using namespace std;
FSUtils::FSUtils()
{
extention = "";
}
/**
* Scan a directory
* needs seperator at the end (not checked!)
*/
void FSUtils::ScanDir(string directoryPath, bool recursive)
{
DIR * dir = opendir( directoryPath.c_str() );
if (NULL != dir)
{
struct dirent *entry;
for(; NULL != (entry = readdir(dir)); )
{
struct stat st;
// Skip dots
if ('.' == entry->d_name[0] && ( '\0' == entry->d_name[1] ||
( '.' == entry->d_name[1] && '\0' == entry->d_name[2])) )
{
// do nothing
}
else
{
if (0 == stat((string(directoryPath) + entry->d_name).c_str(), &st))
{
// directories
if (S_IFDIR == (st.st_mode & S_IFDIR))
{
// add to FileList
File * listEntry = new File();
listEntry->path = directoryPath;
listEntry->fileName = "";
listEntry->fileSize = 0;
listEntry->isDirectory = true;
fileList.push_back(listEntry);
// when recursive scanning
if (recursive) {
string newPath = directoryPath + entry->d_name + SEPERATOR;
ScanDir( newPath );
}
}
// files
if (S_IFREG == (st.st_mode & S_IFREG))
{
string fileName = entry->d_name;
// check for extention
if (extention.empty()) {
File * listEntry = new File();
listEntry->path = directoryPath;
listEntry->fileName = fileName;
listEntry->fileSize = 0;
listEntry->isDirectory = false;
fileList.push_back(listEntry);
}
else {
string ext = fileName.substr( fileName.rfind('.', fileName.length()) );
transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int)) tolower);
if (ext == extention) {
File * listEntry = new File();
listEntry->path = directoryPath;
listEntry->fileName = fileName;
listEntry->fileSize = 0;
listEntry->isDirectory = false;
fileList.push_back(listEntry);
}
}
} // files
} // stat
} // else
} // for
closedir( dir );
}
}
/**
* Create directory
*/
bool FSUtils::CreateDir(string dirName)
{
errno = 0;
#ifdef __WIN32__
mkdir(dirName.c_str());
#else
mkdir(dirName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
#endif
if (errno)
return false;
else
return true;
}
/**
* Remove/delete directory
* dir must be empty or rmdir() fails!
*/
bool FSUtils::RemoveDir(string dirName)
{
errno = 0;
rmdir(dirName.c_str());
if (errno)
return false;
else
return true;
}
/**
*
*/
/*
void FSUtils::ls()
{
vector<string>::iterator it;
for (it = fileList.begin(); it != fileList.end(); it++) {
cout << "\t" << *it << endl;
}
}
*/