1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 /****************************************************************************
26 * We allocate the MP3 buffer for storing the text to be sorted, and then
27 * search the buffer for newlines and store an array of character pointers
30 * The pointer array grows from the top of the buffer and downwards:
33 * | pointers[2] |--------|
34 * | pointers[1] |------| |
35 * | pointers[0] |----| | |
36 * |-------------| | | |
39 * | free space | | | |
42 * |-------------| | | |
44 * | line 3\0 |<---| | |
45 * | line 2\0 |<-----| |
46 * | line 1\0 |<-------|
49 * The advantage of this method is that we optimize the buffer usage.
51 * The disadvantage is that the string pointers will be loaded in reverse
52 * order. We therefore sort the strings in reverse order as well, so we
53 * don't have to sort an already sorted buffer.
54 ****************************************************************************/
56 /***************************************************************************
57 * TODO: Implement a merge sort for files larger than the buffer
58 ****************************************************************************/
63 static char *filename
;
64 static int num_entries
;
65 static char **pointers
;
66 static char *stringbuffer
;
67 static char crlf
[2] = "\r\n";
70 /* Compare function for sorting backwards */
71 static int compare(const void* p1
, const void* p2
)
73 char *s1
= *(char **)p1
;
74 char *s2
= *(char **)p2
;
76 return rb
->strcasecmp(s2
, s1
);
79 static void sort_buffer(void)
81 rb
->qsort(pointers
, num_entries
, sizeof(char *), compare
);
84 int read_buffer(int offset
)
91 fd
= rb
->open_utf8(filename
, O_RDONLY
);
95 bomsize
= rb
->lseek(fd
, 0, SEEK_CUR
);
98 /* Fill the buffer from the file */
99 rb
->lseek(fd
, offset
, SEEK_SET
);
100 readsize
= rb
->read(fd
, stringbuffer
, buf_size
);
104 return readsize
* 10 - 2;
106 /* Temporary fix until we can do merged sorting */
107 if(readsize
== buf_size
)
108 return buf_size
; /* File too big */
110 buf_ptr
= stringbuffer
;
115 while(*buf_ptr
!= '\n' && buf_ptr
< (char *)pointers
) {
116 /* Terminate the string with CR... */
125 return tmp_ptr
- stringbuffer
; /* Buffer is full, return
126 the point to resume at */
133 } while(buf_ptr
< stringbuffer
+ readsize
);
138 static int write_file(void)
140 char tmpfilename
[MAX_PATH
+1];
145 /* Create a temporary file */
146 rb
->snprintf(tmpfilename
, MAX_PATH
+1, "%s.tmp", filename
);
148 fd
= rb
->open_utf8(tmpfilename
, O_WRONLY
|O_CREAT
|O_TRUNC
);
150 fd
= rb
->open(tmpfilename
, O_WRONLY
|O_CREAT
|O_TRUNC
);
155 /* Write the sorted strings, with appended CR/LF, to the temp file,
157 for(i
= num_entries
-1;i
>= 0;i
--) {
158 rc
= rb
->write(fd
, pointers
[i
], rb
->strlen(pointers
[i
]));
164 rc
= rb
->write(fd
, crlf
, 2);
173 /* Remove the original file */
174 rc
= rb
->remove(filename
);
179 /* Replace the old file with the new */
180 rc
= rb
->rename(tmpfilename
, filename
);
187 enum plugin_status
plugin_start(const void* parameter
)
191 if(!parameter
) return PLUGIN_ERROR
;
193 filename
= (char *)parameter
;
195 buf
= rb
->plugin_get_audio_buffer((size_t *)&buf_size
); /* start munching memory */
198 pointers
= (char **)(buf
+ buf_size
- sizeof(int));
200 rb
->lcd_clear_display();
201 rb
->splash(0, "Loading...");
205 rb
->lcd_clear_display();
206 rb
->splash(0, "Sorting...");
209 rb
->lcd_clear_display();
210 rb
->splash(0, "Writing...");
214 rb
->lcd_clear_display();
215 rb
->splashf(HZ
, "Can't write file: %d", rc
);
217 rb
->lcd_clear_display();
218 rb
->splash(HZ
, "Done");
222 rb
->lcd_clear_display();
223 rb
->splashf(HZ
, "Can't read file: %d", rc
);
225 rb
->lcd_clear_display();
226 rb
->splash(HZ
, "The file is too big");