[FL-2847] FFF trailing space fix (#1811)
* Improve whitespace handlilng in FFF * Add tests for odd fff user input * Adjust formatting Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									9bf11d9fd2
								
							
						
					
					
						commit
						61189c3c82
					
				| @ -57,6 +57,23 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n" | ||||
|                                    "Hex data: DE AD BE"; | ||||
| 
 | ||||
| #define READ_TEST_FLP "ff_flp.test" | ||||
| #define READ_TEST_ODD "ff_oddities.test" | ||||
| static const char* test_data_odd = "Filetype: Flipper File test\n" | ||||
|                                    // Tabs before newline
 | ||||
|                                    "Version: 666\t\t\n" | ||||
|                                    "# This is comment\n" | ||||
|                                    // Windows newline in a UNIX file
 | ||||
|                                    "String data: String\r\n" | ||||
|                                    // Trailing whitespace
 | ||||
|                                    "Int32 data: 1234 -6345 7813 0 \n" | ||||
|                                    // Extra whitespace
 | ||||
|                                    "Uint32 data:   1234  0   5678   9098  7654321  \n" | ||||
|                                    // Mixed whitespace
 | ||||
|                                    "Float data: 1.5\t \t1000.0\n" | ||||
|                                    // Leading tabs after key
 | ||||
|                                    "Bool data:\t\ttrue   false\n" | ||||
|                                    // Mixed trailing whitespace
 | ||||
|                                    "Hex data: DE AD BE\t    "; | ||||
| 
 | ||||
| // data created by user on linux machine
 | ||||
| static const char* test_file_linux = TEST_DIR READ_TEST_NIX; | ||||
| @ -64,6 +81,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX; | ||||
| static const char* test_file_windows = TEST_DIR READ_TEST_WIN; | ||||
| // data created by flipper itself
 | ||||
| static const char* test_file_flipper = TEST_DIR READ_TEST_FLP; | ||||
| // data containing odd user input
 | ||||
| static const char* test_file_oddities = TEST_DIR READ_TEST_ODD; | ||||
| 
 | ||||
| static bool storage_write_string(const char* path, const char* data) { | ||||
|     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||
| @ -503,6 +522,12 @@ MU_TEST(flipper_format_multikey_test) { | ||||
|     mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error"); | ||||
| } | ||||
| 
 | ||||
| MU_TEST(flipper_format_oddities_test) { | ||||
|     mu_assert( | ||||
|         storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]"); | ||||
|     mu_assert(test_read(test_file_linux), "Read test error [Oddities]"); | ||||
| } | ||||
| 
 | ||||
| MU_TEST_SUITE(flipper_format) { | ||||
|     tests_setup(); | ||||
|     MU_RUN_TEST(flipper_format_write_test); | ||||
| @ -516,6 +541,7 @@ MU_TEST_SUITE(flipper_format) { | ||||
|     MU_RUN_TEST(flipper_format_update_2_test); | ||||
|     MU_RUN_TEST(flipper_format_update_2_result_test); | ||||
|     MU_RUN_TEST(flipper_format_multikey_test); | ||||
|     MU_RUN_TEST(flipper_format_oddities_test); | ||||
|     tests_teardown(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -4,6 +4,10 @@ | ||||
| #include "flipper_format_stream.h" | ||||
| #include "flipper_format_stream_i.h" | ||||
| 
 | ||||
| static inline bool flipper_format_stream_is_space(char c) { | ||||
|     return c == ' ' || c == '\t' || c == flipper_format_eolr; | ||||
| } | ||||
| 
 | ||||
| static bool flipper_format_stream_write(Stream* stream, const void* data, size_t data_size) { | ||||
|     size_t bytes_written = stream_write(stream, data, data_size); | ||||
|     return bytes_written == data_size; | ||||
| @ -118,55 +122,64 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str | ||||
| } | ||||
| 
 | ||||
| static bool flipper_format_stream_read_value(Stream* stream, FuriString* value, bool* last) { | ||||
|     furi_string_reset(value); | ||||
|     enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace; | ||||
|     const size_t buffer_size = 32; | ||||
|     uint8_t buffer[buffer_size]; | ||||
|     bool result = false; | ||||
|     bool error = false; | ||||
| 
 | ||||
|     furi_string_reset(value); | ||||
| 
 | ||||
|     while(true) { | ||||
|         size_t was_read = stream_read(stream, buffer, buffer_size); | ||||
| 
 | ||||
|         if(was_read == 0) { | ||||
|             // check EOF
 | ||||
|             if(stream_eof(stream) && furi_string_size(value) > 0) { | ||||
|             if(state != LeadingSpace && stream_eof(stream)) { | ||||
|                 result = true; | ||||
|                 *last = true; | ||||
|                 break; | ||||
|             } else { | ||||
|                 error = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for(uint16_t i = 0; i < was_read; i++) { | ||||
|             uint8_t data = buffer[i]; | ||||
|             if(data == flipper_format_eoln) { | ||||
|                 if(furi_string_size(value) > 0) { | ||||
|                     if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { | ||||
|                         error = true; | ||||
|                         break; | ||||
|                     } | ||||
|             const uint8_t data = buffer[i]; | ||||
| 
 | ||||
|                     result = true; | ||||
|                     *last = true; | ||||
|             if(state == LeadingSpace) { | ||||
|                 if(flipper_format_stream_is_space(data)) { | ||||
|                     continue; | ||||
|                 } else if(data == flipper_format_eoln) { | ||||
|                     stream_seek(stream, i - was_read, StreamOffsetFromCurrent); | ||||
|                     error = true; | ||||
|                     break; | ||||
|                 } else { | ||||
|                     error = true; | ||||
|                     state = ReadValue; | ||||
|                     furi_string_push_back(value, data); | ||||
|                 } | ||||
|             } else if(data == ' ') { | ||||
|                 if(furi_string_size(value) > 0) { | ||||
|             } else if(state == ReadValue) { | ||||
|                 if(flipper_format_stream_is_space(data)) { | ||||
|                     state = TrailingSpace; | ||||
|                 } else if(data == flipper_format_eoln) { | ||||
|                     if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { | ||||
|                         error = true; | ||||
|                         break; | ||||
|                     } else { | ||||
|                         result = true; | ||||
|                         *last = true; | ||||
|                     } | ||||
| 
 | ||||
|                     result = true; | ||||
|                     *last = false; | ||||
|                     break; | ||||
|                 } else { | ||||
|                     furi_string_push_back(value, data); | ||||
|                 } | ||||
| 
 | ||||
|             } else if(data == flipper_format_eolr) { | ||||
|                 // Ignore
 | ||||
|             } else { | ||||
|                 furi_string_push_back(value, data); | ||||
|             } else if(state == TrailingSpace) { | ||||
|                 if(flipper_format_stream_is_space(data)) { | ||||
|                     continue; | ||||
|                 } else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { | ||||
|                     error = true; | ||||
|                 } else { | ||||
|                     *last = (data == flipper_format_eoln); | ||||
|                     result = true; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Georgii Surkov
						Georgii Surkov