 7f94ef3179
			
		
	
	
		7f94ef3179
		
			
		
	
	
	
	
		
			
			* Flipper file format: remove C wrapper * Flipper file format: open append, float, uint32_t as array, delete key, value count * Flipper file format: fix scratchpad location * Flipper file format: add EOL on append * SubGHZ keystore: update encryption type read and write * Flipper File Format: enhanced version * Flipper File Format: fix naming * Flipper File Format: fix "open" subset naming * Flipper File Format: tests * Flipper File Format: file helper naming * SubGHZ keystore: merge with current state of flipper file format * Flipper File Format: update make recipe * Flipper File Format: open new file method
		
			
				
	
	
		
			204 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "file_helper.h"
 | |
| 
 | |
| const char flipper_file_eoln = '\n';
 | |
| const char flipper_file_eolr = '\r';
 | |
| 
 | |
| bool file_helper_seek(File* file, int32_t offset) {
 | |
|     uint64_t position = storage_file_tell(file);
 | |
|     return storage_file_seek(file, position + offset, true);
 | |
| }
 | |
| 
 | |
| bool file_helper_write_hex(File* file, const uint8_t* data, const uint16_t data_size) {
 | |
|     const uint8_t byte_text_size = 3;
 | |
|     char byte_text[byte_text_size];
 | |
| 
 | |
|     bool result = true;
 | |
|     uint16_t bytes_written;
 | |
|     for(uint8_t i = 0; i < data_size; i++) {
 | |
|         snprintf(byte_text, byte_text_size, "%02X", data[i]);
 | |
| 
 | |
|         if(i != 0) {
 | |
|             // space
 | |
|             const char space = ' ';
 | |
|             bytes_written = storage_file_write(file, &space, sizeof(char));
 | |
|             if(bytes_written != sizeof(char)) {
 | |
|                 result = false;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         bytes_written = storage_file_write(file, &byte_text, strlen(byte_text));
 | |
|         if(bytes_written != strlen(byte_text)) {
 | |
|             result = false;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| bool file_helper_read_line(File* file, string_t str_result) {
 | |
|     string_clean(str_result);
 | |
|     const uint8_t buffer_size = 32;
 | |
|     uint8_t buffer[buffer_size];
 | |
| 
 | |
|     do {
 | |
|         uint16_t bytes_were_read = storage_file_read(file, buffer, buffer_size);
 | |
|         // TODO process EOF
 | |
|         if(bytes_were_read == 0) break;
 | |
| 
 | |
|         bool result = false;
 | |
|         bool error = false;
 | |
|         for(uint16_t i = 0; i < bytes_were_read; i++) {
 | |
|             if(buffer[i] == flipper_file_eoln) {
 | |
|                 if(!file_helper_seek(file, i - bytes_were_read)) {
 | |
|                     error = true;
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 result = true;
 | |
|                 break;
 | |
|             } else if(buffer[i] == flipper_file_eolr) {
 | |
|                 // Ignore
 | |
|             } else {
 | |
|                 string_push_back(str_result, buffer[i]);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if(result || error) {
 | |
|             break;
 | |
|         }
 | |
|     } while(true);
 | |
| 
 | |
|     return string_size(str_result) != 0;
 | |
| }
 | |
| 
 | |
| bool file_helper_seek_to_next_line(File* file) {
 | |
|     const uint8_t buffer_size = 32;
 | |
|     uint8_t buffer[buffer_size];
 | |
|     bool result = false;
 | |
|     bool error = false;
 | |
| 
 | |
|     do {
 | |
|         uint16_t bytes_were_read = storage_file_read(file, buffer, buffer_size);
 | |
|         if(bytes_were_read == 0) {
 | |
|             if(storage_file_eof(file)) {
 | |
|                 result = true;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         for(uint16_t i = 0; i < bytes_were_read; i++) {
 | |
|             if(buffer[i] == flipper_file_eoln) {
 | |
|                 if(!file_helper_seek(file, i - bytes_were_read)) {
 | |
|                     error = true;
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 result = true;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if(result || error) {
 | |
|             break;
 | |
|         }
 | |
|     } while(true);
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| bool file_helper_read_value(File* file, string_t value, bool* last) {
 | |
|     string_clean(value);
 | |
|     const uint8_t buffer_size = 32;
 | |
|     uint8_t buffer[buffer_size];
 | |
|     bool result = false;
 | |
|     bool error = false;
 | |
| 
 | |
|     while(true) {
 | |
|         uint16_t bytes_were_read = storage_file_read(file, buffer, buffer_size);
 | |
| 
 | |
|         if(bytes_were_read == 0) {
 | |
|             // check EOF
 | |
|             if(storage_file_eof(file) && string_size(value) > 0) {
 | |
|                 result = true;
 | |
|                 *last = true;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         for(uint16_t i = 0; i < bytes_were_read; i++) {
 | |
|             if(buffer[i] == flipper_file_eoln) {
 | |
|                 if(string_size(value) > 0) {
 | |
|                     if(!file_helper_seek(file, i - bytes_were_read)) {
 | |
|                         error = true;
 | |
|                         break;
 | |
|                     }
 | |
| 
 | |
|                     result = true;
 | |
|                     *last = true;
 | |
|                     break;
 | |
|                 } else {
 | |
|                     error = true;
 | |
|                 }
 | |
|             } else if(buffer[i] == ' ') {
 | |
|                 if(string_size(value) > 0) {
 | |
|                     if(!file_helper_seek(file, i - bytes_were_read)) {
 | |
|                         error = true;
 | |
|                         break;
 | |
|                     }
 | |
| 
 | |
|                     result = true;
 | |
|                     *last = false;
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|             } else if(buffer[i] == flipper_file_eolr) {
 | |
|                 // Ignore
 | |
|             } else {
 | |
|                 string_push_back(value, buffer[i]);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if(error || result) break;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| bool file_helper_write(File* file, const void* data, uint16_t data_size) {
 | |
|     uint16_t bytes_written = storage_file_write(file, data, data_size);
 | |
|     return bytes_written == data_size;
 | |
| }
 | |
| 
 | |
| bool file_helper_write_eol(File* file) {
 | |
|     return file_helper_write(file, &flipper_file_eoln, sizeof(char));
 | |
| }
 | |
| 
 | |
| bool file_helper_copy(File* file_from, File* file_to, uint64_t start_offset, uint64_t stop_offset) {
 | |
|     bool result = false;
 | |
| 
 | |
|     const uint8_t buffer_size = 32;
 | |
|     uint8_t buffer[buffer_size];
 | |
|     uint64_t current_offset = start_offset;
 | |
| 
 | |
|     if(storage_file_seek(file_from, start_offset, true)) {
 | |
|         do {
 | |
|             int32_t bytes_count = MIN(buffer_size, stop_offset - current_offset);
 | |
|             if(bytes_count <= 0) {
 | |
|                 result = true;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             uint16_t bytes_were_read = storage_file_read(file_from, buffer, bytes_count);
 | |
|             if(bytes_were_read != bytes_count) break;
 | |
| 
 | |
|             uint16_t bytes_were_written = storage_file_write(file_to, buffer, bytes_count);
 | |
|             if(bytes_were_written != bytes_count) break;
 | |
| 
 | |
|             current_offset += bytes_count;
 | |
|         } while(true);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| } |