1
0
Fork 0

(svn r23216) -Codechange: introduce the concept of having different tar lists

release/1.2
rubidium 2011-11-14 21:28:43 +00:00
parent f600429424
commit 160294ff22
7 changed files with 61 additions and 48 deletions

View File

@ -428,11 +428,11 @@ static bool IsSameAI(const ContentInfo *ci, bool md5sum, AIFileInfo *info)
AIFileChecksumCreator checksum; AIFileChecksumCreator checksum;
const char *tar_filename = info->GetTarFile(); const char *tar_filename = info->GetTarFile();
TarList::iterator iter; TarList::iterator iter;
if (tar_filename != NULL && (iter = _tar_list.find(tar_filename)) != _tar_list.end()) { if (tar_filename != NULL && (iter = _tar_list[AI_DIR].find(tar_filename)) != _tar_list[AI_DIR].end()) {
/* The main script is in a tar file, so find all files that /* The main script is in a tar file, so find all files that
* are in the same tar and add them to the MD5 checksumming. */ * are in the same tar and add them to the MD5 checksumming. */
TarFileList::iterator tar; TarFileList::iterator tar;
FOR_ALL_TARS(tar) { FOR_ALL_TARS(tar, AI_DIR) {
/* Not in the same tar. */ /* Not in the same tar. */
if (tar->second.tar_filename != iter->first) continue; if (tar->second.tar_filename != iter->first) continue;

View File

@ -284,11 +284,11 @@ static const char * const _subdirs[] = {
assert_compile(lengthof(_subdirs) == NUM_SUBDIRS); assert_compile(lengthof(_subdirs) == NUM_SUBDIRS);
const char *_searchpaths[NUM_SEARCHPATHS]; const char *_searchpaths[NUM_SEARCHPATHS];
TarList _tar_list; TarList _tar_list[NUM_SUBDIRS];
TarFileList _tar_filelist; TarFileList _tar_filelist[NUM_SUBDIRS];
typedef std::map<std::string, std::string> TarLinkList; typedef std::map<std::string, std::string> TarLinkList;
static TarLinkList _tar_linklist; ///< List of directory links static TarLinkList _tar_linklist[NUM_SUBDIRS]; ///< List of directory links
/** /**
* Check whether the given file exists * Check whether the given file exists
@ -467,7 +467,7 @@ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir,
} }
/* We can only use .tar in case of data-dir, and read-mode */ /* We can only use .tar in case of data-dir, and read-mode */
if (f == NULL && mode[0] == 'r') { if (f == NULL && mode[0] == 'r' && subdir != NO_DIRECTORY) {
static const uint MAX_RESOLVED_LENGTH = 2 * (100 + 100 + 155) + 1; // Enough space to hold two filenames plus link. See 'TarHeader'. static const uint MAX_RESOLVED_LENGTH = 2 * (100 + 100 + 155) + 1; // Enough space to hold two filenames plus link. See 'TarHeader'.
char resolved_name[MAX_RESOLVED_LENGTH]; char resolved_name[MAX_RESOLVED_LENGTH];
@ -478,7 +478,7 @@ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir,
size_t resolved_len = strlen(resolved_name); size_t resolved_len = strlen(resolved_name);
/* Resolve ONE directory link */ /* Resolve ONE directory link */
for (TarLinkList::iterator link = _tar_linklist.begin(); link != _tar_linklist.end(); link++) { for (TarLinkList::iterator link = _tar_linklist[subdir].begin(); link != _tar_linklist[subdir].end(); link++) {
const std::string &src = link->first; const std::string &src = link->first;
size_t len = src.length(); size_t len = src.length();
if (resolved_len >= len && resolved_name[len - 1] == PATHSEPCHAR && strncmp(src.c_str(), resolved_name, len) == 0) { if (resolved_len >= len && resolved_name[len - 1] == PATHSEPCHAR && strncmp(src.c_str(), resolved_name, len) == 0) {
@ -492,8 +492,8 @@ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir,
} }
} }
TarFileList::iterator it = _tar_filelist.find(resolved_name); TarFileList::iterator it = _tar_filelist[subdir].find(resolved_name);
if (it != _tar_filelist.end()) { if (it != _tar_filelist[subdir].end()) {
f = FioFOpenFileTar(&((*it).second), filesize); f = FioFOpenFileTar(&((*it).second), filesize);
} }
} }
@ -582,15 +582,16 @@ char *BuildWithFullPath(const char *dir)
/** /**
* Find the first directory in a tar archive. * Find the first directory in a tar archive.
* @param tarname the name of the tar archive to look in. * @param tarname the name of the tar archive to look in.
* @param subdir the subdirectory to look in.
*/ */
const char *FioTarFirstDir(const char *tarname) const char *FioTarFirstDir(const char *tarname, Subdirectory subdir)
{ {
TarList::iterator it = _tar_list.find(tarname); TarList::iterator it = _tar_list[subdir].find(tarname);
if (it == _tar_list.end()) return NULL; if (it == _tar_list[subdir].end()) return NULL;
return (*it).second.dirname; return (*it).second.dirname;
} }
static void TarAddLink(const std::string &srcParam, const std::string &destParam) static void TarAddLink(const std::string &srcParam, const std::string &destParam, Subdirectory subdir)
{ {
std::string src = srcParam; std::string src = srcParam;
std::string dest = destParam; std::string dest = destParam;
@ -598,22 +599,22 @@ static void TarAddLink(const std::string &srcParam, const std::string &destParam
std::transform(src.begin(), src.end(), src.begin(), tolower); std::transform(src.begin(), src.end(), src.begin(), tolower);
std::transform(dest.begin(), dest.end(), dest.begin(), tolower); std::transform(dest.begin(), dest.end(), dest.begin(), tolower);
TarFileList::iterator dest_file = _tar_filelist.find(dest); TarFileList::iterator dest_file = _tar_filelist[subdir].find(dest);
if (dest_file != _tar_filelist.end()) { if (dest_file != _tar_filelist[subdir].end()) {
/* Link to file. Process the link like the destination file. */ /* Link to file. Process the link like the destination file. */
_tar_filelist.insert(TarFileList::value_type(src, dest_file->second)); _tar_filelist[subdir].insert(TarFileList::value_type(src, dest_file->second));
} else { } else {
/* Destination file not found. Assume 'link to directory' /* Destination file not found. Assume 'link to directory'
* Append PATHSEPCHAR to 'src' and 'dest' if needed */ * Append PATHSEPCHAR to 'src' and 'dest' if needed */
const std::string src_path = ((*src.rbegin() == PATHSEPCHAR) ? src : src + PATHSEPCHAR); const std::string src_path = ((*src.rbegin() == PATHSEPCHAR) ? src : src + PATHSEPCHAR);
const std::string dst_path = (dest.length() == 0 ? "" : ((*dest.rbegin() == PATHSEPCHAR) ? dest : dest + PATHSEPCHAR)); const std::string dst_path = (dest.length() == 0 ? "" : ((*dest.rbegin() == PATHSEPCHAR) ? dest : dest + PATHSEPCHAR));
_tar_linklist.insert(TarLinkList::value_type(src_path, dst_path)); _tar_linklist[subdir].insert(TarLinkList::value_type(src_path, dst_path));
} }
} }
void FioTarAddLink(const char *src, const char *dest) void FioTarAddLink(const char *src, const char *dest, Subdirectory subdir)
{ {
TarAddLink(src, dest); TarAddLink(src, dest, subdir);
} }
/** /**
@ -632,17 +633,26 @@ static void SimplifyFileName(char *name)
#endif #endif
} }
/**
* Perform the scanning of a particular subdirectory.
* @param subdir The subdirectory to scan.
* @return The number of found tar files.
*/
uint TarScanner::DoScan(Subdirectory sd)
{
_tar_filelist[sd].clear();
_tar_list[sd].clear();
return this->Scan(".tar", sd, false);
}
/* static */ uint TarScanner::DoScan() /* static */ uint TarScanner::DoScan()
{ {
_tar_filelist.clear();
_tar_list.clear();
DEBUG(misc, 1, "Scanning for tars"); DEBUG(misc, 1, "Scanning for tars");
TarScanner fs; TarScanner fs;
uint num = fs.Scan(".tar", NEWGRF_DIR, false); uint num = fs.DoScan(NEWGRF_DIR);
num += fs.Scan(".tar", AI_DIR, false); num += fs.DoScan(AI_DIR);
num += fs.Scan(".tar", AI_LIBRARY_DIR, false); num += fs.DoScan(AI_LIBRARY_DIR);
num += fs.Scan(".tar", SCENARIO_DIR, false); num += fs.DoScan(SCENARIO_DIR);
DEBUG(misc, 1, "Scan complete, found %d files", num); DEBUG(misc, 1, "Scan complete, found %d files", num);
return num; return num;
} }
@ -675,8 +685,8 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
} TarHeader; } TarHeader;
/* Check if we already seen this file */ /* Check if we already seen this file */
TarList::iterator it = _tar_list.find(filename); TarList::iterator it = _tar_list[this->subdir].find(filename);
if (it != _tar_list.end()) return false; if (it != _tar_list[this->subdir].end()) return false;
FILE *f = fopen(filename, "rb"); FILE *f = fopen(filename, "rb");
/* Although the file has been found there can be /* Although the file has been found there can be
@ -686,8 +696,8 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
if (f == NULL) return false; if (f == NULL) return false;
const char *dupped_filename = strdup(filename); const char *dupped_filename = strdup(filename);
_tar_list[filename].filename = dupped_filename; _tar_list[this->subdir][filename].filename = dupped_filename;
_tar_list[filename].dirname = NULL; _tar_list[this->subdir][filename].dirname = NULL;
TarLinkList links; ///< Temporary list to collect links TarLinkList links; ///< Temporary list to collect links
@ -755,7 +765,7 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
SimplifyFileName(name); SimplifyFileName(name);
DEBUG(misc, 6, "Found file in tar: %s (" PRINTF_SIZE " bytes, " PRINTF_SIZE " offset)", name, skip, pos); DEBUG(misc, 6, "Found file in tar: %s (" PRINTF_SIZE " bytes, " PRINTF_SIZE " offset)", name, skip, pos);
if (_tar_filelist.insert(TarFileList::value_type(name, entry)).second) num++; if (_tar_filelist[this->subdir].insert(TarFileList::value_type(name, entry)).second) num++;
break; break;
} }
@ -828,7 +838,7 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
/* Store the first directory name we detect */ /* Store the first directory name we detect */
DEBUG(misc, 6, "Found dir in tar: %s", name); DEBUG(misc, 6, "Found dir in tar: %s", name);
if (_tar_list[filename].dirname == NULL) _tar_list[filename].dirname = strdup(name); if (_tar_list[this->subdir][filename].dirname == NULL) _tar_list[this->subdir][filename].dirname = strdup(name);
break; break;
default: default:
@ -857,7 +867,7 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
for (TarLinkList::iterator link = links.begin(); link != links.end(); link++) { for (TarLinkList::iterator link = links.begin(); link != links.end(); link++) {
const std::string &src = link->first; const std::string &src = link->first;
const std::string &dest = link->second; const std::string &dest = link->second;
TarAddLink(src, dest); TarAddLink(src, dest, this->subdir);
} }
return true; return true;
@ -867,13 +877,14 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
* Extract the tar with the given filename in the directory * Extract the tar with the given filename in the directory
* where the tar resides. * where the tar resides.
* @param tar_filename the name of the tar to extract. * @param tar_filename the name of the tar to extract.
* @param subdir The sub directory the tar is in.
* @return false on failure. * @return false on failure.
*/ */
bool ExtractTar(const char *tar_filename) bool ExtractTar(const char *tar_filename, Subdirectory subdir)
{ {
TarList::iterator it = _tar_list.find(tar_filename); TarList::iterator it = _tar_list[subdir].find(tar_filename);
/* We don't know the file. */ /* We don't know the file. */
if (it == _tar_list.end()) return false; if (it == _tar_list[subdir].end()) return false;
const char *dirname = (*it).second.dirname; const char *dirname = (*it).second.dirname;
@ -891,7 +902,7 @@ bool ExtractTar(const char *tar_filename)
DEBUG(misc, 8, "Extracting %s to directory %s", tar_filename, filename); DEBUG(misc, 8, "Extracting %s to directory %s", tar_filename, filename);
FioCreateDirectory(filename); FioCreateDirectory(filename);
for (TarFileList::iterator it2 = _tar_filelist.begin(); it2 != _tar_filelist.end(); it2++) { for (TarFileList::iterator it2 = _tar_filelist[subdir].begin(); it2 != _tar_filelist[subdir].end(); it2++) {
if (strcmp((*it2).second.tar_filename, tar_filename) != 0) continue; if (strcmp((*it2).second.tar_filename, tar_filename) != 0) continue;
strecpy(p, (*it2).first.c_str(), lastof(filename)); strecpy(p, (*it2).first.c_str(), lastof(filename));
@ -1335,8 +1346,8 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
num += ScanPath(this, extension, path, strlen(path), recursive); num += ScanPath(this, extension, path, strlen(path), recursive);
} }
if (tars) { if (tars && sd != NO_DIRECTORY) {
FOR_ALL_TARS(tar) { FOR_ALL_TARS(tar, sd) {
num += ScanTar(this, extension, tar); num += ScanTar(this, extension, tar);
} }
} }

View File

@ -60,9 +60,9 @@ bool AppendPathSeparator(char *buf, size_t buflen);
void DeterminePaths(const char *exe); void DeterminePaths(const char *exe);
void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize); void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize);
bool FileExists(const char *filename); bool FileExists(const char *filename);
const char *FioTarFirstDir(const char *tarname); const char *FioTarFirstDir(const char *tarname, Subdirectory subdir);
void FioTarAddLink(const char *src, const char *dest); void FioTarAddLink(const char *src, const char *dest, Subdirectory subdir);
bool ExtractTar(const char *tar_filename); bool ExtractTar(const char *tar_filename, Subdirectory subdir);
extern char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc. extern char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc.
@ -90,6 +90,7 @@ public:
/** Helper for scanning for files with tar as extension */ /** Helper for scanning for files with tar as extension */
class TarScanner : FileScanner { class TarScanner : FileScanner {
uint DoScan(Subdirectory sd);
public: public:
/* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename = NULL); /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename = NULL);

View File

@ -507,8 +507,8 @@ static FiosType FiosGetHeightmapListCallback(SaveLoadDialogMode mode, const char
if (type == FIOS_TYPE_INVALID) return FIOS_TYPE_INVALID; if (type == FIOS_TYPE_INVALID) return FIOS_TYPE_INVALID;
TarFileList::iterator it = _tar_filelist.find(file); TarFileList::iterator it = _tar_filelist[SCENARIO_DIR].find(file);
if (it != _tar_filelist.end()) { if (it != _tar_filelist[SCENARIO_DIR].end()) {
/* If the file is in a tar and that tar is not in a heightmap /* If the file is in a tar and that tar is not in a heightmap
* directory we are for sure not supposed to see it. * directory we are for sure not supposed to see it.
* Examples of this are pngs part of documentation within * Examples of this are pngs part of documentation within

View File

@ -535,7 +535,7 @@ void ClientNetworkContentSocketHandler::AfterDownload()
if (this->curInfo->type == CONTENT_TYPE_BASE_MUSIC) { if (this->curInfo->type == CONTENT_TYPE_BASE_MUSIC) {
/* Music can't be in a tar. So extract the tar! */ /* Music can't be in a tar. So extract the tar! */
ExtractTar(GetFullFilename(this->curInfo, false)); ExtractTar(GetFullFilename(this->curInfo, false), GM_DIR);
unlink(GetFullFilename(this->curInfo, false)); unlink(GetFullFilename(this->curInfo, false));
} }

View File

@ -429,6 +429,7 @@ static SQInteger _io_file_read(SQUserPointer file, SQUserPointer buf, SQInteger
{ {
size_t size; size_t size;
FILE *file = FioFOpenFile(filename, "rb", AI_DIR, &size); FILE *file = FioFOpenFile(filename, "rb", AI_DIR, &size);
if (file == NULL) file = FioFOpenFile(filename, "rb", AI_LIBRARY_DIR, &size);
SQInteger ret; SQInteger ret;
unsigned short us; unsigned short us;
unsigned char uc; unsigned char uc;

View File

@ -35,9 +35,9 @@ struct TarFileListEntry {
typedef std::map<std::string, TarListEntry> TarList; typedef std::map<std::string, TarListEntry> TarList;
typedef std::map<std::string, TarFileListEntry> TarFileList; typedef std::map<std::string, TarFileListEntry> TarFileList;
extern TarList _tar_list; extern TarList _tar_list[NUM_SUBDIRS];
extern TarFileList _tar_filelist; extern TarFileList _tar_filelist[NUM_SUBDIRS];
#define FOR_ALL_TARS(tar) for (tar = _tar_filelist.begin(); tar != _tar_filelist.end(); tar++) #define FOR_ALL_TARS(tar, sd) for (tar = _tar_filelist[sd].begin(); tar != _tar_filelist[sd].end(); tar++)
#endif /* TAR_TYPE_H */ #endif /* TAR_TYPE_H */