forked from len0rd/rockbox
Implement fast_readline as a function and use it for tagtree also.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11301 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
593b552486
commit
a1ac743453
4 changed files with 199 additions and 175 deletions
47
apps/misc.c
47
apps/misc.c
|
@ -217,6 +217,53 @@ int read_line(int fd, char* buffer, int buffer_size)
|
||||||
return errno ? -1 : num_read;
|
return errno ? -1 : num_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Performance optimized version of the previous function. */
|
||||||
|
int fast_readline(int fd, char *buf, int buf_size, void *parameters,
|
||||||
|
int (*callback)(int n, const char *buf, void *parameters))
|
||||||
|
{
|
||||||
|
char *p, *next;
|
||||||
|
int rc, pos = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
next = NULL;
|
||||||
|
|
||||||
|
rc = read(fd, &buf[pos], buf_size - pos - 1);
|
||||||
|
if (rc >= 0)
|
||||||
|
buf[pos+rc] = '\0';
|
||||||
|
|
||||||
|
if ( (p = strchr(buf, '\r')) != NULL)
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
next = ++p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
if ( (p = strchr(p, '\n')) != NULL)
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
next = ++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = callback(count, buf, parameters);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
pos = buf_size - ((long)next - (long)buf) - 1;
|
||||||
|
memmove(buf, next, pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
|
||||||
#if LCD_DEPTH == 16
|
#if LCD_DEPTH == 16
|
||||||
|
|
|
@ -42,6 +42,8 @@ char *create_datetime_filename(char *buffer, const char *path,
|
||||||
* stored in buffer.
|
* stored in buffer.
|
||||||
*/
|
*/
|
||||||
int read_line(int fd, char* buffer, int buffer_size);
|
int read_line(int fd, char* buffer, int buffer_size);
|
||||||
|
int fast_readline(int fd, char *buf, int buf_size, void *parameters,
|
||||||
|
int (*callback)(int n, const char *buf, void *parameters));
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
/* Save a .BMP file containing the current screen contents. */
|
/* Save a .BMP file containing the current screen contents. */
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
#include "atoi.h"
|
#include "atoi.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
#include "eeprom_settings.h"
|
#include "eeprom_settings.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
/* Tag Cache thread. */
|
/* Tag Cache thread. */
|
||||||
static struct event_queue tagcache_queue;
|
static struct event_queue tagcache_queue;
|
||||||
|
@ -2687,40 +2688,42 @@ static bool read_tag(char *dest, long size,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_changelog_line(int masterfd, const char *buf)
|
static int parse_changelog_line(int line_n, const char *buf, void *parameters)
|
||||||
{
|
{
|
||||||
struct index_entry idx;
|
struct index_entry idx;
|
||||||
char tag_data[MAX_PATH];
|
char tag_data[MAX_PATH];
|
||||||
int idx_id;
|
int idx_id;
|
||||||
|
int masterfd = (int)parameters;
|
||||||
const int import_tags[] = { tag_playcount, tag_playtime, tag_lastplayed };
|
const int import_tags[] = { tag_playcount, tag_playtime, tag_lastplayed };
|
||||||
int i;
|
int i;
|
||||||
|
(void)line_n;
|
||||||
|
|
||||||
if (*buf == '#')
|
if (*buf == '#')
|
||||||
return true;
|
return 0;
|
||||||
|
|
||||||
if (!read_tag(tag_data, sizeof tag_data, buf, "filename"))
|
if (!read_tag(tag_data, sizeof tag_data, buf, "filename"))
|
||||||
{
|
{
|
||||||
logf("filename missing");
|
logf("filename missing");
|
||||||
logf("-> %s", buf);
|
logf("-> %s", buf);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx_id = find_index(tag_data);
|
idx_id = find_index(tag_data);
|
||||||
if (idx_id < 0)
|
if (idx_id < 0)
|
||||||
{
|
{
|
||||||
logf("entry not found");
|
logf("entry not found");
|
||||||
return false;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_index(masterfd, idx_id, &idx, false))
|
if (!get_index(masterfd, idx_id, &idx, false))
|
||||||
{
|
{
|
||||||
logf("failed to retrieve index entry");
|
logf("failed to retrieve index entry");
|
||||||
return false;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop if tag has already been modified. */
|
/* Stop if tag has already been modified. */
|
||||||
if (idx.flag & FLAG_DIRTYNUM)
|
if (idx.flag & FLAG_DIRTYNUM)
|
||||||
return false;
|
return -4;
|
||||||
|
|
||||||
logf("import: %s", tag_data);
|
logf("import: %s", tag_data);
|
||||||
|
|
||||||
|
@ -2745,7 +2748,7 @@ static bool parse_changelog_line(int masterfd, const char *buf)
|
||||||
current_serial = data;
|
current_serial = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return write_index(masterfd, idx_id, &idx);
|
return write_index(masterfd, idx_id, &idx) ? 0 : -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tagcache_import_changelog(void)
|
bool tagcache_import_changelog(void)
|
||||||
|
@ -2754,7 +2757,6 @@ bool tagcache_import_changelog(void)
|
||||||
struct tagcache_header tch;
|
struct tagcache_header tch;
|
||||||
int clfd, masterfd;
|
int clfd, masterfd;
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
if (!stat.ready)
|
if (!stat.ready)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2779,41 +2781,8 @@ bool tagcache_import_changelog(void)
|
||||||
|
|
||||||
filenametag_fd = open_tag_fd(&tch, tag_filename, false);
|
filenametag_fd = open_tag_fd(&tch, tag_filename, false);
|
||||||
|
|
||||||
/* Fast readline */
|
fast_readline(filenametag_fd, buf, sizeof buf, (void *)masterfd,
|
||||||
while ( 1 )
|
parse_changelog_line);
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
char *next = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = read(clfd, &buf[pos], sizeof(buf)-pos-1);
|
|
||||||
if (rc >= 0)
|
|
||||||
buf[pos+rc] = '\0';
|
|
||||||
|
|
||||||
if ( (p = strchr(buf, '\r')) != NULL)
|
|
||||||
{
|
|
||||||
*p = '\0';
|
|
||||||
next = ++p;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
p = buf;
|
|
||||||
|
|
||||||
if ( (p = strchr(p, '\n')) != NULL)
|
|
||||||
{
|
|
||||||
*p = '\0';
|
|
||||||
next = ++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_changelog_line(masterfd, buf);
|
|
||||||
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
pos = sizeof(buf) - ((long)next - (long)buf) - 1;
|
|
||||||
memmove(buf, next, pos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(clfd);
|
close(clfd);
|
||||||
close(masterfd);
|
close(masterfd);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "atoi.h"
|
#include "atoi.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
#include "yesno.h"
|
#include "yesno.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#define FILE_SEARCH_INSTRUCTIONS ROCKBOX_DIR "/tagnavi.config"
|
#define FILE_SEARCH_INSTRUCTIONS ROCKBOX_DIR "/tagnavi.config"
|
||||||
|
|
||||||
|
@ -678,49 +679,31 @@ bool tagtree_import(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_menu(const char *filename)
|
static bool parse_menu(const char *filename);
|
||||||
|
|
||||||
|
int parse_line(int n, const char *buf, void *parameters)
|
||||||
{
|
{
|
||||||
int fd;
|
|
||||||
char buf[256];
|
|
||||||
char data[256];
|
char data[256];
|
||||||
int variable;
|
int variable;
|
||||||
int rc;
|
static bool read_menu;
|
||||||
bool first = true;
|
|
||||||
bool read_menu = false;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (menu_count >= TAGMENU_MAX_MENUS)
|
(void)parameters;
|
||||||
{
|
|
||||||
logf("max menucount reached");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(filename, O_RDONLY);
|
/* First line, do initialisation. */
|
||||||
if (fd < 0)
|
if (n == 0)
|
||||||
{
|
|
||||||
logf("Search instruction file not found.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now read file for real, parsing into si */
|
|
||||||
while ( 1 )
|
|
||||||
{
|
|
||||||
rc = read_line(fd, buf, sizeof(buf)-1);
|
|
||||||
if (rc <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (first)
|
|
||||||
{
|
{
|
||||||
if (strcasecmp(TAGNAVI_VERSION, buf))
|
if (strcasecmp(TAGNAVI_VERSION, buf))
|
||||||
{
|
{
|
||||||
logf("Version mismatch");
|
logf("Version mismatch");
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
first = false;
|
|
||||||
|
read_menu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf[0] == '#')
|
if (buf[0] == '#')
|
||||||
continue;
|
return 0;
|
||||||
|
|
||||||
if (buf[0] == '\0')
|
if (buf[0] == '\0')
|
||||||
{
|
{
|
||||||
|
@ -730,14 +713,14 @@ static bool parse_menu(const char *filename)
|
||||||
menu_count++;
|
menu_count++;
|
||||||
read_menu = false;
|
read_menu = false;
|
||||||
}
|
}
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!read_menu)
|
if (!read_menu)
|
||||||
{
|
{
|
||||||
strp = buf;
|
strp = buf;
|
||||||
if (get_tag(&variable) <= 0)
|
if (get_tag(&variable) <= 0)
|
||||||
continue;
|
return 0;
|
||||||
|
|
||||||
switch (variable)
|
switch (variable)
|
||||||
{
|
{
|
||||||
|
@ -806,13 +789,13 @@ static bool parse_menu(const char *filename)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu->itemcount >= TAGMENU_MAX_ITEMS)
|
if (menu->itemcount >= TAGMENU_MAX_ITEMS)
|
||||||
{
|
{
|
||||||
logf("max itemcount reached");
|
logf("max itemcount reached");
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate */
|
/* Allocate */
|
||||||
|
@ -825,10 +808,33 @@ static bool parse_menu(const char *filename)
|
||||||
|
|
||||||
memset(menu->items[menu->itemcount]->si, 0, sizeof(struct search_instruction));
|
memset(menu->items[menu->itemcount]->si, 0, sizeof(struct search_instruction));
|
||||||
if (!parse_search(menu->items[menu->itemcount], buf))
|
if (!parse_search(menu->items[menu->itemcount], buf))
|
||||||
continue;
|
return 0;
|
||||||
|
|
||||||
menu->itemcount++;
|
menu->itemcount++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_menu(const char *filename)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (menu_count >= TAGMENU_MAX_MENUS)
|
||||||
|
{
|
||||||
|
logf("max menucount reached");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
logf("Search instruction file not found.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now read file for real, parsing into si */
|
||||||
|
fast_readline(fd, buf, sizeof buf, NULL, parse_line);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue