1
0
Fork 0

Use unsigned for numbers in shortened filenames

Bitu (aka uintptr_t) is not necessary for handling shortened files,
as we can represent max 10^7 shortened files anyway; unsigned is good
enough.

This allows use to use simple %u for conversion instead of PRIuPTR,
which caused a bug on AmigaOS on PPC.

Fixes: #162
This commit is contained in:
Patryk Obara 2020-02-05 21:15:31 +01:00 committed by Patryk Obara
parent 4a6704367b
commit 2983de4db4
2 changed files with 22 additions and 18 deletions

View file

@ -196,7 +196,7 @@ public:
bool isDir;
Bit16u id;
Bitu nextEntry;
Bitu shortNr;
unsigned shortNr;
// contents
std::vector<CFileInfo*> fileList;
std::vector<CFileInfo*> longNameList;
@ -209,7 +209,7 @@ private:
bool RemoveTrailingDot (char* shortname);
Bits GetLongName (CFileInfo* info, char* shortname, const size_t shortname_len);
void CreateShortName (CFileInfo* dir, CFileInfo* info);
Bitu CreateShortNameID (CFileInfo* dir, const char* name);
unsigned CreateShortNameID (CFileInfo* dir, const char* name);
int CompareShortname (const char* compareName, const char* shortName);
bool SetResult (CFileInfo* dir, char * &result, Bitu entryNr);
bool IsCachedIn (CFileInfo* dir);

View file

@ -411,33 +411,34 @@ int DOS_Drive_Cache::CompareShortname(const char* compareName, const char* short
return strcmp(compareName,shortName);
}
Bitu DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name) {
unsigned DOS_Drive_Cache::CreateShortNameID(CFileInfo *curDir, const char *name)
{
assert(curDir);
const auto filelist_size = curDir->longNameList.size();
if (filelist_size == 0)
return 1; // short name IDs start with 1
Bitu foundNr = 0;
Bits low = 0;
Bits high = (Bits)(filelist_size-1);
Bits mid, res;
unsigned found_nr = 0;
Bits low = 0;
Bits high = (Bits)(filelist_size - 1);
while (low<=high) {
mid = (low+high)/2;
res = CompareShortname(name,curDir->longNameList[mid]->shortname);
while (low <= high) {
auto mid = (low + high) / 2;
const char *other_shortname = curDir->longNameList[mid]->shortname;
const int res = CompareShortname(name, other_shortname);
if (res>0) low = mid+1; else
if (res<0) high = mid-1;
else {
// any more same x chars in next entries ?
do {
foundNr = curDir->longNameList[mid]->shortNr;
found_nr = curDir->longNameList[mid]->shortNr;
mid++;
} while((Bitu)mid<curDir->longNameList.size() && (CompareShortname(name,curDir->longNameList[mid]->shortname)==0));
} while((Bitu)mid < filelist_size && (CompareShortname(name, curDir->longNameList[mid]->shortname) == 0));
break;
};
}
return foundNr+1;
return found_nr + 1;
}
bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) {
@ -598,8 +599,7 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) {
if (createShort) {
// Create number
char buffer[8];
info->shortNr = CreateShortNameID(curDir,tmpName);
info->shortNr = CreateShortNameID(curDir, tmpName);
// If processing a directory containing 10 million or more long files,
// then ten duplicate short filenames will be named ~1000000.ext,
@ -608,20 +608,24 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) {
// Yes, this is a broken corner-case, but is still memory-safe.
// TODO: modify MOUNT/IMGMOUNT to exit with an error when encountering
// a directory having more than 65534 files, which is FAT32's limit.
snprintf(buffer, sizeof(buffer), "%" PRIuPTR, info->shortNr);
char short_nr[8] = {'\0'};
snprintf(short_nr, sizeof(short_nr), "%u", info->shortNr);
// Copy first letters
Bits tocopy = 0;
size_t buflen = strlen(buffer);
size_t buflen = strlen(short_nr);
if (len + buflen + 1 > 8)
tocopy = (Bits)(8 - buflen - 1);
else
tocopy = len;
// Copy the lesser of "DOS_NAMELENGTH_ASCII" or "tocopy + 1" characters.
safe_strncpy(info->shortname, tmpName,
tocopy < DOS_NAMELENGTH_ASCII ? tocopy + 1 : DOS_NAMELENGTH_ASCII);
// Copy number
strncat(info->shortname, "~", DOS_NAMELENGTH_ASCII - strlen(info->shortname) - 1);
strncat(info->shortname, buffer, DOS_NAMELENGTH_ASCII - strlen(info->shortname) - 1);
strncat(info->shortname, short_nr, DOS_NAMELENGTH_ASCII - strlen(info->shortname) - 1);
// Add (and cut) Extension, if available
if (pos) {
// Step to last extension...