1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-11-26 12:12:02 +00:00

Perform title sorting at startup and in the background gamecard title info thread, not while retrieving data using non-static functions.

Orphan titles are now sorted by title ID.
This commit is contained in:
Pablo Curiel 2020-08-20 20:18:05 -04:00
parent f809d795e3
commit d6cdfe5c06

View file

@ -403,8 +403,9 @@ static void titleRemoveGameCardTitleInfoEntries(void);
static bool titleIsUserApplicationContentAvailable(u64 app_id); static bool titleIsUserApplicationContentAvailable(u64 app_id);
static TitleInfo *_titleGetInfoFromStorageByTitleId(u8 storage_id, u64 title_id, bool lock); static TitleInfo *_titleGetInfoFromStorageByTitleId(u8 storage_id, u64 title_id, bool lock);
static int titleSystemTitleMetadataComparison(const void *a, const void *b); static int titleSystemTitleMetadataEntrySortFunction(const void *a, const void *b);
static int titleUserApplicationMetadataComparison(const void *a, const void *b); static int titleUserApplicationMetadataEntrySortFunction(const void *a, const void *b);
static int titleOrphanTitleInfoSortFunction(const void *a, const void *b);
bool titleInitialize(void) bool titleInitialize(void)
{ {
@ -606,10 +607,6 @@ TitleApplicationMetadata **titleGetApplicationMetadataEntries(bool is_system, u3
if (app_metadata && app_count) if (app_metadata && app_count)
{ {
/* System titles: sort metadata entries by ID. */
/* User applications: sort metadata entries alphabetically. */
qsort(app_metadata, app_count, sizeof(TitleApplicationMetadata*), is_system ? &titleSystemTitleMetadataComparison : &titleUserApplicationMetadataComparison);
/* Update output counter. */ /* Update output counter. */
*out_count = app_count; *out_count = app_count;
} else { } else {
@ -706,7 +703,10 @@ TitleInfo **titleGetInfoFromOrphanTitles(u32 *out_count)
if ((g_titleInfo[i].meta_key.type == NcmContentMetaType_Patch || g_titleInfo[i].meta_key.type == NcmContentMetaType_AddOnContent) && !g_titleInfo[i].parent) orphan_info[j++] = &(g_titleInfo[i]); if ((g_titleInfo[i].meta_key.type == NcmContentMetaType_Patch || g_titleInfo[i].meta_key.type == NcmContentMetaType_AddOnContent) && !g_titleInfo[i].parent) orphan_info[j++] = &(g_titleInfo[i]);
} }
/* Update counter. */ /* Sort orphan title info entries by title ID. */
if (g_titleInfoOrphanCount > 1) qsort(orphan_info, g_titleInfoOrphanCount, sizeof(TitleInfo*), &titleOrphanTitleInfoSortFunction);
/* Update output counter. */
*out_count = g_titleInfoOrphanCount; *out_count = g_titleInfoOrphanCount;
end: end:
@ -943,6 +943,9 @@ static bool titleGenerateMetadataEntriesFromSystemTitles(void)
sprintf(g_appMetadata[g_appMetadataCount + i].lang_entry.name, g_systemTitles[i].name); sprintf(g_appMetadata[g_appMetadataCount + i].lang_entry.name, g_systemTitles[i].name);
} }
/* Sort metadata entries by title ID. */
qsort(g_appMetadata + g_appMetadataCount, g_systemTitlesCount, sizeof(TitleApplicationMetadata), &titleSystemTitleMetadataEntrySortFunction);
/* Update application metadata count. */ /* Update application metadata count. */
g_appMetadataCount += g_systemTitlesCount; g_appMetadataCount += g_systemTitlesCount;
@ -956,7 +959,7 @@ static bool titleGenerateMetadataEntriesFromNsRecords(void)
NsApplicationRecord *app_records = NULL; NsApplicationRecord *app_records = NULL;
u32 app_records_count = 0; u32 app_records_count = 0;
u32 cur_app_count = g_appMetadataCount; u32 cur_app_count = g_appMetadataCount, new_app_count = 0;
TitleApplicationMetadata *tmp_app_metadata = NULL; TitleApplicationMetadata *tmp_app_metadata = NULL;
bool success = false; bool success = false;
@ -998,35 +1001,43 @@ static bool titleGenerateMetadataEntriesFromNsRecords(void)
/* Retrieve application metadata for each ns application record. */ /* Retrieve application metadata for each ns application record. */
for(u32 i = 0; i < app_records_count; i++) for(u32 i = 0; i < app_records_count; i++)
{ {
if (!titleRetrieveApplicationMetadataByTitleId(app_records[i].application_id, &(g_appMetadata[g_appMetadataCount]))) continue; if (!titleRetrieveApplicationMetadataByTitleId(app_records[i].application_id, &(g_appMetadata[g_appMetadataCount + new_app_count]))) continue;
g_appMetadataCount++; new_app_count++;
} }
/* Check retrieved application metadata count. */ /* Check retrieved application metadata count. */
if (g_appMetadataCount == cur_app_count) if (!new_app_count)
{ {
LOGFILE("Unable to retrieve application metadata from ns application records! (%u %s).", app_records_count, app_records_count > 1 ? "entries" : "entry"); LOGFILE("Unable to retrieve application metadata from ns application records! (%u %s).", app_records_count, app_records_count > 1 ? "entries" : "entry");
goto end; goto end;
} }
/* Decrease application metadata buffer size if needed. */ /* Sort application metadata entries by name. */
if (g_appMetadataCount < (cur_app_count + app_records_count)) if (new_app_count > 1) qsort(g_appMetadata + g_appMetadataCount, new_app_count, sizeof(TitleApplicationMetadata), &titleUserApplicationMetadataEntrySortFunction);
{
TitleApplicationMetadata *tmp_app_metadata = realloc(g_appMetadata, g_appMetadataCount * sizeof(TitleApplicationMetadata)); /* Update application metadata count. */
if (!tmp_app_metadata) g_appMetadataCount += new_app_count;
{
LOGFILE("Failed to reallocate application metadata buffer! (%u %s).", g_appMetadataCount, g_appMetadataCount > 1 ? "entries" : "entry");
goto end;
}
g_appMetadata = tmp_app_metadata;
tmp_app_metadata = NULL;
}
success = true; success = true;
end: end:
if (app_records) free(app_records); if (app_records)
{
/* Decrease application metadata buffer size if needed. */
if (app_records_count && g_appMetadataCount < (cur_app_count + app_records_count))
{
TitleApplicationMetadata *tmp_app_metadata = realloc(g_appMetadata, g_appMetadataCount * sizeof(TitleApplicationMetadata));
if (tmp_app_metadata)
{
g_appMetadata = tmp_app_metadata;
tmp_app_metadata = NULL;
} else {
LOGFILE("Failed to reallocate application metadata buffer! (%u %s).", g_appMetadataCount, g_appMetadataCount > 1 ? "entries" : "entry");
}
}
free(app_records);
}
return success; return success;
} }
@ -1638,9 +1649,7 @@ static bool titleRefreshGameCardTitleInfo(void)
/* Retrieve application metadata. */ /* Retrieve application metadata. */
if (!titleRetrieveApplicationMetadataByTitleId(cur_title_info->meta_key.id, &(g_appMetadata[g_appMetadataCount]))) continue; if (!titleRetrieveApplicationMetadataByTitleId(cur_title_info->meta_key.id, &(g_appMetadata[g_appMetadataCount]))) continue;
cur_title_info->app_metadata = &(g_appMetadata[g_appMetadataCount]); cur_title_info->app_metadata = &(g_appMetadata[g_appMetadataCount++]);
g_appMetadataCount++;
gamecard_metadata_count++; gamecard_metadata_count++;
} }
@ -1658,6 +1667,11 @@ static bool titleRefreshGameCardTitleInfo(void)
goto end; goto end;
} }
/* Sort application metadata entries by name. */
u32 new_app_count = (g_appMetadataCount - g_systemTitlesCount);
if (g_appMetadataCount > orig_app_count && new_app_count > 1) qsort(g_appMetadata + g_systemTitlesCount, new_app_count, sizeof(TitleApplicationMetadata), \
&titleUserApplicationMetadataEntrySortFunction);
success = true; success = true;
cleanup = false; cleanup = false;
@ -1782,10 +1796,10 @@ end:
return info; return info;
} }
static int titleSystemTitleMetadataComparison(const void *a, const void *b) static int titleSystemTitleMetadataEntrySortFunction(const void *a, const void *b)
{ {
const TitleApplicationMetadata *app_metadata_1 = *((const TitleApplicationMetadata**)a); const TitleApplicationMetadata *app_metadata_1 = (const TitleApplicationMetadata*)a;
const TitleApplicationMetadata *app_metadata_2 = *((const TitleApplicationMetadata**)b); const TitleApplicationMetadata *app_metadata_2 = (const TitleApplicationMetadata*)b;
if (app_metadata_1->title_id < app_metadata_2->title_id) if (app_metadata_1->title_id < app_metadata_2->title_id)
{ {
@ -1799,10 +1813,27 @@ static int titleSystemTitleMetadataComparison(const void *a, const void *b)
return 0; return 0;
} }
static int titleUserApplicationMetadataComparison(const void *a, const void *b) static int titleUserApplicationMetadataEntrySortFunction(const void *a, const void *b)
{ {
const TitleApplicationMetadata *app_metadata_1 = *((const TitleApplicationMetadata**)a); const TitleApplicationMetadata *app_metadata_1 = (const TitleApplicationMetadata*)a;
const TitleApplicationMetadata *app_metadata_2 = *((const TitleApplicationMetadata**)b); const TitleApplicationMetadata *app_metadata_2 = (const TitleApplicationMetadata*)b;
return strcasecmp(app_metadata_1->lang_entry.name, app_metadata_2->lang_entry.name); return strcasecmp(app_metadata_1->lang_entry.name, app_metadata_2->lang_entry.name);
} }
static int titleOrphanTitleInfoSortFunction(const void *a, const void *b)
{
const TitleInfo *title_info_1 = *((const TitleInfo**)a);
const TitleInfo *title_info_2 = *((const TitleInfo**)b);
if (title_info_1->meta_key.id < title_info_2->meta_key.id)
{
return -1;
} else
if (title_info_1->meta_key.id > title_info_2->meta_key.id)
{
return 1;
}
return 0;
}