mp_flipper_file_reader.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include <stdio.h>
  2. #include <furi.h>
  3. #include <storage/storage.h>
  4. #include <mp_flipper_runtime.h>
  5. #include <mp_flipper_file_reader.h>
  6. #include "mp_flipper_file_helper.h"
  7. typedef struct {
  8. size_t pointer;
  9. FuriString* content;
  10. size_t size;
  11. } FileReaderContext;
  12. inline void* mp_flipper_file_reader_context_alloc(const char* filename) {
  13. FuriString* path = furi_string_alloc_printf("%s", filename);
  14. Storage* storage = furi_record_open(RECORD_STORAGE);
  15. File* file = storage_file_alloc(storage);
  16. FileReaderContext* ctx = NULL;
  17. do {
  18. if(mp_flipper_try_resolve_filesystem_path(path) == MP_FLIPPER_IMPORT_STAT_NO_EXIST) {
  19. furi_string_free(path);
  20. mp_flipper_raise_os_error_with_filename(MP_ENOENT, filename);
  21. }
  22. if(!storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
  23. storage_file_free(file);
  24. mp_flipper_raise_os_error_with_filename(MP_ENOENT, filename);
  25. break;
  26. }
  27. ctx = malloc(sizeof(FileReaderContext));
  28. ctx->pointer = 0;
  29. ctx->content = furi_string_alloc();
  30. ctx->size = storage_file_size(file);
  31. char character = '\0';
  32. for(size_t i = 0; i < ctx->size; i++) {
  33. storage_file_read(file, &character, 1);
  34. furi_string_push_back(ctx->content, character);
  35. }
  36. } while(false);
  37. storage_file_free(file);
  38. furi_record_close(RECORD_STORAGE);
  39. furi_string_free(path);
  40. return ctx;
  41. }
  42. inline uint32_t mp_flipper_file_reader_read(void* data) {
  43. FileReaderContext* ctx = data;
  44. if(ctx->pointer >= ctx->size) {
  45. return MP_FLIPPER_FILE_READER_EOF;
  46. }
  47. return furi_string_get_char(ctx->content, ctx->pointer++);
  48. }
  49. void mp_flipper_file_reader_close(void* data) {
  50. FileReaderContext* ctx = data;
  51. furi_string_free(ctx->content);
  52. free(data);
  53. }