diff --git a/lib/include/edapi/journal/entry.h b/lib/include/edapi/journal/entry.h index fc2b2b2..ba2a391 100644 --- a/lib/include/edapi/journal/entry.h +++ b/lib/include/edapi/journal/entry.h @@ -6,6 +6,9 @@ #include #include +#define ED_JOURNAL_ENTRY_FILEHEADER "Fileheader" +#define ED_JOURNAL_ENTRY_COMMANDER "Commander" + G_BEGIN_DECLS struct _EDJournalEntryClass { @@ -19,14 +22,37 @@ G_DECLARE_DERIVABLE_TYPE( #define ED_TYPE_JOURNALENTRY ed_journal_entry_get_type() +/** + * Returns a new EDJournalEntry object. + */ EDJournalEntry *ed_journal_entry_new(void); +/** + * Returns a new EDJournalEntry object, and automatically parses + * the given JSON line. + */ EDJournalEntry *ed_journal_entry_new_parse(gchar const *line, GError **error); EDErrorCode ed_journal_entry_parse(EDJournalEntry *self, gchar const *line, GError **error); +/** + * Returns the underlying json_t pointer. This is a jansson + * pointer and it should not be freed. + */ +void *ed_journal_entry_get_json(EDJournalEntry *self); + +gchar const *ed_journal_entry_get_string(EDJournalEntry *self, + gchar const *name); + +gchar const *ed_journal_entry_get_event(EDJournalEntry *self); + +/** + * Returns true if the journal entry is of the given event. + */ +gboolean ed_journal_entry_is(EDJournalEntry *self, gchar const *event); + G_END_DECLS #endif diff --git a/lib/include/edapi/journal/file.h b/lib/include/edapi/journal/file.h index 4534f32..1202ddb 100644 --- a/lib/include/edapi/journal/file.h +++ b/lib/include/edapi/journal/file.h @@ -20,14 +20,28 @@ EDErrorCode ed_journal_file_parse_filename( gint *part ); -EDErrorCode ed_journal_file_parse(EDJournalFile *file, char const *filename); - +/** + * Opens the given journal file, and peeks into it. This + * function fails if the given file cannot be opened. Loading + * entries is a time consuming task (especially with multiple + * files in a journal), so this function only peeks the first + * few entries to figure out game version and CMDR name. + */ EDErrorCode ed_journal_file_open(EDJournalFile *file, char const *filename, GError **error); +/** + * Load all entries from this given journal. + */ +EDErrorCode ed_journal_file_load(EDJournalFile *self, GError **error); + GDateTime *ed_journal_file_get_datetime(EDJournalFile *self); +gchar const *ed_journal_file_get_commander(EDJournalFile *self); + +gchar const *ed_journal_file_get_gameversion(EDJournalFile *self); + G_END_DECLS #endif diff --git a/lib/src/journal/entry.c b/lib/src/journal/entry.c index b6feed2..d5ff3bc 100644 --- a/lib/src/journal/entry.c +++ b/lib/src/journal/entry.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -93,3 +94,37 @@ EDErrorCode ed_journal_entry_parse(EDJournalEntry *self, return ret; } + +void *ed_journal_entry_get_json(EDJournalEntry *self) +{ + return_if_true(self == NULL, NULL); + EDJournalEntryPrivate *p = ed_journal_entry_get_instance_private(self); + return p->entry; +} + +gchar const *ed_journal_entry_get_string(EDJournalEntry *self, + gchar const *name) +{ + EDJournalEntryPrivate *p = ed_journal_entry_get_instance_private(self); + return_if_true(p->entry == NULL, NULL); + + json_t *j = json_object_get(p->entry, name); + return_if_true(j == NULL || !json_is_string(j), NULL); + + return json_string_value(j); +} + +gchar const *ed_journal_entry_get_event(EDJournalEntry *self) +{ + return ed_journal_entry_get_string(self, "event"); +} + +gboolean ed_journal_entry_is(EDJournalEntry *self, gchar const *event) +{ + return_if_true(self == NULL || S_EMPTY(event), FALSE); + + gchar const *ev = ed_journal_entry_get_event(self); + return_if_true(ev == NULL, FALSE); + + return (g_ascii_strcasecmp(ev, event) == 0); +} diff --git a/lib/src/journal/file.c b/lib/src/journal/file.c index 5b2e514..1c6e03f 100644 --- a/lib/src/journal/file.c +++ b/lib/src/journal/file.c @@ -11,6 +11,8 @@ typedef struct { GDateTime *timestamp; gint part; GList *entries; + gchar *commander; + gchar *gameversion; } EDJournalFilePrivate; struct _EDJournalFile { @@ -34,10 +36,10 @@ static void ed_journal_file_finalize(GObject *obj) EDJournalFile *self = ED_JOURNALFILE(obj); EDJournalFilePrivate *p = ed_journal_file_get_instance_private(self); - free(p->filename); + g_free(p->filename); p->filename = NULL; - free(p->datetime); + g_free(p->datetime); p->datetime = NULL; if (p->timestamp != NULL) { @@ -48,6 +50,12 @@ static void ed_journal_file_finalize(GObject *obj) p->timestamp = NULL; } + g_free(p->commander); + p->commander = NULL; + + g_free(p->gameversion); + p->gameversion = NULL; + g_list_free_full(p->entries, g_object_unref); p->entries = NULL; @@ -165,7 +173,8 @@ static EDErrorCode ed_journal_file_parse_timestamp(EDJournalFile *file) return ed_error_invalid; } -EDErrorCode ed_journal_file_parse(EDJournalFile *self, char const *filename) +static EDErrorCode ed_journal_file_parse_(EDJournalFile *self, + char const *filename) { EDJournalFilePrivate *p = ed_journal_file_get_instance_private(self); gchar *basename = NULL; @@ -202,8 +211,43 @@ done: return ret; } -static EDErrorCode ed_journal_file_load(EDJournalFile *self, - GError **error) +static EDErrorCode +ed_journal_file_parse_fileheader(EDJournalFile *self, + EDJournalFilePrivate *p, + EDJournalEntry *e) +{ + + gchar const *version = ed_journal_entry_get_string( + e, "gameversion"); + + if (!S_EMPTY(version)) { + g_free(p->gameversion); + p->gameversion = g_strdup(version); + } + + return ed_error_success; +} + +static EDErrorCode +ed_journal_file_parse_commander(EDJournalFile *self, + EDJournalFilePrivate *p, + EDJournalEntry *e) +{ + gchar const *cmdr = ed_journal_entry_get_string( + e, "Name"); + + if (!S_EMPTY(cmdr)) { + g_free(p->commander); + p->commander = g_strdup(cmdr); + } + + return ed_error_success; +} + +static EDErrorCode +ed_journal_file_load_(EDJournalFile *self, + GError **error, + gboolean peek) { EDErrorCode ret = ed_error_internal; EDJournalFilePrivate *p = ed_journal_file_get_instance_private(self); @@ -265,7 +309,21 @@ static EDErrorCode ed_journal_file_load(EDJournalFile *self, continue; } - p->entries = g_list_append(p->entries, entry); + if (ed_journal_entry_is(entry, ED_JOURNAL_ENTRY_FILEHEADER)) { + ed_journal_file_parse_fileheader(self, p, entry); + } else if (ed_journal_entry_is(entry, ED_JOURNAL_ENTRY_COMMANDER)) { + ed_journal_file_parse_commander(self, p, entry); + + /* if we are just peeking, we stop here + */ + if (peek) { + break; + } + } + + if (!peek) { + p->entries = g_list_append(p->entries, entry); + } } ret = ed_error_success; @@ -285,12 +343,12 @@ EDErrorCode ed_journal_file_open(EDJournalFile *file, { EDErrorCode r = ed_error_success; - r = ed_journal_file_parse(file, filename); + r = ed_journal_file_parse_(file, filename); if (ED_ERROR(r)) { return r; } - r = ed_journal_file_load(file, error); + r = ed_journal_file_load_(file, error, TRUE); if (ED_ERROR(r)) { return r; } @@ -298,9 +356,29 @@ EDErrorCode ed_journal_file_open(EDJournalFile *file, return r; } +EDErrorCode ed_journal_file_load(EDJournalFile *self, GError **error) +{ + return_if_true(self == NULL, ed_error_args); + return ed_journal_file_load_(self, error, FALSE); +} + GDateTime *ed_journal_file_get_datetime(EDJournalFile *self) { return_if_true(self == NULL, NULL); EDJournalFilePrivate *p = ed_journal_file_get_instance_private(self); return p->timestamp; } + +gchar const *ed_journal_file_get_commander(EDJournalFile *self) +{ + return_if_true(self == NULL, NULL); + EDJournalFilePrivate *p = ed_journal_file_get_instance_private(self); + return p->commander; +} + +gchar const *ed_journal_file_get_gameversion(EDJournalFile *self) +{ + return_if_true(self == NULL, NULL); + EDJournalFilePrivate *p = ed_journal_file_get_instance_private(self); + return p->gameversion; +}