(Playlist) Use flags

This commit is contained in:
libretroadmin 2024-09-05 09:50:11 +02:00
parent 239ea7ef0e
commit 070e018c6c
1 changed files with 169 additions and 150 deletions

View File

@ -61,6 +61,14 @@ typedef struct
bool overwrite_playlist; bool overwrite_playlist;
} playlist_manual_scan_record_t; } playlist_manual_scan_record_t;
enum content_playlist_flags
{
CNT_PLAYLIST_FLG_MOD = (1 << 0),
CNT_PLAYLIST_FLG_OLD_FMT = (1 << 1),
CNT_PLAYLIST_FLG_COMPRESSED = (1 << 2),
CNT_PLAYLIST_FLG_CACHED_EXT = (1 << 3)
};
struct content_playlist struct content_playlist
{ {
char *default_core_path; char *default_core_path;
@ -78,10 +86,15 @@ struct content_playlist
enum playlist_thumbnail_match_mode thumbnail_match_mode; enum playlist_thumbnail_match_mode thumbnail_match_mode;
enum playlist_sort_mode sort_mode; enum playlist_sort_mode sort_mode;
bool modified; uint8_t flags;
bool old_format; };
bool compressed;
bool cached_external; enum json_ctx_flags
{
JSON_CTX_FLG_IN_ITEMS = (1 << 0),
JSON_CTX_FLG_IN_SUBSYSTEM_CONTENT = (1 << 1),
JSON_CTX_FLG_CAPACITY_EXCEEDED = (1 << 2),
JSON_CTX_FLG_OOM = (1 << 3)
}; };
typedef struct typedef struct
@ -99,10 +112,7 @@ typedef struct
unsigned array_depth; unsigned array_depth;
unsigned object_depth; unsigned object_depth;
bool in_items; uint8_t flags;
bool in_subsystem_roms;
bool capacity_exceeded;
bool out_of_memory;
} JSONContext; } JSONContext;
/* TODO/FIXME - global state - perhaps move outside this file */ /* TODO/FIXME - global state - perhaps move outside this file */
@ -120,8 +130,8 @@ void playlist_set_cached_external(playlist_t* pl)
if (!pl) if (!pl)
return; return;
playlist_cached = pl; playlist_cached = pl;
playlist_cached->cached_external = true; playlist_cached->flags |= CNT_PLAYLIST_FLG_CACHED_EXT;
} }
/* Convenience function: copies specified playlist /* Convenience function: copies specified playlist
@ -360,8 +370,8 @@ static bool playlist_path_equal(const char *real_path,
* loads an archive file via the command line or some * loads an archive file via the command line or some
* external launcher (where the [delimiter][rom_file] * external launcher (where the [delimiter][rom_file]
* part is almost always omitted) */ * part is almost always omitted) */
real_path_is_compressed = path_is_compressed_file(real_path); real_path_is_compressed = path_is_compressed_file(real_path);
entry_real_path_is_compressed = path_is_compressed_file(entry_real_path); entry_real_path_is_compressed = path_is_compressed_file(entry_real_path);
if ( (real_path_is_compressed && !entry_real_path_is_compressed) if ( (real_path_is_compressed && !entry_real_path_is_compressed)
|| (!real_path_is_compressed && entry_real_path_is_compressed)) || (!real_path_is_compressed && entry_real_path_is_compressed))
@ -430,8 +440,7 @@ static bool playlist_path_matches_entry(playlist_path_id_t *path_id,
entry->path_id->real_path)) entry->path_id->real_path))
return true; return true;
#else #else
if (string_is_equal(path_id->real_path, if (string_is_equal(path_id->real_path, entry->path_id->real_path))
entry->path_id->real_path))
return true; return true;
#endif #endif
} }
@ -493,7 +502,8 @@ static bool playlist_path_matches_entry(playlist_path_id_t *path_id,
* (Taking into account relative paths, case insensitive * (Taking into account relative paths, case insensitive
* filesystems) * filesystems)
**/ **/
static bool playlist_core_path_equal(const char *real_core_path, const char *entry_core_path, const playlist_config_t *config) static bool playlist_core_path_equal(const char *real_core_path,
const char *entry_core_path, const playlist_config_t *config)
{ {
char entry_real_core_path[PATH_MAX_LENGTH]; char entry_real_core_path[PATH_MAX_LENGTH];
@ -509,21 +519,20 @@ static bool playlist_core_path_equal(const char *real_core_path, const char *ent
playlist_resolve_path(PLAYLIST_SAVE, true, entry_real_core_path, playlist_resolve_path(PLAYLIST_SAVE, true, entry_real_core_path,
sizeof(entry_real_core_path)); sizeof(entry_real_core_path));
if (string_is_empty(entry_real_core_path)) if (!string_is_empty(entry_real_core_path))
return false; {
#ifdef _WIN32 #ifdef _WIN32
/* Handle case-insensitive operating systems*/ /* Handle case-insensitive operating systems*/
if (string_is_equal_noncase(real_core_path, entry_real_core_path)) if (string_is_equal_noncase(real_core_path, entry_real_core_path))
return true; return true;
#else #else
if (string_is_equal(real_core_path, entry_real_core_path)) if (string_is_equal(real_core_path, entry_real_core_path))
return true; return true;
#endif #endif
if ( config->autofix_paths
if ( config->autofix_paths && core_info_core_file_id_is_equal(real_core_path, entry_core_path))
&& core_info_core_file_id_is_equal(real_core_path, entry_core_path)) return true;
return true; }
return false; return false;
} }
@ -654,7 +663,7 @@ void playlist_delete_index(playlist_t *playlist,
RBUF_RESIZE(playlist->entries, len - 1); RBUF_RESIZE(playlist->entries, len - 1);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
/** /**
@ -770,7 +779,7 @@ void playlist_update(playlist_t *playlist, size_t idx,
entry->path_id = NULL; entry->path_id = NULL;
} }
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->label && (update_entry->label != entry->label)) if (update_entry->label && (update_entry->label != entry->label))
@ -778,16 +787,15 @@ void playlist_update(playlist_t *playlist, size_t idx,
if (entry->label) if (entry->label)
free(entry->label); free(entry->label);
entry->label = strdup(update_entry->label); entry->label = strdup(update_entry->label);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->core_path && (update_entry->core_path != entry->core_path)) if (update_entry->core_path && (update_entry->core_path != entry->core_path))
{ {
if (entry->core_path) if (entry->core_path)
free(entry->core_path); free(entry->core_path);
entry->core_path = NULL;
entry->core_path = strdup(update_entry->core_path); entry->core_path = strdup(update_entry->core_path);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->core_name && (update_entry->core_name != entry->core_name)) if (update_entry->core_name && (update_entry->core_name != entry->core_name))
@ -795,7 +803,7 @@ void playlist_update(playlist_t *playlist, size_t idx,
if (entry->core_name) if (entry->core_name)
free(entry->core_name); free(entry->core_name);
entry->core_name = strdup(update_entry->core_name); entry->core_name = strdup(update_entry->core_name);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->db_name && (update_entry->db_name != entry->db_name)) if (update_entry->db_name && (update_entry->db_name != entry->db_name))
@ -803,7 +811,7 @@ void playlist_update(playlist_t *playlist, size_t idx,
if (entry->db_name) if (entry->db_name)
free(entry->db_name); free(entry->db_name);
entry->db_name = strdup(update_entry->db_name); entry->db_name = strdup(update_entry->db_name);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->crc32 && (update_entry->crc32 != entry->crc32)) if (update_entry->crc32 && (update_entry->crc32 != entry->crc32))
@ -811,7 +819,7 @@ void playlist_update(playlist_t *playlist, size_t idx,
if (entry->crc32) if (entry->crc32)
free(entry->crc32); free(entry->crc32);
entry->crc32 = strdup(update_entry->crc32); entry->crc32 = strdup(update_entry->crc32);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -838,85 +846,96 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx,
entry->path_id = NULL; entry->path_id = NULL;
} }
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->core_path && (update_entry->core_path != entry->core_path)) if (update_entry->core_path && (update_entry->core_path != entry->core_path))
{ {
if (entry->core_path) if (entry->core_path)
free(entry->core_path); free(entry->core_path);
entry->core_path = NULL; entry->core_path = strdup(update_entry->core_path);
entry->core_path = strdup(update_entry->core_path); if (register_update)
playlist->modified = playlist->modified || register_update; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->runtime_status != entry->runtime_status) if (update_entry->runtime_status != entry->runtime_status)
{ {
entry->runtime_status = update_entry->runtime_status; entry->runtime_status = update_entry->runtime_status;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->runtime_hours != entry->runtime_hours) if (update_entry->runtime_hours != entry->runtime_hours)
{ {
entry->runtime_hours = update_entry->runtime_hours; entry->runtime_hours = update_entry->runtime_hours;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->runtime_minutes != entry->runtime_minutes) if (update_entry->runtime_minutes != entry->runtime_minutes)
{ {
entry->runtime_minutes = update_entry->runtime_minutes; entry->runtime_minutes = update_entry->runtime_minutes;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->runtime_seconds != entry->runtime_seconds) if (update_entry->runtime_seconds != entry->runtime_seconds)
{ {
entry->runtime_seconds = update_entry->runtime_seconds; entry->runtime_seconds = update_entry->runtime_seconds;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_year != entry->last_played_year) if (update_entry->last_played_year != entry->last_played_year)
{ {
entry->last_played_year = update_entry->last_played_year; entry->last_played_year = update_entry->last_played_year;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_month != entry->last_played_month) if (update_entry->last_played_month != entry->last_played_month)
{ {
entry->last_played_month = update_entry->last_played_month; entry->last_played_month = update_entry->last_played_month;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_day != entry->last_played_day) if (update_entry->last_played_day != entry->last_played_day)
{ {
entry->last_played_day = update_entry->last_played_day; entry->last_played_day = update_entry->last_played_day;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_hour != entry->last_played_hour) if (update_entry->last_played_hour != entry->last_played_hour)
{ {
entry->last_played_hour = update_entry->last_played_hour; entry->last_played_hour = update_entry->last_played_hour;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_minute != entry->last_played_minute) if (update_entry->last_played_minute != entry->last_played_minute)
{ {
entry->last_played_minute = update_entry->last_played_minute; entry->last_played_minute = update_entry->last_played_minute;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_second != entry->last_played_second) if (update_entry->last_played_second != entry->last_played_second)
{ {
entry->last_played_second = update_entry->last_played_second; entry->last_played_second = update_entry->last_played_second;
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->runtime_str && (update_entry->runtime_str != entry->runtime_str)) if (update_entry->runtime_str && (update_entry->runtime_str != entry->runtime_str))
{ {
if (entry->runtime_str) if (entry->runtime_str)
free(entry->runtime_str); free(entry->runtime_str);
entry->runtime_str = NULL; entry->runtime_str = strdup(update_entry->runtime_str);
entry->runtime_str = strdup(update_entry->runtime_str); if (register_update)
playlist->modified = playlist->modified || register_update; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
if (update_entry->last_played_str && (update_entry->last_played_str != entry->last_played_str)) if (update_entry->last_played_str && (update_entry->last_played_str != entry->last_played_str))
@ -925,7 +944,8 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx,
free(entry->last_played_str); free(entry->last_played_str);
entry->last_played_str = NULL; entry->last_played_str = NULL;
entry->last_played_str = strdup(update_entry->last_played_str); entry->last_played_str = strdup(update_entry->last_played_str);
playlist->modified = playlist->modified || register_update; if (register_update)
playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -1050,7 +1070,7 @@ bool playlist_push_runtime(playlist_t *playlist,
success: success:
if (path_id) if (path_id)
playlist_path_id_free(path_id); playlist_path_id_free(path_id);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
return true; return true;
error: error:
@ -1532,7 +1552,7 @@ bool playlist_push(playlist_t *playlist,
success: success:
if (path_id) if (path_id)
playlist_path_id_free(path_id); playlist_path_id_free(path_id);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
return true; return true;
error: error:
@ -1547,7 +1567,7 @@ void playlist_write_runtime_file(playlist_t *playlist)
intfstream_t *file = NULL; intfstream_t *file = NULL;
rjsonwriter_t* writer; rjsonwriter_t* writer;
if (!playlist || !playlist->modified) if (!playlist || !(playlist->flags & CNT_PLAYLIST_FLG_MOD))
return; return;
if (!(file = intfstream_open_file(playlist->config.path, if (!(file = intfstream_open_file(playlist->config.path,
@ -1688,9 +1708,9 @@ void playlist_write_runtime_file(playlist_t *playlist)
rjsonwriter_raw(writer, "\n", 1); rjsonwriter_raw(writer, "\n", 1);
rjsonwriter_free(writer); rjsonwriter_free(writer);
playlist->modified = false; playlist->flags &= ~CNT_PLAYLIST_FLG_MOD;
playlist->old_format = false; playlist->flags &= ~CNT_PLAYLIST_FLG_OLD_FMT;
playlist->compressed = false; playlist->flags &= ~CNT_PLAYLIST_FLG_COMPRESSED;
RARCH_LOG("[Playlist]: Written to playlist file: \"%s\".\n", playlist->config.path); RARCH_LOG("[Playlist]: Written to playlist file: \"%s\".\n", playlist->config.path);
end: end:
@ -1711,12 +1731,15 @@ void playlist_write_file(playlist_t *playlist)
* match requested * match requested
* > Current playlist compression status does * > Current playlist compression status does
* not match requested */ * not match requested */
if (!playlist || bool pl_compressed = ((playlist->flags & CNT_PLAYLIST_FLG_COMPRESSED) > 0);
!(playlist->modified || bool pl_old_fmt = ((playlist->flags & CNT_PLAYLIST_FLG_OLD_FMT) > 0);
if ( !playlist
|| !((playlist->flags & CNT_PLAYLIST_FLG_MOD) ||
#if defined(HAVE_ZLIB) #if defined(HAVE_ZLIB)
(playlist->compressed != playlist->config.compress) || (pl_compressed != playlist->config.compress) ||
#endif #endif
(playlist->old_format != playlist->config.old_format))) (pl_old_fmt != playlist->config.old_format)))
return; return;
#if defined(HAVE_ZLIB) #if defined(HAVE_ZLIB)
@ -1768,7 +1791,7 @@ void playlist_write_file(playlist_t *playlist)
playlist->right_thumbnail_mode, playlist->left_thumbnail_mode, playlist->right_thumbnail_mode, playlist->left_thumbnail_mode,
playlist->sort_mode); playlist->sort_mode);
playlist->old_format = true; playlist->flags |= (CNT_PLAYLIST_FLG_OLD_FMT);
} }
else else
#endif #endif
@ -2083,11 +2106,15 @@ void playlist_write_file(playlist_t *playlist)
RARCH_ERR("Failed to write to playlist file: \"%s\".\n", playlist->config.path); RARCH_ERR("Failed to write to playlist file: \"%s\".\n", playlist->config.path);
} }
playlist->old_format = false; playlist->flags &= ~(CNT_PLAYLIST_FLG_OLD_FMT);
} }
playlist->modified = false; playlist->flags &= ~CNT_PLAYLIST_FLG_MOD;
playlist->compressed = compressed;
if (compressed)
playlist->flags |= (CNT_PLAYLIST_FLG_COMPRESSED);
else
playlist->flags &= ~(CNT_PLAYLIST_FLG_COMPRESSED);
RARCH_LOG("[Playlist]: Written to playlist file: \"%s\".\n", playlist->config.path); RARCH_LOG("[Playlist]: Written to playlist file: \"%s\".\n", playlist->config.path);
end: end:
@ -2213,14 +2240,14 @@ static bool JSONEndArrayHandler(void *context)
pCtx->array_depth--; pCtx->array_depth--;
if ( pCtx->in_items if ( (pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& (pCtx->array_depth == 0) && (pCtx->array_depth == 0)
&& (pCtx->object_depth <= 1)) && (pCtx->object_depth <= 1))
pCtx->in_items = false; pCtx->flags &= (JSON_CTX_FLG_IN_ITEMS);
else if (pCtx->in_subsystem_roms else if ((pCtx->flags & JSON_CTX_FLG_IN_SUBSYSTEM_CONTENT)
&& (pCtx->array_depth <= 1) && (pCtx->array_depth <= 1)
&& (pCtx->object_depth <= 2)) && (pCtx->object_depth <= 2))
pCtx->in_subsystem_roms = false; pCtx->flags &= (JSON_CTX_FLG_IN_SUBSYSTEM_CONTENT);
return true; return true;
} }
@ -2231,12 +2258,12 @@ static bool JSONStartObjectHandler(void *context)
pCtx->object_depth++; pCtx->object_depth++;
if ( pCtx->in_items if ( (pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& (pCtx->object_depth == 2)) && (pCtx->object_depth == 2))
{ {
if ( if (
(pCtx->array_depth == 1) (pCtx->array_depth == 1)
&& !pCtx->capacity_exceeded) && !(pCtx->flags & JSON_CTX_FLG_CAPACITY_EXCEEDED))
{ {
size_t len = RBUF_LEN(pCtx->playlist->entries); size_t len = RBUF_LEN(pCtx->playlist->entries);
if (len < pCtx->playlist->config.capacity) if (len < pCtx->playlist->config.capacity)
@ -2245,7 +2272,7 @@ static bool JSONStartObjectHandler(void *context)
* buffer just yet, wait until JSONEndObjectHandler for that */ * buffer just yet, wait until JSONEndObjectHandler for that */
if (!RBUF_TRYFIT(pCtx->playlist->entries, len + 1)) if (!RBUF_TRYFIT(pCtx->playlist->entries, len + 1))
{ {
pCtx->out_of_memory = true; pCtx->flags |= JSON_CTX_FLG_OOM;
return false; return false;
} }
pCtx->current_entry = &pCtx->playlist->entries[len]; pCtx->current_entry = &pCtx->playlist->entries[len];
@ -2257,13 +2284,13 @@ static bool JSONStartObjectHandler(void *context)
* Note: We can't just abort here, since there may * Note: We can't just abort here, since there may
* be more metadata to read at the end of the file... */ * be more metadata to read at the end of the file... */
RARCH_WARN("JSON file contains more entries than current playlist capacity. Excess entries will be discarded.\n"); RARCH_WARN("JSON file contains more entries than current playlist capacity. Excess entries will be discarded.\n");
pCtx->capacity_exceeded = true; pCtx->flags |= JSON_CTX_FLG_CAPACITY_EXCEEDED;
pCtx->current_entry = NULL; pCtx->current_entry = NULL;
/* In addition, since we are discarding excess entries, /* In addition, since we are discarding excess entries,
* the playlist must be flagged as being modified * the playlist must be flagged as being modified
* (i.e. the playlist is not the same as when it was * (i.e. the playlist is not the same as when it was
* last saved to disk...) */ * last saved to disk...) */
pCtx->playlist->modified = true; pCtx->playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
} }
@ -2275,11 +2302,11 @@ static bool JSONEndObjectHandler(void *context)
{ {
JSONContext *pCtx = (JSONContext *)context; JSONContext *pCtx = (JSONContext *)context;
if ( pCtx->in_items if ( (pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& pCtx->object_depth == 2) && (pCtx->object_depth == 2))
{ {
if ( (pCtx->array_depth == 1) if ( (pCtx->array_depth == 1)
&& !pCtx->capacity_exceeded) && !(pCtx->flags & JSON_CTX_FLG_CAPACITY_EXCEEDED))
RBUF_RESIZE(pCtx->playlist->entries, RBUF_RESIZE(pCtx->playlist->entries,
RBUF_LEN(pCtx->playlist->entries) + 1); RBUF_LEN(pCtx->playlist->entries) + 1);
} }
@ -2293,8 +2320,8 @@ static bool JSONStringHandler(void *context, const char *pValue, size_t length)
{ {
JSONContext *pCtx = (JSONContext *)context; JSONContext *pCtx = (JSONContext *)context;
if ( pCtx->in_items if ( (pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& pCtx->in_subsystem_roms && (pCtx->flags & JSON_CTX_FLG_IN_SUBSYSTEM_CONTENT)
&& (pCtx->object_depth == 2) && (pCtx->object_depth == 2)
&& (pCtx->array_depth == 2)) && (pCtx->array_depth == 2))
{ {
@ -2308,7 +2335,7 @@ static bool JSONStringHandler(void *context, const char *pValue, size_t length)
string_list_append(pCtx->current_entry->subsystem_roms, pValue, attr); string_list_append(pCtx->current_entry->subsystem_roms, pValue, attr);
} }
} }
else if ((pCtx->in_items) else if ((pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& (pCtx->object_depth == 2)) && (pCtx->object_depth == 2))
{ {
if (pCtx->array_depth == 1) if (pCtx->array_depth == 1)
@ -2348,7 +2375,7 @@ static bool JSONNumberHandler(void *context, const char *pValue, size_t length)
{ {
JSONContext *pCtx = (JSONContext *)context; JSONContext *pCtx = (JSONContext *)context;
if ( pCtx->in_items if ( (pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& (pCtx->object_depth == 2)) && (pCtx->object_depth == 2))
{ {
if ( (pCtx->array_depth == 1) if ( (pCtx->array_depth == 1)
@ -2391,7 +2418,7 @@ static bool JSONBoolHandler(void *context, bool value)
{ {
JSONContext *pCtx = (JSONContext *)context; JSONContext *pCtx = (JSONContext *)context;
if ( !pCtx->in_items if ( (!(pCtx->flags & JSON_CTX_FLG_IN_ITEMS))
&& (pCtx->object_depth == 1) && (pCtx->object_depth == 1)
&& (pCtx->array_depth == 0) && (pCtx->array_depth == 0)
&& pCtx->current_meta_bool_val) && pCtx->current_meta_bool_val)
@ -2406,7 +2433,7 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
{ {
JSONContext *pCtx = (JSONContext *)context; JSONContext *pCtx = (JSONContext *)context;
if ( pCtx->in_items if ( (pCtx->flags & JSON_CTX_FLG_IN_ITEMS)
&& (pCtx->object_depth == 2)) && (pCtx->object_depth == 2))
{ {
if (pCtx->array_depth == 1) if (pCtx->array_depth == 1)
@ -2415,11 +2442,11 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
if (pCtx->current_string_val) if (pCtx->current_string_val)
return false; return false;
if (length && !pCtx->capacity_exceeded) if (length && (!(pCtx->flags & JSON_CTX_FLG_CAPACITY_EXCEEDED)))
{ {
pCtx->current_string_val = NULL; pCtx->current_string_val = NULL;
pCtx->current_entry_uint_val = NULL; pCtx->current_entry_uint_val = NULL;
pCtx->in_subsystem_roms = false; pCtx->flags &= ~(JSON_CTX_FLG_IN_SUBSYSTEM_CONTENT);
switch (pValue[0]) switch (pValue[0])
{ {
case 'c': case 'c':
@ -2472,7 +2499,7 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
else if (string_is_equal(pValue, "subsystem_name")) else if (string_is_equal(pValue, "subsystem_name"))
pCtx->current_string_val = &pCtx->current_entry->subsystem_name; pCtx->current_string_val = &pCtx->current_entry->subsystem_name;
else if (string_is_equal(pValue, "subsystem_roms")) else if (string_is_equal(pValue, "subsystem_roms"))
pCtx->in_subsystem_roms = true; pCtx->flags |= (JSON_CTX_FLG_IN_SUBSYSTEM_CONTENT);
break; break;
} }
} }
@ -2488,7 +2515,7 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
pCtx->current_meta_thumbnail_match_mode_val = NULL; pCtx->current_meta_thumbnail_match_mode_val = NULL;
pCtx->current_meta_sort_mode_val = NULL; pCtx->current_meta_sort_mode_val = NULL;
pCtx->current_meta_bool_val = NULL; pCtx->current_meta_bool_val = NULL;
pCtx->in_items = false; pCtx->flags &= ~(JSON_CTX_FLG_IN_ITEMS);
switch (pValue[0]) switch (pValue[0])
{ {
@ -2504,7 +2531,7 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le
break; break;
case 'i': case 'i':
if (string_is_equal(pValue, "items")) if (string_is_equal(pValue, "items"))
pCtx->in_items = true; pCtx->flags |= JSON_CTX_FLG_IN_ITEMS;
break; break;
case 'l': case 'l':
if (string_is_equal(pValue, "label_display_mode")) if (string_is_equal(pValue, "label_display_mode"))
@ -2554,9 +2581,7 @@ static void playlist_get_old_format_metadata_value(
return; return;
start++; start++;
end = strchr(start, '\"'); if (!(end = strchr(start, '\"')))
if (!end)
return; return;
*end = '\0'; *end = '\0';
@ -2587,7 +2612,10 @@ static bool playlist_read_file(playlist_t *playlist)
if (!file) if (!file)
return true; return true;
playlist->compressed = intfstream_is_compressed(file); if (intfstream_is_compressed(file))
playlist->flags |= CNT_PLAYLIST_FLG_COMPRESSED;
else
playlist->flags &= ~CNT_PLAYLIST_FLG_COMPRESSED;
/* Detect format of playlist /* Detect format of playlist
* > Read file until we find the first printable * > Read file until we find the first printable
@ -2599,12 +2627,15 @@ static bool playlist_read_file(playlist_t *playlist)
goto end; goto end;
} while (!isgraph(test_char) || test_char > 0x7F); } while (!isgraph(test_char) || test_char > 0x7F);
playlist->old_format = (test_char != '{'); if (test_char != '{')
playlist->flags |= (CNT_PLAYLIST_FLG_OLD_FMT);
else
playlist->flags &= ~(CNT_PLAYLIST_FLG_OLD_FMT);
/* Reset file to start */ /* Reset file to start */
intfstream_rewind(file); intfstream_rewind(file);
if (!playlist->old_format) if (!(playlist->flags & CNT_PLAYLIST_FLG_OLD_FMT))
{ {
rjson_t* parser; rjson_t* parser;
JSONContext context = {0}; JSONContext context = {0};
@ -2634,7 +2665,7 @@ static bool playlist_read_file(playlist_t *playlist)
NULL) /* Unused null handler */ NULL) /* Unused null handler */
!= RJSON_DONE) != RJSON_DONE)
{ {
if (context.out_of_memory) if (context.flags & JSON_CTX_FLG_OOM)
{ {
RARCH_WARN("Ran out of memory while parsing JSON playlist\n"); RARCH_WARN("Ran out of memory while parsing JSON playlist\n");
res = false; res = false;
@ -2791,7 +2822,7 @@ static bool playlist_read_file(playlist_t *playlist)
STRLEN_CONST("thumbnail_mode")) == 0) STRLEN_CONST("thumbnail_mode")) == 0)
{ {
char *tok, *save; char *tok, *save;
char thumbnail_mode_str[8] = {0}; char thumbnail_mode_str[8] = {0};
char *thumbnail_mode_str_cpy = strdup(thumbnail_mode_str); char *thumbnail_mode_str_cpy = strdup(thumbnail_mode_str);
playlist_get_old_format_metadata_value( playlist_get_old_format_metadata_value(
@ -2852,7 +2883,7 @@ end:
void playlist_free_cached(void) void playlist_free_cached(void)
{ {
if (playlist_cached && !playlist_cached->cached_external) if (playlist_cached && !(playlist_cached->flags & CNT_PLAYLIST_FLG_CACHED_EXT))
playlist_free(playlist_cached); playlist_free(playlist_cached);
playlist_cached = NULL; playlist_cached = NULL;
} }
@ -2866,18 +2897,21 @@ playlist_t *playlist_get_cached(void)
bool playlist_init_cached(const playlist_config_t *config) bool playlist_init_cached(const playlist_config_t *config)
{ {
bool pl_compressed, pl_old_fmt;
playlist_t *playlist = playlist_init(config); playlist_t *playlist = playlist_init(config);
if (!playlist) if (!playlist)
return false; return false;
pl_compressed = ((playlist->flags & CNT_PLAYLIST_FLG_COMPRESSED) > 0);
pl_old_fmt = ((playlist->flags & CNT_PLAYLIST_FLG_OLD_FMT) > 0);
/* If playlist format/compression state /* If playlist format/compression state
* does not match requested settings, update * does not match requested settings, update
* file on disk immediately */ * file on disk immediately */
if ( if (
#if defined(HAVE_ZLIB) #if defined(HAVE_ZLIB)
(playlist->compressed != playlist->config.compress) || (pl_compressed != playlist->config.compress) ||
#endif #endif
(playlist->old_format != playlist->config.old_format)) (pl_old_fmt != playlist->config.old_format))
playlist_write_file(playlist); playlist_write_file(playlist);
playlist_cached = playlist; playlist_cached = playlist;
@ -2896,22 +2930,19 @@ playlist_t *playlist_init(const playlist_config_t *config)
{ {
playlist_t *playlist = (playlist_t*)malloc(sizeof(*playlist)); playlist_t *playlist = (playlist_t*)malloc(sizeof(*playlist));
if (!playlist) if (!playlist)
goto error; return NULL;
/* Set initial values */ /* Set initial values */
playlist->modified = false; playlist->flags = 0;
playlist->old_format = false; playlist->default_core_name = NULL;
playlist->compressed = false; playlist->default_core_path = NULL;
playlist->cached_external = false; playlist->base_content_directory = NULL;
playlist->default_core_name = NULL; playlist->entries = NULL;
playlist->default_core_path = NULL; playlist->label_display_mode = LABEL_DISPLAY_MODE_DEFAULT;
playlist->base_content_directory = NULL; playlist->right_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
playlist->entries = NULL; playlist->left_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
playlist->label_display_mode = LABEL_DISPLAY_MODE_DEFAULT; playlist->thumbnail_match_mode = PLAYLIST_THUMBNAIL_MATCH_MODE_DEFAULT;
playlist->right_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; playlist->sort_mode = PLAYLIST_SORT_MODE_DEFAULT;
playlist->left_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
playlist->thumbnail_match_mode = PLAYLIST_THUMBNAIL_MATCH_MODE_DEFAULT;
playlist->sort_mode = PLAYLIST_SORT_MODE_DEFAULT;
playlist->scan_record.search_recursively = false; playlist->scan_record.search_recursively = false;
playlist->scan_record.search_archives = false; playlist->scan_record.search_archives = false;
@ -3025,7 +3056,7 @@ playlist_t *playlist_init(const playlist_config_t *config)
playlist->base_content_directory = strdup(playlist->config.base_content_directory); playlist->base_content_directory = strdup(playlist->config.base_content_directory);
/* Save playlist */ /* Save playlist */
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
playlist_write_file(playlist); playlist_write_file(playlist);
} }
@ -3160,12 +3191,8 @@ void command_playlist_update_write(
bool playlist_index_is_valid(playlist_t *playlist, size_t idx, bool playlist_index_is_valid(playlist_t *playlist, size_t idx,
const char *path, const char *core_path) const char *path, const char *core_path)
{ {
if (!playlist) if (!playlist || idx >= RBUF_LEN(playlist->entries))
return false; return false;
if (idx >= RBUF_LEN(playlist->entries))
return false;
return playlist_path_equal(path, playlist->entries[idx].path, &playlist->config) return playlist_path_equal(path, playlist->entries[idx].path, &playlist->config)
&& string_is_equal(path_basename_nocompression(playlist->entries[idx].core_path), && string_is_equal(path_basename_nocompression(playlist->entries[idx].core_path),
path_basename_nocompression(core_path)); path_basename_nocompression(core_path));
@ -3223,9 +3250,9 @@ bool playlist_entries_are_equal(
bool playlist_index_entries_are_equal( bool playlist_index_entries_are_equal(
playlist_t *playlist, size_t idx_a, size_t idx_b) playlist_t *playlist, size_t idx_a, size_t idx_b)
{ {
size_t len;
struct playlist_entry *entry_a = NULL; struct playlist_entry *entry_a = NULL;
struct playlist_entry *entry_b = NULL; struct playlist_entry *entry_b = NULL;
size_t len;
if (!playlist) if (!playlist)
return false; return false;
@ -3277,11 +3304,9 @@ void playlist_get_db_name(playlist_t *playlist, size_t idx,
/* Only use file basename if this is a 'collection' playlist /* Only use file basename if this is a 'collection' playlist
* (i.e. ignore history/favourites) */ * (i.e. ignore history/favourites) */
if ( if (
!string_is_empty(conf_path_basename) !string_is_empty(conf_path_basename)
&& !string_is_equal(conf_path_basename, && !string_is_equal(conf_path_basename, FILE_PATH_CONTENT_HISTORY)
FILE_PATH_CONTENT_HISTORY) && !string_is_equal(conf_path_basename, FILE_PATH_CONTENT_FAVORITES)
&& !string_is_equal(conf_path_basename,
FILE_PATH_CONTENT_FAVORITES)
) )
*db_name = conf_path_basename; *db_name = conf_path_basename;
else else
@ -3295,23 +3320,17 @@ void playlist_get_db_name(playlist_t *playlist, size_t idx,
const char *playlist_get_default_core_path(playlist_t *playlist) const char *playlist_get_default_core_path(playlist_t *playlist)
{ {
if (!playlist) return playlist ? playlist->default_core_path : NULL;
return NULL;
return playlist->default_core_path;
} }
const char *playlist_get_default_core_name(playlist_t *playlist) const char *playlist_get_default_core_name(playlist_t *playlist)
{ {
if (!playlist) return playlist ? playlist->default_core_name : NULL;
return NULL;
return playlist->default_core_name;
} }
enum playlist_label_display_mode playlist_get_label_display_mode(playlist_t *playlist) enum playlist_label_display_mode playlist_get_label_display_mode(playlist_t *playlist)
{ {
if (!playlist) return playlist ? playlist->label_display_mode : LABEL_DISPLAY_MODE_DEFAULT;
return LABEL_DISPLAY_MODE_DEFAULT;
return playlist->label_display_mode;
} }
enum playlist_thumbnail_mode playlist_get_thumbnail_mode( enum playlist_thumbnail_mode playlist_get_thumbnail_mode(
@ -3421,7 +3440,7 @@ void playlist_set_default_core_path(playlist_t *playlist,
if (playlist->default_core_path) if (playlist->default_core_path)
free(playlist->default_core_path); free(playlist->default_core_path);
playlist->default_core_path = strdup(real_core_path); playlist->default_core_path = strdup(real_core_path);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3436,7 +3455,7 @@ void playlist_set_default_core_name(
if (playlist->default_core_name) if (playlist->default_core_name)
free(playlist->default_core_name); free(playlist->default_core_name);
playlist->default_core_name = strdup(core_name); playlist->default_core_name = strdup(core_name);
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3446,7 +3465,7 @@ void playlist_set_label_display_mode(playlist_t *playlist,
if (playlist && playlist->label_display_mode != label_display_mode) if (playlist && playlist->label_display_mode != label_display_mode)
{ {
playlist->label_display_mode = label_display_mode; playlist->label_display_mode = label_display_mode;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3461,11 +3480,11 @@ void playlist_set_thumbnail_mode(
{ {
case PLAYLIST_THUMBNAIL_RIGHT: case PLAYLIST_THUMBNAIL_RIGHT:
playlist->right_thumbnail_mode = thumbnail_mode; playlist->right_thumbnail_mode = thumbnail_mode;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
break; break;
case PLAYLIST_THUMBNAIL_LEFT: case PLAYLIST_THUMBNAIL_LEFT:
playlist->left_thumbnail_mode = thumbnail_mode; playlist->left_thumbnail_mode = thumbnail_mode;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
break; break;
case PLAYLIST_THUMBNAIL_ICON: case PLAYLIST_THUMBNAIL_ICON:
/* should never be reached. Do Nothing */ /* should never be reached. Do Nothing */
@ -3480,7 +3499,7 @@ void playlist_set_sort_mode(playlist_t *playlist,
if (playlist && playlist->sort_mode != sort_mode) if (playlist && playlist->sort_mode != sort_mode)
{ {
playlist->sort_mode = sort_mode; playlist->sort_mode = sort_mode;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3501,7 +3520,7 @@ void playlist_set_scan_content_dir(playlist_t *playlist, const char *content_dir
if ( (current_string_empty && !new_string_empty) if ( (current_string_empty && !new_string_empty)
|| (!current_string_empty && new_string_empty) || (!current_string_empty && new_string_empty)
|| !string_is_equal(playlist->scan_record.content_dir, content_dir)) || !string_is_equal(playlist->scan_record.content_dir, content_dir))
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
else else
return; /* Strings are identical; do nothing */ return; /* Strings are identical; do nothing */
@ -3532,7 +3551,7 @@ void playlist_set_scan_file_exts(playlist_t *playlist, const char *file_exts)
if ( ( current_string_empty && !new_string_empty) if ( ( current_string_empty && !new_string_empty)
|| (!current_string_empty && new_string_empty) || (!current_string_empty && new_string_empty)
|| !string_is_equal(playlist->scan_record.file_exts, file_exts)) || !string_is_equal(playlist->scan_record.file_exts, file_exts))
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
else else
return; /* Strings are identical; do nothing */ return; /* Strings are identical; do nothing */
@ -3563,7 +3582,7 @@ void playlist_set_scan_dat_file_path(playlist_t *playlist, const char *dat_file_
if ( ( current_string_empty && !new_string_empty) if ( ( current_string_empty && !new_string_empty)
|| (!current_string_empty && new_string_empty) || (!current_string_empty && new_string_empty)
|| !string_is_equal(playlist->scan_record.dat_file_path, dat_file_path)) || !string_is_equal(playlist->scan_record.dat_file_path, dat_file_path))
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
else else
return; /* Strings are identical; do nothing */ return; /* Strings are identical; do nothing */
@ -3582,7 +3601,7 @@ void playlist_set_scan_search_recursively(playlist_t *playlist, bool search_recu
if (playlist && playlist->scan_record.search_recursively != search_recursively) if (playlist && playlist->scan_record.search_recursively != search_recursively)
{ {
playlist->scan_record.search_recursively = search_recursively; playlist->scan_record.search_recursively = search_recursively;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3591,7 +3610,7 @@ void playlist_set_scan_search_archives(playlist_t *playlist, bool search_archive
if (playlist && playlist->scan_record.search_archives != search_archives) if (playlist && playlist->scan_record.search_archives != search_archives)
{ {
playlist->scan_record.search_archives = search_archives; playlist->scan_record.search_archives = search_archives;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3600,7 +3619,7 @@ void playlist_set_scan_filter_dat_content(playlist_t *playlist, bool filter_dat_
if (playlist && playlist->scan_record.filter_dat_content != filter_dat_content) if (playlist && playlist->scan_record.filter_dat_content != filter_dat_content)
{ {
playlist->scan_record.filter_dat_content = filter_dat_content; playlist->scan_record.filter_dat_content = filter_dat_content;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }
@ -3609,7 +3628,7 @@ void playlist_set_scan_overwrite_playlist(playlist_t *playlist, bool overwrite_p
if (playlist && playlist->scan_record.overwrite_playlist != overwrite_playlist) if (playlist && playlist->scan_record.overwrite_playlist != overwrite_playlist)
{ {
playlist->scan_record.overwrite_playlist = overwrite_playlist; playlist->scan_record.overwrite_playlist = overwrite_playlist;
playlist->modified = true; playlist->flags |= CNT_PLAYLIST_FLG_MOD;
} }
} }