7#ifndef PRINTLINES_ALLOWED
8#define PRINTLINES_ALLOWED 0
11static const char *FNAME =
"kest_files.c";
13#define IO_BUFFER_SIZE 128
15#define write_byte(x) fputc(x, file);
16#define write_short(x) do { arg16 = x; fwrite(&arg16, 1, 2, file);} while(0)
17#define write_int32(x) do { arg32 = x; fwrite(&arg32, sizeof( int32_t), 1, file);} while(0)
18#define write_uint32(x) do {uarg32 = x; fwrite(&uarg32, sizeof(uint32_t), 1, file);} while(0)
19#define write_float(x) fwrite(&x, sizeof(float), 1, file);
20#define write_string(x) \
21 do {if (x) {for (int a = 0; x[a] != 0; a++) {fputc(x[a], file);}} fputc(0, file);} while (0)
23#define read_byte(x) x = fgetc(file);
24#define read_short(x) fread(&x, sizeof(uint16_t), 1, file);
25#define read_int32(x) fread(&x, sizeof(int32_t), 1, file);
26#define read_uint32(x) fread(&x, sizeof(uint32_t), 1, file);
27#define read_float(x) fread(&x, sizeof(float), 1, file);
28#define read_string() \
30 for (int i = 0; i < IO_BUFFER_SIZE; i++)\
32 string_read_buffer[i] = fgetc(file);\
33 if (!string_read_buffer[i])\
37#define read_and_strndup_string(x) \
39 for (int i = 0; i < IO_BUFFER_SIZE; i++)\
41 string_read_buffer[i] = fgetc(file);\
42 if (!string_read_buffer[i])\
45 x = kest_strndup(string_read_buffer, IO_BUFFER_SIZE);\
51 FILE *file = fopen(fname,
"rb");
62 while (fread(&
byte, 1, 1, file))
64 if (i % 8 == 1)
KEST_PRINTF(
"\n %s%d | ", (i < 10) ?
" " : ((i < 100) ?
" " :
""), i - 1);
82 if (
byte != magic_byte)
100 if (!fname || !profile)
106 FILE *file = fopen(fname,
"wb");
129 char *name = profile->
name ? profile->
name :
"Unnamed Profile";
134 kest_parameter_pll *current_param;
135 kest_setting_pll *current_setting;
139 while (current_effect)
141 current_effect = current_effect->next;
149 while (current_effect)
151 if (!current_effect->data || !current_effect->data->eff)
154 current_effect = current_effect->next;
161 current_param = current_effect->data->parameters;
163 while (current_param)
165 if (current_param->data)
168 current_param = current_param->next;
171 current_setting = current_effect->data->settings;
173 while (current_setting)
175 if (current_setting->data)
178 current_setting = current_setting->next;
181 current_effect = current_effect->next;
184 fseek(file, 1, SEEK_SET);
196 if (!sequence || !fname)
199 KEST_PRINTF(
"Saving sequence %s to sd card!\n", sequence->
name ?
"(unnamed)" : sequence->
name);
200 FILE *file = fopen(fname,
"wb");
212 char *name = sequence->
name ? sequence->
name :
"Unnamed Sequence";
218 uint16_t n_profiles = 0;
224 current = current->
next;
227 KEST_PRINTF(
"Sequence has %d profiles...\n", n_profiles);
244 current = current->
next;
247 fseek(file, 1, SEEK_SET);
260 if (!state || !fname)
264 FILE *file = fopen(fname,
"wb");
287 fseek(file, 1, SEEK_SET);
300 if (!state || !fname)
303 KEST_PRINTF(
"load state from file %s...\n", fname);
307 FILE *file = fopen(fname,
"rb");
323 fseek(file, 0, SEEK_END);
324 int file_size = ftell(file);
325 fseek(file, 0, SEEK_SET);
327 uint8_t *content =
kest_alloc(file_size *
sizeof(uint8_t));
332 fread(content, 1, file_size, file);
340 goto read_settings_exit;
348 goto read_settings_exit;
351 ptr = (
void*)&content[2];
359 KEST_PRINTF(
"Reading active profile fname from position %d\n", i);
363 while (content[i] && i - j < 31)
365 KEST_PRINTF(
"\t0x%02x = '%c'\n", content[i], content[i]);
381 while (content[i] && i - j < 31)
394 KEST_PRINTF(
"Reading current page identifier struct, starting at position %d\n", i);
398 i +=
sizeof(int32_t);
401 i +=
sizeof(int32_t);
403 KEST_PRINTF(
"Reading state->current_page.fname from position %d\n", i);
408 while (content[i] && i - j < 32)
410 KEST_PRINTF(
"\t0x%02x = '%c'\n", content[i], content[i]);
437 if (!fname || !profile)
445 FILE *file = fopen(fname,
"r");
464 kest_parameter_pll *current_param = NULL;
465 kest_setting_pll *current_setting = NULL;
472 KEST_PRINTF(
"Attempted load of profile from file \"%s\", whose first byte 0x%02x is not the profile magic byte 0x%02x\n",
475 goto profile_read_bail;
483 KEST_PRINTF(
"Attempted load of profile from file \"%s\", whose second byte 0x%02x indicates that its write was unfinished\n",
486 goto profile_read_bail;
493 KEST_PRINTF(
"Allocation fail allocating string of length %d for profile name from file %s\n", (
int)
byte, fname);
494 goto profile_read_bail;
497 profile->
name = name;
505 for (
int i = 0; i < n_effects; i++)
507 KEST_PRINTF(
"Profile professes to contain %d effects\n", n_effects);
515 KEST_PRINTF(
"Profile references non-existent effect. Aborting.\n");
517 goto profile_read_bail;
528 goto profile_read_bail;
539 while (current_param)
541 if (current_param->data)
544 current_param = current_param->next;
548 while (current_setting)
550 if (current_setting->data)
553 current_setting = current_setting->next;
567 profile->
fname[k] = 0;
571 profile->
fname[k] = fname[k];
593 if (!fname || !sequence)
600 FILE *file = fopen(fname,
"r");
604 KEST_PRINTF(
"Could not open file \"%s\"\n", fname);
615 char *profile_fname = NULL;
625 KEST_PRINTF(
"Attempted load of sequence from file \"%s\", whose first byte 0x%02x is not the sequence magic byte 0x%02x",
628 goto sequence_read_bail;
631 KEST_PRINTF(
"Attempted load of sequence from file \"%s\", whose second byte 0x%02x indicates that its write was unfinishedn",
634 goto sequence_read_bail;
641 KEST_PRINTF(
"Allocation fail allocating string of length %d for sequence name from file %s", (
int)
byte, fname);
642 goto sequence_read_bail;
645 sequence->
name = name;
653 for (
int i = 0; i < n_profiles; i++)
657 KEST_PRINTF(
"Sequence contains profile %s...\n", string_read_buffer);
666 KEST_PRINTF(
"Error: sequence %s contains profile %s, but no such profile found!\n", fname, string_read_buffer);
678 sequence->
fname[k] = 0;
682 sequence->
fname[k] = fname[k];
710 KEST_PRINTF(
"Failed to create profiles directory\n");
727 KEST_PRINTF(
"Failed to create sequences directory\n");
738int safe_file_write(
int (*write_func)(
void *arg,
const char *fname),
void *arg,
const char *fname)
744 FILE *target = fopen(fname,
"r");
745 char buf[strlen(fname) + 5];
753 sprintf(buf,
"%s.bak", fname);
756 FILE *bakfile = fopen(buf,
"r");
770 int ret_val = write_func(arg, fname);
789 FILE *target = fopen(fname,
"r");
790 char buf[strlen(fname) + 5];
798 sprintf(buf,
"%s.bak", fname);
801 FILE *bakfile = fopen(buf,
"r");
831#define FNAME_DIGITS 4
838 int plen = 0, slen = 0;
841 plen = strlen(prefix);
843 slen = strlen(suffix);
849 for (
int i = 0; i < plen; i++)
850 fname[index++] = prefix[i];
859 fname[index++] = (x < 10) ?
'0' + x :
'A' + (x - 10);
862 for (
int i = 0; i < slen; i++)
863 fname[index++] = (suffix[i] ==
'%') ?
'_' : suffix[i];
895 test = fopen(profile->
fname,
"r");
910 KEST_PRINTF(
"Sucessfully saved profile as %s. Dumping file...\n", profile->
fname);
933 test = fopen(sequence->
fname,
"r");
949 KEST_PRINTF(
"Sucessfully saved sequence as %s. Dumping file...\n", sequence->
fname);
983 kest_profile_pll *nl;
989 KEST_PRINTF(
"Loading profile %s...\n", current_file->data);
1000 nl = kest_profile_pll_append(cxt->
profiles, profile);
1016 current_file = current_file->next;
1034 kest_sequence_pll *nl;
1036 while (current_file)
1048 nl = kest_sequence_pll_append(cxt->
sequences, sequence);
1064 current_file = current_file->next;
1093 KEST_PRINTF(
"Attempting to load effect from file \"%s\"...\n", current->data);
1097 KEST_PRINTF(
"kest_read_eff_desc_from_file returned the pointer %p\n", eff);
1101 KEST_PRINTF(
"Obtained an effect descriptor by the name of \"%s\" ! Adding it to the list %p...\n",
1103 ret_val = kest_effect_desc_pll_safe_append(&cxt->
effects, eff);
1112 current = current->next;
1130 KEST_PRINTF(
"Generating list of files in %s\n", dir);
1134 DIR *directory = opendir(dir);
1142 struct dirent *directory_entry = readdir(directory);
1147 while (directory_entry)
1149 KEST_PRINTF(
"Directory entry: %s\n", directory_entry->d_name);
1150 if (directory_entry->d_type == DT_DIR)
1153 directory_entry = readdir(directory);
1161 KEST_PRINTF(
"Error: couldn't allocate string to list directory entry %s/%s", dir, directory_entry->d_name);
1165 sprintf(fname,
"%s%s", dir, directory_entry->d_name);
1167 nl = char_pll_append(list, fname);
1175 KEST_PRINTF(
"Error: couldn't append linked list to list directory entry %s/%s", dir, directory_entry->d_name);
1179 directory_entry = readdir(directory);
1196 DIR *directory = opendir(dir);
1204 struct dirent *directory_entry = readdir(directory);
1207 int bufsize = strlen(dir) + NAME_MAX + 1;
1213 while (directory_entry)
1215 KEST_PRINTF(
"Directory entry: %s\n", directory_entry->d_name);
1216 if (directory_entry->d_type == DT_DIR)
1219 snprintf(buf, bufsize,
"%s/%s", dir, directory_entry->d_name);
1231 snprintf(buf, bufsize,
"%s/%s", dir, directory_entry->d_name);
1236 directory_entry = readdir(directory);
1252 for (
int k = 0; a[k] && b[k]; k++)
void kest_free(void *ptr)
void * kest_alloc(size_t size)
kest_effect_desc * kest_cxt_get_effect_desc_from_cname(kest_context *cxt, const char *cname)
kest_profile * cxt_get_profile_by_fname(kest_context *cxt, const char *fname)
int kest_eff_parser_reset_mempool()
kest_effect_desc * kest_read_eff_desc_from_file(char *fname)
int kest_eff_parser_deinit_mempool()
const char * kest_error_code_to_string(int error_code)
#define ERR_UNFINISHED_WRITE
int save_sequence_as_file(kest_sequence *sequence, const char *fname)
#define read_and_strndup_string(x)
int file_validity_check(FILE *file, uint8_t magic_byte, uint8_t *byte_out)
int load_saved_sequences(kest_context *cxt)
int safe_file_write(int(*write_func)(void *arg, const char *fname), void *arg, const char *fname)
int load_state_from_file(kest_state *state, const char *fname)
int kest_init_directories()
void erase_sd_card_void_cb(void *data)
int fnames_agree(char *a, char *b)
int load_saved_profiles(kest_context *cxt)
void generate_filename(char *prefix, char *suffix, char *dest)
int save_profile(kest_profile *profile)
void dump_file_contents(char *fname)
int load_effects(kest_context *cxt)
int save_profile_as_file(kest_profile *profile, const char *fname)
int read_sequence_from_file(kest_sequence *sequence, const char *fname)
int save_state_to_file(kest_state *state, const char *fname)
int read_profile_from_file(kest_profile *profile, const char *fname)
string_ll * list_files_in_directory(char *dir)
int save_sequence(kest_sequence *sequence)
int save_profile_as_file_safe(kest_profile *profile, const char *fname)
int erase_folder(const char *dir)
#define KEST_WRITE_UNFINISHED_BYTE
#define SEQUENCE_EXTENSION
#define KEST_PROFILES_DIR
#define KEST_SEQUENCE_MAGIC_BYTE
#define KEST_PROFILE_MAGIC_BYTE
#define KEST_EFFECT_DESC_DIR
#define KEST_PROFILE_BROKEN_TRANSFORMER
#define KEST_WRITE_FINISHED_BYTE
#define KEST_STATE_MAGIC_BYTE
#define KEST_SEQUENCES_DIR
#define MAIN_SEQUENCE_FNAME
#define PROFILE_EXTENSION
#define KEST_FILENAME_LEN
int init_m_profile(kest_profile *profile)
void free_profile(kest_profile *profile)
kest_effect * kest_profile_append_effect_eff(kest_profile *profile, kest_effect_desc *eff)
kest_ui_page * create_profile_view_for(kest_profile *profile)
int init_m_sequence(kest_sequence *sequence)
void free_sequence(kest_sequence *sequence)
int sequence_append_profile(kest_sequence *sequence, kest_profile *profile)
int create_sequence_view_for(kest_sequence *sequence)
int char_is_letter(char c)
kest_sequence main_sequence
kest_effect_desc_pll * effects
kest_setting_pll * settings
kest_parameter_pll * parameters
kest_effect_pll * effects
char fname[KEST_FILENAME_LEN]
char fname[KEST_FILENAME_LEN]
seq_profile_ll * profiles
kest_page_identifier current_page
char active_profile_fname[32]
char active_sequence_fname[32]
struct seq_profile_ll * next