Something went wrong. Try again.
A modern, network-enabled music player platform built on Rockbox technology. rockboxd.tsiry-sandratraina.com
rust deno navidrome airplay libadwaita zig mpris snapcast mpd rockbox audio subsonic
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * * Copyright (C) 2002 Linus Nielsen Feltzing * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include "plugin.h"
/**************************************************************************** * Buffer handling: * * We allocate the MP3 buffer for storing the text to be sorted, and then * search the buffer for newlines and store an array of character pointers * to the strings. * * The pointer array grows from the top of the buffer and downwards: * * |-------------| * | pointers[2] |--------| * | pointers[1] |------| | * | pointers[0] |----| | | * |-------------| | | | * | | | | | * | | | | | * | free space | | | | * | | | | | * | | | | | * |-------------| | | | * | | | | | * | line 3\0 |<---| | | * | line 2\0 |<-----| | * | line 1\0 |<-------| * |-------------| * * The advantage of this method is that we optimize the buffer usage. * * The disadvantage is that the string pointers will be loaded in reverse * order. We therefore sort the strings in reverse order as well, so we * don't have to sort an already sorted buffer. ****************************************************************************/
/*************************************************************************** * TODO: Implement a merge sort for files larger than the buffer ****************************************************************************/size_t buf_size;static char *filename;static int num_entries;static char **pointers;static char *stringbuffer;static char crlf[2] __NONSTRING = "\r\n";static int bomsize;
/* Compare function for sorting backwards */static int compare(const void* p1, const void* p2){ char *s1 = *(char **)p1; char *s2 = *(char **)p2;
return rb->strcasecmp(s2, s1);}
static void sort_buffer(void){ rb->qsort(pointers, num_entries, sizeof(char *), compare);}
static int read_buffer(int offset){ int fd; char *buf_ptr; char *tmp_ptr; int readsize;
fd = rb->open_utf8(filename, O_RDONLY); if(fd < 0) return 10 * fd - 1;
bomsize = rb->lseek(fd, 0, SEEK_CUR); offset += bomsize;
/* Fill the buffer from the file */ rb->lseek(fd, offset, SEEK_SET); readsize = rb->read(fd, stringbuffer, buf_size); rb->close(fd);
if(readsize < 0) return readsize * 10 - 2;
/* Temporary fix until we can do merged sorting */ if(readsize == (int)buf_size) return buf_size; /* File too big */
buf_ptr = stringbuffer; num_entries = 0;
do { tmp_ptr = buf_ptr; while(*buf_ptr != '\n' && buf_ptr < (char *)pointers) { /* Terminate the string with CR... */ if(*buf_ptr == '\r') *buf_ptr = 0; buf_ptr++; } /* ...and with LF */ if(*buf_ptr == '\n') *buf_ptr = 0; else { return tmp_ptr - stringbuffer; /* Buffer is full, return the point to resume at */ }
pointers--; *pointers = tmp_ptr; num_entries++; buf_ptr++; } while(buf_ptr < stringbuffer + readsize);
return 0;}
static int write_file(void){ char tmpfilename[MAX_PATH+1]; int fd; int i; int rc;
/* Create a temporary file */ rb->snprintf(tmpfilename, MAX_PATH+1, "%s.tmp", filename); if (bomsize) fd = rb->open_utf8(tmpfilename, O_WRONLY|O_CREAT|O_TRUNC); else fd = rb->open(tmpfilename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
if(fd < 0) return 10 * fd - 1;
/* Write the sorted strings, with appended CR/LF, to the temp file, in reverse order */ for(i = num_entries-1;i >= 0;i--) { rc = rb->write(fd, pointers[i], rb->strlen(pointers[i])); if(rc < 0) { rb->close(fd); return 10 * rc - 2; }
rc = rb->write(fd, crlf, 2); if(rc < 0) { rb->close(fd); return 10 * rc - 3; } }
rb->close(fd);
/* Remove the original file */ rc = rb->remove(filename); if(rc < 0) { return 10 * rc - 4; }
/* Replace the old file with the new */ rc = rb->rename(tmpfilename, filename); if(rc < 0) { return 10 * rc - 5; } return 0;}
enum plugin_status plugin_start(const void* parameter){ char *buf; int rc; if(!parameter) return PLUGIN_ERROR;
if (!rb->yesno_pop_confirm(ID2P(LANG_REALLY_OVERWRITE))) return PLUGIN_OK;
filename = (char *)parameter;
buf = rb->plugin_get_audio_buffer(&buf_size); /* start munching memory */
stringbuffer = buf; pointers = (char **)(buf + buf_size - sizeof(int));
rb->lcd_clear_display(); rb->splash(0, "Loading...");
rc = read_buffer(0); if(rc == 0) { rb->lcd_clear_display(); rb->splash(0, "Sorting..."); sort_buffer();
rb->lcd_clear_display(); rb->splash(0, "Writing...");
rc = write_file(); if(rc < 0) { rb->lcd_clear_display(); rb->splashf(HZ, "Can't write file: %d", rc); } else { rb->lcd_clear_display(); rb->splash(HZ, "Done"); } } else { if(rc < 0) { rb->lcd_clear_display(); rb->splashf(HZ, "Can't read file: %d", rc); } else { rb->lcd_clear_display(); rb->splash(HZ, "The file is too big"); } }
return PLUGIN_OK;}