mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
226 lines
5.1 KiB
C++
226 lines
5.1 KiB
C++
/****************************************************************************
|
|
* Copyright (C) 2010
|
|
* by Dimok
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any
|
|
* damages arising from the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any
|
|
* purpose, including commercial applications, and to alter it and
|
|
* redistribute it freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented; you
|
|
* must not claim that you wrote the original software. If you use
|
|
* this software in a product, an acknowledgment in the product
|
|
* documentation would be appreciated but is not required.
|
|
*
|
|
* 2. Altered source versions must be plainly marked as such, and
|
|
* must not be misrepresented as being the original software.
|
|
*
|
|
* 3. This notice may not be removed or altered from any source
|
|
* distribution.
|
|
*
|
|
* DirList Class
|
|
* for WiiXplorer 2010
|
|
***************************************************************************/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string>
|
|
#include <algorithm>
|
|
#include <sys/stat.h>
|
|
#include <sys/dirent.h>
|
|
|
|
#define MAXPATHLEN 1024
|
|
|
|
#include "utils/StringTools.h"
|
|
#include "DirList.h"
|
|
|
|
DirList::DirList(const char * path, const char *filter, u32 flags, s32 max_depth)
|
|
{
|
|
this->LoadPath(path, filter, flags, max_depth);
|
|
this->SortList();
|
|
}
|
|
|
|
DirList::~DirList()
|
|
{
|
|
ClearList();
|
|
}
|
|
|
|
bool DirList::LoadPath(const char * folder, const char *filter, u32 flags, s32 max_depth)
|
|
{
|
|
if(!folder) return false;
|
|
|
|
std::string folderpath(folder);
|
|
|
|
return LoadPath(folderpath, filter, flags, max_depth);
|
|
}
|
|
|
|
bool DirList::LoadPath(std::string &folderpath, const char *filter, u32 flags, s32 max_depth)
|
|
{
|
|
if(folderpath.size() < 3)
|
|
return false;
|
|
|
|
struct dirent *dirent = NULL;
|
|
DIR *dir = NULL;
|
|
|
|
if(folderpath[folderpath.size()-1] == '/')
|
|
folderpath.erase(folderpath.size()-1);
|
|
|
|
bool isRoot = (folderpath.find('/') == std::string::npos);
|
|
if(isRoot)
|
|
folderpath += '/';
|
|
|
|
dir = opendir(folderpath.c_str());
|
|
if (dir == NULL)
|
|
return false;
|
|
|
|
char * filename = new (std::nothrow) char[MAXPATHLEN];
|
|
struct stat *st = new (std::nothrow) struct stat;
|
|
if(!filename || !st)
|
|
{
|
|
delete [] filename;
|
|
delete st;
|
|
closedir(dir);
|
|
return false;
|
|
}
|
|
|
|
while ((dirent = readdir(dir)) != 0)
|
|
{
|
|
if(strlen(dirent->d_name) == 0)
|
|
continue;
|
|
|
|
snprintf(filename, MAXPATHLEN, "%s/%s", folderpath.c_str(), dirent->d_name);
|
|
|
|
if(stat(filename, st) != 0)
|
|
continue;
|
|
|
|
snprintf(filename, MAXPATHLEN, dirent->d_name);
|
|
|
|
if(st->st_mode & S_IFDIR)
|
|
{
|
|
if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0)
|
|
continue;
|
|
|
|
if((flags & CheckSubfolders) && (max_depth != 0))
|
|
{
|
|
int length = folderpath.size();
|
|
if(!isRoot) folderpath += '/';
|
|
folderpath += filename;
|
|
LoadPath(folderpath, filter, flags, max_depth - 1);
|
|
folderpath.erase(length);
|
|
}
|
|
|
|
if(!(flags & Dirs))
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if(!(flags & Files))
|
|
continue;
|
|
}
|
|
|
|
if(flags & MainDOL)
|
|
{
|
|
if(!(memcmp(filename, "boot.dol", 8) == 0 || memcmp(filename, "boot.elf", 8) == 0))
|
|
continue;
|
|
}
|
|
|
|
if(filter)
|
|
{
|
|
char * fileext = strrchr(filename, '.');
|
|
if(!fileext)
|
|
continue;
|
|
|
|
if(strtokcmp(fileext, filter, ",") == 0)
|
|
AddEntrie(folderpath.c_str(), filename, st->st_size, (st->st_mode & S_IFDIR) ? true : false);
|
|
}
|
|
else
|
|
{
|
|
AddEntrie(folderpath.c_str(), filename, st->st_size, (st->st_mode & S_IFDIR) ? true : false);
|
|
}
|
|
}
|
|
closedir(dir);
|
|
delete [] filename;
|
|
delete st;
|
|
|
|
return true;
|
|
}
|
|
|
|
void DirList::AddEntrie(const char * folderpath, const char * filename, u64 filesize, bool isDir)
|
|
{
|
|
if(!folderpath || !filename)
|
|
return;
|
|
|
|
int pos = FileInfo.size();
|
|
|
|
FileInfo.resize(pos+1);
|
|
|
|
FileInfo[pos].FilePath = new (std::nothrow) char[strlen(folderpath)+strlen(filename)+2];
|
|
if(FileInfo[pos].FilePath)
|
|
sprintf(FileInfo[pos].FilePath, "%s/%s", folderpath, filename);
|
|
FileInfo[pos].FileSize = filesize;
|
|
FileInfo[pos].isDir = isDir;
|
|
}
|
|
|
|
void DirList::ClearList()
|
|
{
|
|
for(u32 i = 0; i < FileInfo.size(); ++i)
|
|
{
|
|
if(FileInfo[i].FilePath)
|
|
delete [] FileInfo[i].FilePath;
|
|
}
|
|
|
|
FileInfo.clear();
|
|
std::vector<FileInfos>().swap(FileInfo);
|
|
}
|
|
|
|
const char * DirList::GetFilename(int ind)
|
|
{
|
|
if (!valid(ind))
|
|
return NULL;
|
|
|
|
return FullpathToFilename(FileInfo[ind].FilePath);
|
|
}
|
|
|
|
static bool SortCallback(const FileInfos & f1, const FileInfos & f2)
|
|
{
|
|
if(f1.isDir && !(f2.isDir)) return true;
|
|
if(!(f1.isDir) && f2.isDir) return false;
|
|
|
|
if(f1.FilePath && !f2.FilePath) return true;
|
|
if(!f1.FilePath) return false;
|
|
|
|
if(strcasecmp(f1.FilePath, f2.FilePath) > 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void DirList::SortList()
|
|
{
|
|
if(FileInfo.size() > 1)
|
|
std::sort(FileInfo.begin(), FileInfo.end(), SortCallback);
|
|
}
|
|
|
|
void DirList::SortList(bool (*SortFunc)(const FileInfos &a, const FileInfos &b))
|
|
{
|
|
if(FileInfo.size() > 1)
|
|
std::sort(FileInfo.begin(), FileInfo.end(), SortFunc);
|
|
}
|
|
|
|
int DirList::GetFileIndex(const char *filename)
|
|
{
|
|
if(!filename)
|
|
return -1;
|
|
|
|
for (u32 i = 0; i < FileInfo.size(); ++i)
|
|
{
|
|
if (strcasecmp(GetFilename(i), filename) == 0)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|