Device detection based on USB PIDs. This is currently linux only and requires libusb...
[Rockbox.git] / apps / plugins / search.c
blob097f4ac7d5892ce361f3d6b9820e56d5e9896065
1 /***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
11 * Copyright (C) 2003 Stefan Meyer
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
20 #include "plugin.h"
21 #include "ctype.h"
23 PLUGIN_HEADER
25 static struct plugin_api* rb;
27 #define BUFFER_SIZE 16384
29 static int fd;
30 static int fdw;
32 static int file_size;
33 static int results = 0;
35 static char buffer[BUFFER_SIZE+1];
36 static char search_string[60] ;
38 static int buffer_pos; /* Position of the buffer in the file */
40 static int line_end; /* Index of the end of line */
42 char resultfile[MAX_PATH];
43 char path[MAX_PATH];
45 static int strpcasecmp(const char *s1, const char *s2){
46 while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) {
47 s1++;
48 s2++;
51 return (*s1 == '\0');
54 static void fill_buffer(int pos){
55 int numread;
56 int i;
57 int found = false ;
58 const char crlf = '\n';
60 if (pos>=file_size-BUFFER_SIZE)
61 pos = file_size-BUFFER_SIZE;
62 if (pos<0)
63 pos = 0;
65 rb->lseek(fd, pos, SEEK_SET);
66 numread = rb->read(fd, buffer, BUFFER_SIZE);
68 buffer[numread] = 0;
69 line_end = 0;
71 for(i=0;i<numread;i++) {
72 switch(buffer[i]) {
73 case '\r':
74 buffer[i] = ' ';
75 break;
76 case '\n':
77 buffer[i] = 0;
78 buffer_pos = pos + i +1 ;
80 if (found){
81 /* write to playlist */
82 rb->write(fdw, &buffer[line_end],
83 rb->strlen( &buffer[line_end] ));
84 rb->write(fdw, &crlf, 1);
86 found = false ;
87 results++ ;
89 line_end = i +1 ;
91 break;
93 default:
94 if (!found && tolower(buffer[i]) == tolower(search_string[0]))
95 found = strpcasecmp(&search_string[0],&buffer[i]) ;
96 break;
99 DEBUGF("\n-------------------\n");
102 static void search_buffer(void){
103 buffer_pos = 0;
105 fill_buffer(0);
106 while ((buffer_pos+1) < file_size)
107 fill_buffer(buffer_pos);
110 static void clear_display(void){
111 int i;
112 FOR_NB_SCREENS(i){
113 rb->screens[i]->clear_display();
117 static bool search_init(char* file){
118 rb->memset(search_string, 0, sizeof(search_string));
120 if (!rb->kbd_input(search_string,sizeof search_string)){
121 clear_display();
122 rb->splash(0, "Searching...");
123 fd = rb->open(file, O_RDONLY);
124 if (fd==-1)
125 return false;
127 fdw = rb->creat(resultfile);
129 if (fdw < 0) {
130 #ifdef HAVE_LCD_BITMAP
131 rb->splash(HZ, "Failed to create result file!");
132 #else
133 rb->splash(HZ, "File creation failed");
134 #endif
135 return false;
138 file_size = rb->lseek(fd, 0, SEEK_END);
140 return true;
143 return false ;
146 /* this is the plugin entry point */
147 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
149 int ok;
150 char *filename = parameter;
151 char *p;
153 rb = api;
155 DEBUGF("%s - %s\n", (char *)parameter, &filename[rb->strlen(filename)-4]);
156 /* Check the extension. We only allow .m3u files. */
157 if(rb->strcasecmp(&filename[rb->strlen(filename)-4], ".m3u") &&
158 rb->strcasecmp(&filename[rb->strlen(filename)-5], ".m3u8")) {
159 rb->splash(HZ, "Not a .m3u or .m3u8 file");
160 return PLUGIN_ERROR;
163 rb->strcpy(path, filename);
165 p = rb->strrchr(path, '/');
166 if(p)
167 *p = 0;
169 rb->snprintf(resultfile, MAX_PATH, "%s/search_result.m3u", path);
170 ok = search_init(parameter);
171 if (!ok)
172 return PLUGIN_ERROR;
173 search_buffer();
175 clear_display();
176 rb->splash(HZ, "Done");
177 rb->close(fdw);
178 rb->close(fd);
180 /* We fake a USB connection to force a reload of the file browser */
181 return PLUGIN_USB_CONNECTED;