flipper_file_helper.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include "flipper_file_helper.h"
  2. const char* flipper_file_filetype_key = "Filetype";
  3. const char* flipper_file_version_key = "Version";
  4. const char flipper_file_delimiter = ':';
  5. const char flipper_file_comment = '#';
  6. #ifdef __linux__
  7. const char* flipper_file_scratchpad = ".scratch.pad";
  8. #else
  9. const char* flipper_file_scratchpad = "/any/.scratch.pad";
  10. #endif
  11. bool flipper_file_read_valid_key(File* file, string_t key) {
  12. string_reset(key);
  13. bool found = false;
  14. bool error = false;
  15. const uint8_t buffer_size = 32;
  16. uint8_t buffer[buffer_size];
  17. bool accumulate = true;
  18. bool new_line = true;
  19. while(true) {
  20. uint16_t bytes_were_read = storage_file_read(file, buffer, buffer_size);
  21. if(bytes_were_read == 0) break;
  22. for(uint16_t i = 0; i < bytes_were_read; i++) {
  23. if(buffer[i] == flipper_file_eoln) {
  24. // EOL found, clean data, start accumulating data and set the new_line flag
  25. string_reset(key);
  26. accumulate = true;
  27. new_line = true;
  28. } else if(buffer[i] == flipper_file_eolr) {
  29. // Ignore
  30. } else if(buffer[i] == flipper_file_comment && new_line) {
  31. // if there is a comment character and we are at the beginning of a new line
  32. // do not accumulate comment data and reset the new_line flag
  33. accumulate = false;
  34. new_line = false;
  35. } else if(buffer[i] == flipper_file_delimiter) {
  36. if(new_line) {
  37. // we are on a "new line" and found the delimiter
  38. // this can only be if we have previously found some kind of key, so
  39. // clear the data, set the flag that we no longer want to accumulate data
  40. // and reset the new_line flag
  41. string_reset(key);
  42. accumulate = false;
  43. new_line = false;
  44. } else {
  45. // parse the delimiter only if we are accumulating data
  46. if(accumulate) {
  47. // we found the delimiter, move the rw pointer to the correct location
  48. // and signal that we have found something
  49. if(!file_helper_seek(file, i - bytes_were_read)) {
  50. error = true;
  51. break;
  52. }
  53. found = true;
  54. break;
  55. }
  56. }
  57. } else {
  58. // just new symbol, reset the new_line flag
  59. new_line = false;
  60. if(accumulate) {
  61. // and accumulate data if we want
  62. string_push_back(key, buffer[i]);
  63. }
  64. }
  65. }
  66. if(found || error) break;
  67. }
  68. return found;
  69. }
  70. bool flipper_file_seek_to_key(File* file, const char* key) {
  71. bool found = false;
  72. string_t readed_key;
  73. string_init(readed_key);
  74. while(!storage_file_eof(file)) {
  75. if(flipper_file_read_valid_key(file, readed_key)) {
  76. if(string_cmp_str(readed_key, key) == 0) {
  77. if(!file_helper_seek(file, 2)) break;
  78. found = true;
  79. break;
  80. }
  81. }
  82. }
  83. string_clear(readed_key);
  84. return found;
  85. }
  86. bool flipper_file_write_key(File* file, const char* key) {
  87. bool result = false;
  88. do {
  89. result = file_helper_write(file, key, strlen(key));
  90. if(!result) break;
  91. const char delimiter_buffer[2] = {flipper_file_delimiter, ' '};
  92. result = file_helper_write(file, delimiter_buffer, sizeof(delimiter_buffer));
  93. } while(false);
  94. return result;
  95. }
  96. bool flipper_file_get_scratchpad_name(const char** name) {
  97. // TODO do not rewrite existing file
  98. *name = flipper_file_scratchpad;
  99. return true;
  100. }