kb_layout_provider.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "kb_layout_provider.h"
  2. #include <storage/storage.h>
  3. #include <toolbox/stream/stream.h>
  4. #include <toolbox/stream/file_stream.h>
  5. #define KB_LAYOUTS_FILE EXT_PATH("apps_assets/totp/kb_layouts.klx")
  6. bool totp_kb_layout_provider_get_layout_data(AutomationKeyboardLayout kb_layout, uint16_t* buffer) {
  7. Storage* storage = furi_record_open(RECORD_STORAGE);
  8. Stream* stream = file_stream_alloc(storage);
  9. bool result = false;
  10. do {
  11. if(!file_stream_open(stream, KB_LAYOUTS_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) {
  12. break;
  13. }
  14. if(!stream_seek(
  15. stream,
  16. sizeof(uint8_t) + kb_layout * (TOTP_KB_LAYOUT_NAME_MAX_LENGTH + sizeof(uint16_t)) +
  17. TOTP_KB_LAYOUT_NAME_MAX_LENGTH,
  18. StreamOffsetFromStart)) {
  19. break;
  20. }
  21. uint16_t offset;
  22. if(stream_read(stream, (uint8_t*)&offset, sizeof(uint16_t)) != sizeof(uint16_t)) {
  23. break;
  24. }
  25. if(!stream_seek(stream, offset, StreamOffsetFromStart)) {
  26. break;
  27. }
  28. size_t bytes_to_read = TOTP_KB_LAYOUT_DATA_LENGTH * sizeof(uint16_t);
  29. if(stream_read(stream, (uint8_t*)buffer, bytes_to_read) != bytes_to_read) {
  30. break;
  31. }
  32. result = true;
  33. } while(false);
  34. file_stream_close(stream);
  35. stream_free(stream);
  36. furi_record_close(RECORD_STORAGE);
  37. return result;
  38. }
  39. uint8_t totp_kb_layout_provider_get_layouts_count() {
  40. Storage* storage = furi_record_open(RECORD_STORAGE);
  41. Stream* stream = file_stream_alloc(storage);
  42. uint8_t result = 0;
  43. do {
  44. if(!file_stream_open(stream, KB_LAYOUTS_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) {
  45. break;
  46. }
  47. if(!stream_rewind(stream)) {
  48. break;
  49. }
  50. if(stream_read(stream, &result, 1) != 1) {
  51. break;
  52. }
  53. } while(false);
  54. file_stream_close(stream);
  55. stream_free(stream);
  56. furi_record_close(RECORD_STORAGE);
  57. return result;
  58. }
  59. bool totp_kb_layout_provider_get_layout_name(
  60. AutomationKeyboardLayout kb_layout,
  61. char* buffer,
  62. size_t buffer_length) {
  63. Storage* storage = furi_record_open(RECORD_STORAGE);
  64. Stream* stream = file_stream_alloc(storage);
  65. bool result = false;
  66. do {
  67. if(!file_stream_open(stream, KB_LAYOUTS_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) {
  68. break;
  69. }
  70. if(!stream_seek(
  71. stream,
  72. sizeof(uint8_t) + kb_layout * (TOTP_KB_LAYOUT_NAME_MAX_LENGTH + sizeof(uint16_t)),
  73. StreamOffsetFromStart)) {
  74. break;
  75. }
  76. size_t bytes_to_read = M_MIN(TOTP_KB_LAYOUT_NAME_MAX_LENGTH, buffer_length);
  77. if(stream_read(stream, (uint8_t*)buffer, bytes_to_read) != bytes_to_read) {
  78. break;
  79. }
  80. buffer[buffer_length - 1] = '\0';
  81. result = true;
  82. } while(false);
  83. file_stream_close(stream);
  84. stream_free(stream);
  85. furi_record_close(RECORD_STORAGE);
  86. return result;
  87. }
  88. bool totp_kb_layout_provider_get_layout_by_name(
  89. const char* name,
  90. AutomationKeyboardLayout* kb_layout) {
  91. Storage* storage = furi_record_open(RECORD_STORAGE);
  92. Stream* stream = file_stream_alloc(storage);
  93. uint8_t count = 0;
  94. bool found = false;
  95. do {
  96. if(!file_stream_open(stream, KB_LAYOUTS_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) {
  97. break;
  98. }
  99. if(!stream_rewind(stream)) {
  100. break;
  101. }
  102. if(stream_read(stream, &count, 1) != 1) {
  103. break;
  104. }
  105. char current_name[TOTP_KB_LAYOUT_NAME_MAX_LENGTH + 1];
  106. for(AutomationKeyboardLayout i = 0; i < count; i++) {
  107. if(stream_read(stream, (uint8_t*)&current_name[0], TOTP_KB_LAYOUT_NAME_MAX_LENGTH) !=
  108. TOTP_KB_LAYOUT_NAME_MAX_LENGTH) {
  109. break;
  110. }
  111. current_name[TOTP_KB_LAYOUT_NAME_MAX_LENGTH] = '\0';
  112. if(strncasecmp(name, &current_name[0], TOTP_KB_LAYOUT_NAME_MAX_LENGTH) == 0) {
  113. found = true;
  114. *kb_layout = i;
  115. break;
  116. }
  117. if(!stream_seek(stream, sizeof(uint16_t), StreamOffsetFromCurrent)) {
  118. break;
  119. }
  120. }
  121. } while(false);
  122. file_stream_close(stream);
  123. stream_free(stream);
  124. furi_record_close(RECORD_STORAGE);
  125. return found;
  126. }