#include "elencofile.h"
ElencoFile::ElencoFile( const char *cartella ) {
ef = NULL;
tf = 0;
dd = 0;
if( !AcquisisciElencoDaCartella(cartella) ) throw false;
}
ElencoFile::~ElencoFile() {
if( ef ) delete[] ef;
}
ElencoFile::ElencoFile(const ElencoFile& other) {
ef = NULL;
tf = 0;
dd = 0;
*this = other;
}
ElencoFile& ElencoFile::operator=(const ElencoFile& rhs) {
if (this == &rhs) return *this; // handle self assignment
if( rhs.ef ) {
void *tmp = malloc( rhs.dd );
if( NULL == tmp ) throw false;
memcpy( tmp, rhs.ef, rhs.dd );
if( ef ) free( ef );
ef = (char**)tmp;
tf = rhs.tf;
dd = rhs.dd;
}
return *this;
}
bool ElencoFile::AcquisisciElencoDaCartella( const char *cartella ) {
char *dupPercCart = NULL;
bool ok = false;
if( (dupPercCart=DuplicaPercorso(cartella)) ) {
unsigned int tfTmp = 0;
size_t ddTmp = 0;
if( AnalizzaContenutoCartella(dupPercCart,&tfTmp,&ddTmp) ) {
char **efTmp = CreaElencoDaCartella( dupPercCart, tfTmp, ddTmp );
if( NULL != efTmp ) {
if( ef ) free( ef );
ef = efTmp;
tf = tfTmp;
dd = ddTmp;
ok = true;
}
}
free( (void*)dupPercCart );
}
return ok;
}
const char *ElencoFile::NomeFile( unsigned int indice ) const {
if( ef && indice<tf )
return ef[indice];
else return NULL;
}
// privata
char *ElencoFile::DuplicaPercorso( const char *percorso ) {
char *buff = NULL;
if( NULL==percorso ) {
DWORD dimBuff = GetCurrentDirectory( 0, NULL );
if( (buff=(char*)calloc(dimBuff+4,sizeof(*buff))) ) {
GetCurrentDirectory( dimBuff, buff );
memcpy( buff+dimBuff-1, "\\*.*", 5 );
}
}
else {
size_t l = lstrlen( percorso );
if( (buff=(char*)malloc(l+5)) ) {
memcpy( buff, percorso, l );
memcpy( buff+l, "\\*.*", 5 );
}
}
return buff;
}
// privata
bool ElencoFile::AnalizzaContenutoCartella(
const char *cartella, unsigned int *qFile, size_t *dDati ) {
if( !cartella || !qFile || !dDati ) return false;
size_t lNomeCartella = lstrlen(cartella)-3;
WIN32_FIND_DATA fd = {0};
HANDLE hnd = NULL;
*qFile = 0;
*dDati = 0;
hnd = FindFirstFile( cartella, &fd );
if( INVALID_HANDLE_VALUE != hnd ) {
if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
while( FindNextFile(hnd,&fd) ) {
if( !(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ) {
*dDati += sizeof(char*)+lNomeCartella+lstrlen(fd.cFileName)+1;
++(*qFile);
}
}
}
FindClose( hnd );
return true;
}
return false;
}
// privata
char **ElencoFile::CreaElencoDaCartella(
const char *cartella, unsigned int qFile, size_t dDati ) {
if( !cartella ) return NULL;
void *dTmp = calloc( dDati, 1 );
if( !dTmp ) return NULL;
// Lo scopo della gran confusione creata con una pletora di puntatori e cast
// nelle prossime righe, e' inserire tutti i percorsi+nomi dei file in un
// unico blocco di memoria al quale sia possibile accedere come ad un comune
// array di stringhe C. Inutilmente complicato? Puo' darsi. Pasticciato?
// Puo' darsi. Pero' sembra funzionarea a dovere. :)
size_t lPercorso = lstrlen(cartella)-3;
size_t dimPtr = sizeof(char*);
void *y = dTmp;
void *x = ((void*)(((size_t)dTmp)+qFile*dimPtr));
unsigned int i=0;
WIN32_FIND_DATA fd = {0};
HANDLE hnd = FindFirstFile( cartella, &fd );
if( INVALID_HANDLE_VALUE != hnd ) {
if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
while( FindNextFile(hnd,&fd) && i<qFile ) {
if( !(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ) {
size_t lNomeFile = lstrlen(fd.cFileName);
memcpy( y, &x, dimPtr );
memcpy( x, cartella, lPercorso );
memcpy( (void*)((size_t)x+lPercorso), fd.cFileName, lNomeFile+1 );
y = (void*)(((size_t)y)+dimPtr);
x = (void*)((size_t)x+lPercorso+lNomeFile+1);
++i;
}
}
}
else {
free( dTmp );
dTmp = NULL;
}
FindClose( hnd );
return (char**)dTmp;
}
return NULL;
}