From d4d373de28e94e78e44a4f849dbae4d70f48eef9 Mon Sep 17 00:00:00 2001 From: dam Date: Fri, 17 Feb 2023 16:52:35 +0000 Subject: Prototypes for store and load database. --- ttt.jai | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 176 insertions(+), 11 deletions(-) diff --git a/ttt.jai b/ttt.jai index 1eaf8e1..585d7af 100644 --- a/ttt.jai +++ b/ttt.jai @@ -32,7 +32,7 @@ TASK_NAME_BYTES :: #run TASK_NAME_LENGTH+1; // TODO Get rid of this! FIRST_DAY_OF_WEEK :: 1; // (0-6, Sunday = 0). NUM_WEEK_DAYS :: 7; // Just to be more clear about what we're looping about. -APP_FOLDER_NAME :: ".task_time_tracker"; +APP_FOLDER_NAME :: ".task_time_tracker_v2"; // TODO Using _v2 to avoid erasing my work data. DB_FILE_NAME :: "database.bin"; AR_FILE_NAME :: "archive.csv"; @@ -43,22 +43,26 @@ SECONDS_IN_DAY :: cast(s64)24*SECONDS_IN_HOUR; SECONDS_IN_YEAR :: cast(s64)365*SECONDS_IN_DAY; MAX_DATABASE_TASKS :: S64_MAX; -Task :: struct { +OldTask :: struct { times : [NUM_WEEK_DAYS] s64; name : [TASK_NAME_BYTES] u8; // TODO Start using strings. } +Task :: struct { + times : [NUM_WEEK_DAYS] s64; + name : string~s8; + name_data : [62]u8; + name.data = cast(*~s8 u8) (0x80 ^ 0x01); // *name_data[0]; +} + Database :: struct { active_task : *~s64 Task = null; selected_task : *~s64 Task = null; - tasks : [..] Task; modified_on : s64; total_times : [NUM_WEEK_DAYS] s64; -// size_t count; // Will always be equal or less than capacity. TODO Will this be necessary? + tasks : [..] Task; } - - // const char DB_FILE_SIGN[] = DB_FILE_SIGN_STR; // const size_t DB_FILE_SIGN_LENGTH = sizeof(DB_FILE_SIGN_STR)-1; // const size_t SIZEOF_TASK_ST = sizeof(task_st); @@ -1226,13 +1230,174 @@ main :: () { app_directory = join(home_path, "/", APP_FOLDER_NAME); db_file_path = join(app_directory, "/", DB_FILE_NAME); ar_file_path = join(app_directory, "/", AR_FILE_NAME); + } + + + { // Load database prototype + +/* +typedef struct { + task_st *tasks; + size_t count; // Will always be equal or less than capacity. + size_t capacity; // Will always be equal or less than PTRDIFF_MAX (see MAX_DATABASE_TASKS). + ptrdiff_t active_task; // Will always be less than capacity/count. + ptrdiff_t selected_task; // Will always be less than capacity/count. + int64_t modified_on; + int64_t total_times[NUM_WEEK_DAYS]; +} database_st; +*/ +/* +Database :: struct { + active_task : *~s64 Task = null; + selected_task : *~s64 Task = null; + modified_on : s64; + total_times : [NUM_WEEK_DAYS] s64; + tasks : [..] Task; +} +*/ + + db : Database; + + // I'm having some troubles with the relative pointers: + // - array_add uses = to copy the pointers and I lose their values. + // - when printing the database after loading from file I'm getting a segmentation fault. + // also... the array_add + // TODO WIP + + //load_database(*db, db_file_path); + + task : Task; + memcpy(task.name.data, "bazinga".data, 7); + task.name.count = 7; + print(">>>'%'\n", task.name); + print("###%\n\n", task); + + add_task(*db, *task); + store_database(db, db_file_path); + + //array_add(*db.tasks, task); + //memcpy(*db.tasks[0], *task, size_of(Task)); + + //print("www\n"); + print("loaded: %\n", db); + + + + add_task :: (db: *Database, task: *Task) { + idx := db.tasks.count; + maybe_grow(*db.tasks); + db.tasks.count += 1; + memcpy(*db.tasks[idx], task, size_of(Task)); + } + - // TODO DEBUG - print_owner_allocator("home_path", home_path.data); - print_owner_allocator("app_directory", app_directory.data); - print_owner_allocator("db_file_path", db_file_path.data); - print_owner_allocator("ar_file_path", ar_file_path.data); + // Stores data from database into binary file. + // Returns success. + store_database :: (db: Database, path: string) -> success: bool { + //assert(db != null, "Parameter 'db' is null."); + assert(xx path, "Parameter 'path' is empty."); + + // Open file. + file, open_success := file_open(path, for_writing = true); // log_errors: bool = true + if open_success == false { + print_error("Failed to open file '%' while storing database: ERROR_FROM_LOG", path); // TODO Get error from logger ?! + return false; + } + + file_write(*file, DB_FILE_SIGN_STR); + file_write(*file, *db, size_of(Database)); + //fwrite(DB_FILE_SIGN, SIZEOF_CHAR, DB_FILE_SIGN_LENGTH, file); + //fwrite(db, SIZEOF_DATABASE_ST, 1, file); + //fwrite(db->tasks, SIZEOF_TASK_ST, db->count, file); + + file_close(*file); + return true; + } + + // Loads data from binary file into database. + // Returns success. + load_database :: (db: *Database, path: string) -> success: bool { + assert(db != null, "Parameter 'db' is null."); + assert(xx path, "Parameter 'path' is empty."); + + // Open file. + file, open_success := file_open(path); // log_errors: bool = true + if open_success == false { + print_error("Failed to open file '%' while loading database: ERROR_FROM_LOG", path); // TODO Get error from logger ?! + return false; + } + + // Validate file signature. + file_signature: [DB_FILE_SIGN_STR.count] u8; + read_success := file_read(file, *file_signature, DB_FILE_SIGN_STR.count); + if read_success == false print_error("Failed to read file signature from '%'.", path); + if cast(string)file_signature != DB_FILE_SIGN_STR { + print_error("Invalid file signature."); + file_close(*file); + return false; + } + + // Read database structure. + + read_success = file_read(file, db, size_of(Database)); + //if read_success == false print_error("Failed to read database info from '%'.", path); + + + //file_open :: (name: string, for_writing := false, keep_existing_content := false, log_errors := true) -> File, bool + //file_read :: (f: File, vdata: *void, bytes_to_read: s64) -> (success: bool, total_read: s64) + + return true; + } + + // Loads data from binary file into database. + // Returns success. + /* + load_database :: ( + + + bool load_database(database_st *db, const char *path) { + assert(db != NULL); + assert(path != NULL); + + // Open file. + FILE *file = fopen(path, "rb"); + if (file == NULL) { + print_error("Failed to open file '%s' while loading database: %s.", path, strerror(errno)); + return false; + } + + // Validate file signature. + char file_signature[DB_FILE_SIGN_LENGTH]; + fread(&file_signature, SIZEOF_CHAR, DB_FILE_SIGN_LENGTH, file); + if (strncmp(file_signature, DB_FILE_SIGN, DB_FILE_SIGN_LENGTH) != 0) { + print_error("Invalid file signature."); + fclose(file); + return false; + } + + // Read database structure. + fread(db, SIZEOF_DATABASE_ST, 1, file); + + // Reserve database capacity for tasks. + size_t capacity_bytes = db->capacity * SIZEOF_TASK_ST; + db->tasks = malloc(capacity_bytes); + if (db->tasks == NULL && capacity_bytes > 0) { + print_error("Failed to allocate memory while loading database: %s.", strerror(errno)); + return false; + } + + // Read database tasks. + fread(db->tasks, SIZEOF_TASK_ST, db->count, file); + + // Make sure we are reading all the file. + assert(fgetc(file) == EOF); + + fclose(file); + return true; + } + */ } + return; // TODO DEBUG /* -- cgit v1.2.3