A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 177 lines 4.7 kB view raw
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}