2021-11-04 10:06:13 +00:00
|
|
|
#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) {
|
2021-11-15 17:09:40 +00:00
|
|
|
string_reset(str_result);
|
2021-11-04 10:06:13 +00:00
|
|
|
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) {
|
2021-11-15 17:09:40 +00:00
|
|
|
string_reset(value);
|
2021-11-04 10:06:13 +00:00
|
|
|
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;
|
|
|
|
}
|