flipperzero-firmware/lib/flipper_file/file_helper.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_reset(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_reset(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;
}