Garmin: refactor the code to prepare for MTP support
Breaking things into helper function makes it much easier to then support both regular file operations and MTP. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
9de9efcae0
commit
c7f67509d4
107
src/garmin.c
107
src/garmin.c
@ -124,52 +124,73 @@ static int name_cmp(const void *a, const void *b)
|
|||||||
*
|
*
|
||||||
* Return number of files found.
|
* Return number of files found.
|
||||||
*/
|
*/
|
||||||
static int get_file_list(dc_device_t *abstract, DIR *dir, struct file_list *files)
|
|
||||||
|
static int
|
||||||
|
check_filename(dc_device_t *abstract, const char *name)
|
||||||
|
{
|
||||||
|
int len = strlen(name);
|
||||||
|
const char *explain = NULL;
|
||||||
|
|
||||||
|
DEBUG (abstract->context, " %s", name);
|
||||||
|
|
||||||
|
if (len < 5)
|
||||||
|
explain = "name too short";
|
||||||
|
if (len >= FIT_NAME_SIZE)
|
||||||
|
explain = "name too long";
|
||||||
|
if (strncasecmp(name + len - 4, ".FIT", 4))
|
||||||
|
explain = "name lacks FIT suffix";
|
||||||
|
|
||||||
|
DEBUG (abstract->context, " %s - %s", name, explain ? explain : "adding to list");
|
||||||
|
return explain == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
make_space(struct file_list *files)
|
||||||
|
{
|
||||||
|
if (files->nr == files->allocated) {
|
||||||
|
struct fit_name *array;
|
||||||
|
int n = 3*(files->allocated + 8)/2;
|
||||||
|
size_t new_size;
|
||||||
|
|
||||||
|
new_size = n * sizeof(array[0]);
|
||||||
|
array = realloc(files->array, new_size);
|
||||||
|
if (!array)
|
||||||
|
return DC_STATUS_NOMEMORY;
|
||||||
|
|
||||||
|
files->array = array;
|
||||||
|
files->allocated = n;
|
||||||
|
}
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_name(struct file_list *files, const char *name)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* NOTE! This depends on the zero-padding that strncpy does.
|
||||||
|
*
|
||||||
|
* strncpy() doesn't just limit the size of the copy, it
|
||||||
|
* will zero-pad the end of the result buffer.
|
||||||
|
*/
|
||||||
|
struct fit_name *entry = files->array + files->nr++;
|
||||||
|
strncpy(entry->name, name, FIT_NAME_SIZE);
|
||||||
|
entry->name[FIT_NAME_SIZE] = 0; // ensure it's null-terminated
|
||||||
|
}
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
get_file_list(dc_device_t *abstract, DIR *dir, struct file_list *files)
|
||||||
{
|
{
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
|
|
||||||
DEBUG (abstract->context, "Iterating over Garmin files");
|
DEBUG (abstract->context, "Iterating over Garmin files");
|
||||||
while ((de = readdir(dir)) != NULL) {
|
while ((de = readdir(dir)) != NULL) {
|
||||||
int len = strlen(de->d_name);
|
if (!check_filename(abstract, de->d_name))
|
||||||
struct fit_name *entry;
|
|
||||||
const char *explain = NULL;
|
|
||||||
|
|
||||||
DEBUG (abstract->context, " %s", de->d_name);
|
|
||||||
|
|
||||||
if (len < 5)
|
|
||||||
explain = "name too short";
|
|
||||||
if (len >= FIT_NAME_SIZE)
|
|
||||||
explain = "name too long";
|
|
||||||
if (strncasecmp(de->d_name + len - 4, ".FIT", 4))
|
|
||||||
explain = "name lacks FIT suffix";
|
|
||||||
|
|
||||||
DEBUG (abstract->context, " %s - %s", de->d_name, explain ? explain : "adding to list");
|
|
||||||
if (explain)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (files->nr == files->allocated) {
|
dc_status_t rc = make_space(files);
|
||||||
struct fit_name *array;
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
int n = 3*(files->allocated + 8)/2;
|
return rc;
|
||||||
size_t new_size;
|
add_name(files, de->d_name);
|
||||||
|
|
||||||
new_size = n * sizeof(array[0]);
|
|
||||||
array = realloc(files->array, new_size);
|
|
||||||
if (!array)
|
|
||||||
return DC_STATUS_NOMEMORY;
|
|
||||||
|
|
||||||
files->array = array;
|
|
||||||
files->allocated = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE! This depends on the zero-padding that strncpy does.
|
|
||||||
*
|
|
||||||
* strncpy() doesn't just limit the size of the copy, it
|
|
||||||
* will zero-pad the end of the result buffer.
|
|
||||||
*/
|
|
||||||
entry = files->array + files->nr++;
|
|
||||||
strncpy(entry->name, de->d_name, FIT_NAME_SIZE);
|
|
||||||
entry->name[FIT_NAME_SIZE] = 0; // ensure it's null-terminated
|
|
||||||
}
|
}
|
||||||
DEBUG (abstract->context, "Found %d files", files->nr);
|
DEBUG (abstract->context, "Found %d files", files->nr);
|
||||||
|
|
||||||
@ -221,10 +242,14 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
|
|||||||
dc_parser_t *parser;
|
dc_parser_t *parser;
|
||||||
char pathname[PATH_MAX];
|
char pathname[PATH_MAX];
|
||||||
size_t pathlen;
|
size_t pathlen;
|
||||||
struct file_list files = { 0, 0, NULL };
|
struct file_list files = {
|
||||||
|
0, // nr
|
||||||
|
0, // allocated
|
||||||
|
NULL, // array of names
|
||||||
|
};
|
||||||
dc_buffer_t *file;
|
dc_buffer_t *file;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int rc;
|
dc_status_t rc;
|
||||||
|
|
||||||
// Read the directory name from the iostream
|
// Read the directory name from the iostream
|
||||||
rc = dc_iostream_read(device->iostream, &pathname, sizeof(pathname)-1, &pathlen);
|
rc = dc_iostream_read(device->iostream, &pathname, sizeof(pathname)-1, &pathlen);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user