A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 *
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
10 *
11 * Copyright (C) 2003 Stefan Meyer
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "plugin.h"
23#include <ctype.h>
24
25
26
27#define BUFFER_SIZE 16384
28
29static int fd;
30static int fdw;
31
32static int file_size, bomsize;
33static int results = 0;
34
35static char buffer[BUFFER_SIZE+1];
36static char search_string[60] ;
37
38static int buffer_pos; /* Position of the buffer in the file */
39
40static int line_end; /* Index of the end of line */
41
42char resultfile[MAX_PATH];
43char path[MAX_PATH];
44
45static int strpcasecmp(const char *s1, const char *s2){
46 while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) {
47 s1++;
48 s2++;
49 }
50
51 return (*s1 == '\0');
52}
53
54static void fill_buffer(int pos){
55 int numread;
56 int i;
57 int found = false ;
58 const char crlf = '\n';
59
60 rb->lseek(fd, pos+bomsize, SEEK_SET);
61 numread = rb->read(fd, buffer, MIN(BUFFER_SIZE, file_size-pos));
62
63 buffer[numread] = 0;
64 line_end = 0;
65
66 for(i=0;i<numread;i++) {
67 switch(buffer[i]) {
68 case '\r':
69 buffer[i] = ' ';
70 break;
71 case '\n':
72 buffer[i] = 0;
73 buffer_pos = pos + i +1 ;
74
75 if (found){
76 /* write to playlist */
77 rb->write(fdw, &buffer[line_end],
78 rb->strlen( &buffer[line_end] ));
79 rb->write(fdw, &crlf, 1);
80
81 found = false ;
82 results++ ;
83 }
84 line_end = i +1 ;
85
86 break;
87
88 default:
89 if (!found && tolower(buffer[i]) == tolower(search_string[0]))
90 found = strpcasecmp(&search_string[0],&buffer[i]) ;
91 break;
92 }
93 }
94 DEBUGF("\n-------------------\n");
95}
96
97static void search_buffer(void){
98 buffer_pos = 0;
99
100 fill_buffer(0);
101 while ((buffer_pos+1) < file_size)
102 fill_buffer(buffer_pos);
103}
104
105static void clear_display(void){
106 FOR_NB_SCREENS(i){
107 rb->screens[i]->clear_display();
108 }
109}
110
111static bool search_init(const char* file){
112 rb->memset(search_string, 0, sizeof(search_string));
113
114 if (!rb->kbd_input(search_string,sizeof(search_string), NULL)){
115 clear_display();
116 rb->splash(0, "Searching...");
117 fd = rb->open_utf8(file, O_RDONLY);
118 if (fd < 0)
119 return false;
120
121 bomsize = rb->lseek(fd, 0, SEEK_CUR);
122 if (bomsize)
123 fdw = rb->open_utf8(resultfile, O_WRONLY|O_CREAT|O_TRUNC);
124 else
125 fdw = rb->open(resultfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
126
127 if (fdw < 0) {
128 rb->splash(HZ, "Failed to create result file!");
129 rb->close(fd);
130 return false;
131 }
132
133 file_size = rb->lseek(fd, 0, SEEK_END) - bomsize;
134
135 return true;
136 }
137
138 return false ;
139}
140
141/* this is the plugin entry point */
142enum plugin_status plugin_start(const void* parameter)
143{
144 int ok;
145 const char *filename = parameter;
146 char *p;
147 if(!parameter) return PLUGIN_ERROR;
148
149 DEBUGF("%s - %s\n", (char *)parameter, &filename[rb->strlen(filename)-4]);
150 /* Check the extension. We only allow .m3u files. */
151 if (!(p = rb->strrchr(filename, '.')) ||
152 (rb->strcasecmp(p, ".m3u") && rb->strcasecmp(p, ".m3u8")))
153 {
154 rb->splash(HZ, "Not a .m3u or .m3u8 file");
155 return PLUGIN_ERROR;
156 }
157
158 rb->strcpy(path, filename);
159
160 p = rb->strrchr(path, '/');
161 if(p)
162 *p = 0;
163
164 rb->snprintf(resultfile, MAX_PATH, "%s/search_result.m3u", path);
165 ok = search_init(parameter);
166 if (!ok)
167 return PLUGIN_ERROR;
168 search_buffer();
169
170 clear_display();
171 rb->splash(HZ, "Done");
172 rb->close(fdw);
173 rb->close(fd);
174 rb->reload_directory();
175
176 return PLUGIN_OK;
177}