summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2010-01-15 07:20:56 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2010-01-15 07:20:56 +0000
commitfea4689e91139ed92f2acad3c3c30afcbf1c1794 (patch)
treeba29527e52c26fb67bee64c75dbec89d8dae4191
parentfafbfbc56c3f70fe29cb2bc74666298186fa2434 (diff)
downloadrockbox-fea4689e91139ed92f2acad3c3c30afcbf1c1794.tar.gz
rockbox-fea4689e91139ed92f2acad3c3c30afcbf1c1794.zip
Get rid of those horrible macros to protect against NULL reference when looking up the id3 info for tokens.
Change the way the wps playlist viewer gets the token values. All %i tokens are now supported (and a few others, experiment :) ) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24233 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/skin_engine/skin_display.c60
-rw-r--r--apps/gui/skin_engine/skin_tokens.c432
-rw-r--r--apps/gui/skin_engine/wps_internals.h2
-rw-r--r--apps/playback.c4
4 files changed, 239 insertions, 259 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index e63b078d37..e90ac4c4ce 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -169,17 +169,20 @@ bool audio_peek_track(struct mp3entry* id3, int offset);
169static void draw_playlist_viewer_list(struct gui_wps *gwps, 169static void draw_playlist_viewer_list(struct gui_wps *gwps,
170 struct playlistviewer *viewer) 170 struct playlistviewer *viewer)
171{ 171{
172 struct wps_state *state = gwps->state;
172 int lines = viewport_get_nb_lines(viewer->vp); 173 int lines = viewport_get_nb_lines(viewer->vp);
173 int line_height = font_get(viewer->vp->font)->height; 174 int line_height = font_get(viewer->vp->font)->height;
174 int cur_playlist_pos = playlist_get_display_index(); 175 int cur_playlist_pos = playlist_get_display_index();
175 int start_item = MAX(0, cur_playlist_pos + viewer->start_offset); 176 int start_item = MAX(0, cur_playlist_pos + viewer->start_offset);
176 int i; 177 int i;
178 struct wps_token token;
177 179
178 struct mp3entry *pid3; 180 struct mp3entry *pid3;
179#if CONFIG_CODEC == SWCODEC 181#if CONFIG_CODEC == SWCODEC
180 struct mp3entry id3; 182 struct mp3entry id3;
181#endif 183#endif
182 char buf[MAX_PATH*2], tempbuf[MAX_PATH]; 184 char buf[MAX_PATH*2], tempbuf[MAX_PATH];
185 unsigned int buf_used = 0;
183 186
184 187
185 gwps->display->set_viewport(viewer->vp); 188 gwps->display->set_viewport(viewer->vp);
@@ -187,11 +190,11 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps,
187 { 190 {
188 if (i == cur_playlist_pos) 191 if (i == cur_playlist_pos)
189 { 192 {
190 pid3 = audio_current_track(); 193 pid3 = state->id3;
191 } 194 }
192 else if (i == cur_playlist_pos+1) 195 else if (i == cur_playlist_pos+1)
193 { 196 {
194 pid3 = audio_next_track(); 197 pid3 = state->nid3;
195 } 198 }
196#if CONFIG_CODEC == SWCODEC 199#if CONFIG_CODEC == SWCODEC
197 else if ((i>cur_playlist_pos) && audio_peek_track(&id3, i-cur_playlist_pos)) 200 else if ((i>cur_playlist_pos) && audio_peek_track(&id3, i-cur_playlist_pos))
@@ -200,51 +203,56 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps,
200 } 203 }
201#endif 204#endif
202 else 205 else
206 {
203 pid3 = NULL; 207 pid3 = NULL;
208 }
204 209
205 int line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; 210 int line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO;
206 int token = 0, cur_string = 0; 211 int j = 0, cur_string = 0;
207 char *filename = playlist_peek(i-cur_playlist_pos); 212 char *filename = playlist_peek(i-cur_playlist_pos);
208 buf[0] = '\0'; 213 buf[0] = '\0';
209 while (token < viewer->lines[line].count) 214 buf_used = 0;
215 while (j < viewer->lines[line].count && (buf_used<sizeof(buf)))
210 { 216 {
211 switch (viewer->lines[line].tokens[token]) 217 const char *out = NULL;
218 token.type = viewer->lines[line].tokens[j];
219 token.value.i = 0;
220 token.next = false;
221 out = get_id3_token(&token, pid3, tempbuf, sizeof(tempbuf), -1, NULL);
222 if (out)
223 {
224 snprintf(&buf[buf_used], sizeof(buf)-buf_used, "%s", out);
225 buf_used += strlen(out);
226 j++;
227 continue;
228 }
229 switch (viewer->lines[line].tokens[j])
212 { 230 {
213 case WPS_TOKEN_STRING: 231 case WPS_TOKEN_STRING:
214 case WPS_TOKEN_CHARACTER: 232 case WPS_TOKEN_CHARACTER:
215 strcat(buf, viewer->lines[line].strings[cur_string++]); 233 snprintf(tempbuf, sizeof(tempbuf), "%s",
234 viewer->lines[line].strings[cur_string]);
235 cur_string++;
216 break; 236 break;
217 case WPS_TOKEN_PLAYLIST_POSITION: 237 case WPS_TOKEN_PLAYLIST_POSITION:
218 snprintf(tempbuf, sizeof(tempbuf), "%d", i); 238 snprintf(tempbuf, sizeof(tempbuf), "%d", i);
219 strcat(buf, tempbuf);
220 break; 239 break;
221 case WPS_TOKEN_FILE_NAME: 240 case WPS_TOKEN_FILE_NAME:
222 get_dir(tempbuf, sizeof(tempbuf), filename, 0); 241 get_dir(tempbuf, sizeof(tempbuf), filename, 0);
223 strcat(buf, tempbuf);
224 break; 242 break;
225 case WPS_TOKEN_FILE_PATH: 243 case WPS_TOKEN_FILE_PATH:
226 strcat(buf, filename); 244 snprintf(tempbuf, sizeof(tempbuf), "%s", filename);
227 break;
228 case WPS_TOKEN_METADATA_ARTIST:
229 if (pid3)
230 strcat(buf, pid3->artist ? pid3->artist : "");
231 break; 245 break;
232 case WPS_TOKEN_METADATA_TRACK_TITLE:
233 if (pid3)
234 strcat(buf, pid3->title ? pid3->title : "");
235 break;
236 case WPS_TOKEN_TRACK_LENGTH:
237 if (pid3)
238 {
239 format_time(tempbuf, sizeof(tempbuf), pid3->length);
240 strcat(buf, tempbuf);
241 }
242 break;
243
244 default: 246 default:
247 tempbuf[0] = '\0';
245 break; 248 break;
246 } 249 }
247 token++; 250 if (tempbuf[0])
251 {
252 snprintf(&buf[buf_used], sizeof(buf)-buf_used, "%s", tempbuf);
253 buf_used += strlen(tempbuf);
254 }
255 j++;
248 } 256 }
249 257
250 if (viewer->lines[line].scroll) 258 if (viewer->lines[line].scroll)
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 9b54361321..c09a6ef839 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -62,6 +62,8 @@
62#include "language.h" 62#include "language.h"
63#include "usb.h" 63#include "usb.h"
64 64
65extern struct wps_state wps_state;
66
65static char* get_codectype(const struct mp3entry* id3) 67static char* get_codectype(const struct mp3entry* id3)
66{ 68{
67 if (id3 && id3->codectype < AFMT_NUM_CODECS) { 69 if (id3 && id3->codectype < AFMT_NUM_CODECS) {
@@ -148,8 +150,197 @@ static int pitch_speed_enum(int range, int32_t val, int32_t normval)
148} 150}
149#endif 151#endif
150 152
151/* Return the tag found at index i and write its value in buf. 153
152 The return value is buf if the tag had a value, or NULL if not. 154/* All tokens which only need the info to return a value go in here */
155const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
156 char *buf, int buf_size, int limit, int *intval)
157{
158 struct wps_state *state = &wps_state;
159 if (id3)
160 {
161 switch (token->type)
162 {
163 case WPS_TOKEN_METADATA_ARTIST:
164 return id3->artist;
165 case WPS_TOKEN_METADATA_COMPOSER:
166 return id3->composer;
167 case WPS_TOKEN_METADATA_ALBUM:
168 return id3->album;
169 case WPS_TOKEN_METADATA_ALBUM_ARTIST:
170 return id3->albumartist;
171 case WPS_TOKEN_METADATA_GROUPING:
172 return id3->grouping;
173 case WPS_TOKEN_METADATA_GENRE:
174 return id3->genre_string;
175 case WPS_TOKEN_METADATA_DISC_NUMBER:
176 if (id3->disc_string)
177 return id3->disc_string;
178 if (id3->discnum) {
179 snprintf(buf, buf_size, "%d", id3->discnum);
180 return buf;
181 }
182 return NULL;
183 case WPS_TOKEN_METADATA_TRACK_NUMBER:
184 if (id3->track_string)
185 return id3->track_string;
186 if (id3->tracknum) {
187 snprintf(buf, buf_size, "%d", id3->tracknum);
188 return buf;
189 }
190 return NULL;
191 case WPS_TOKEN_METADATA_TRACK_TITLE:
192 return id3->title;
193 case WPS_TOKEN_METADATA_VERSION:
194 switch (id3->id3version)
195 {
196 case ID3_VER_1_0:
197 return "1";
198 case ID3_VER_1_1:
199 return "1.1";
200 case ID3_VER_2_2:
201 return "2.2";
202 case ID3_VER_2_3:
203 return "2.3";
204 case ID3_VER_2_4:
205 return "2.4";
206 default:
207 break;
208 }
209 return NULL;
210 case WPS_TOKEN_METADATA_YEAR:
211 if( id3->year_string )
212 return id3->year_string;
213 if (id3->year) {
214 snprintf(buf, buf_size, "%d", id3->year);
215 return buf;
216 }
217 return NULL;
218 case WPS_TOKEN_METADATA_COMMENT:
219 return id3->comment;
220 case WPS_TOKEN_FILE_PATH:
221 return id3->path;
222 case WPS_TOKEN_FILE_BITRATE:
223 if(id3->bitrate)
224 snprintf(buf, buf_size, "%d", id3->bitrate);
225 else
226 return "?";
227 return buf;
228 case WPS_TOKEN_TRACK_TIME_ELAPSED:
229 format_time(buf, buf_size,
230 id3->elapsed + state->ff_rewind_count);
231 return buf;
232
233 case WPS_TOKEN_TRACK_TIME_REMAINING:
234 format_time(buf, buf_size,
235 id3->length - id3->elapsed -
236 state->ff_rewind_count);
237 return buf;
238
239 case WPS_TOKEN_TRACK_LENGTH:
240 format_time(buf, buf_size, id3->length);
241 return buf;
242
243 case WPS_TOKEN_TRACK_ELAPSED_PERCENT:
244 if (id3->length <= 0)
245 return NULL;
246
247 if (intval)
248 {
249 *intval = limit * (id3->elapsed + state->ff_rewind_count)
250 / id3->length + 1;
251 }
252 snprintf(buf, buf_size, "%d",
253 100*(id3->elapsed + state->ff_rewind_count) / id3->length);
254 return buf;
255
256
257 case WPS_TOKEN_FILE_CODEC:
258 if (intval)
259 {
260 if(id3->codectype == AFMT_UNKNOWN)
261 *intval = AFMT_NUM_CODECS;
262 else
263 *intval = id3->codectype;
264 }
265 return get_codectype(id3);
266
267 case WPS_TOKEN_FILE_FREQUENCY:
268 snprintf(buf, buf_size, "%ld", id3->frequency);
269 return buf;
270 case WPS_TOKEN_FILE_FREQUENCY_KHZ:
271 /* ignore remainders < 100, so 22050 Hz becomes just 22k */
272 if ((id3->frequency % 1000) < 100)
273 snprintf(buf, buf_size, "%ld", id3->frequency / 1000);
274 else
275 snprintf(buf, buf_size, "%ld.%d",
276 id3->frequency / 1000,
277 (id3->frequency % 1000) / 100);
278 return buf;
279 case WPS_TOKEN_FILE_NAME:
280 if (get_dir(buf, buf_size, id3->path, 0)) {
281 /* Remove extension */
282 char* sep = strrchr(buf, '.');
283 if (NULL != sep) {
284 *sep = 0;
285 }
286 return buf;
287 }
288 return NULL;
289 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
290 return get_dir(buf, buf_size, id3->path, 0);
291 case WPS_TOKEN_FILE_SIZE:
292 snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
293 return buf;
294 case WPS_TOKEN_FILE_VBR:
295 return (id3->vbr) ? "(avg)" : NULL;
296 case WPS_TOKEN_FILE_DIRECTORY:
297 return get_dir(buf, buf_size, id3->path, token->value.i);
298
299#ifdef HAVE_TAGCACHE
300 case WPS_TOKEN_DATABASE_PLAYCOUNT:
301 if (intval)
302 *intval = id3->playcount + 1;
303 snprintf(buf, buf_size, "%ld", id3->playcount);
304 return buf;
305 case WPS_TOKEN_DATABASE_RATING:
306 if (intval)
307 *intval = id3->rating + 1;
308 snprintf(buf, buf_size, "%ld", id3->rating);
309 return buf;
310 case WPS_TOKEN_DATABASE_AUTOSCORE:
311 if (intval)
312 *intval = id3->score + 1;
313 snprintf(buf, buf_size, "%ld", id3->score);
314 return buf;
315#endif
316
317 default:
318 return NULL;
319 }
320 }
321 else /* id3 == NULL, handle the error based on the expected return type */
322 {
323 switch (token->type)
324 {
325 /* Most tokens expect NULL on error so leave that for the default case,
326 * The ones that expect "0" need to be handled */
327 case WPS_TOKEN_FILE_FREQUENCY:
328 case WPS_TOKEN_FILE_FREQUENCY_KHZ:
329 case WPS_TOKEN_FILE_SIZE:
330 case WPS_TOKEN_DATABASE_PLAYCOUNT:
331 case WPS_TOKEN_DATABASE_RATING:
332 case WPS_TOKEN_DATABASE_AUTOSCORE:
333 if (intval)
334 *intval = 0;
335 return "0";
336 default:
337 return NULL;
338 }
339 }
340 return buf;
341}
342
343/* Return the tags value as text. buf should be used as temp storage if needed.
153 344
154 intval is used with conditionals/enums: when this function is called, 345 intval is used with conditionals/enums: when this function is called,
155 intval should contain the number of options in the conditional/enum. 346 intval should contain the number of options in the conditional/enum.
@@ -158,27 +349,6 @@ static int pitch_speed_enum(int range, int32_t val, int32_t normval)
158 and the original value of *intval, inclusive). 349 and the original value of *intval, inclusive).
159 When not treating a conditional/enum, intval should be NULL. 350 When not treating a conditional/enum, intval should be NULL.
160*/ 351*/
161
162/* a few convinience macros for the id3 == NULL case
163 * depends on a few variable names in get_token_value() */
164
165#define HANDLE_NULL_ID3(id3field) (LIKELY(id3) ? (id3field) : NULL)
166
167#define HANDLE_NULL_ID3_NUM_ZERO { if (UNLIKELY(!id3)) return zero_str; }
168
169#define HANDLE_NULL_ID3_NUM_INTVAL(id3field) \
170 do { \
171 if (intval) { \
172 *intval = (LIKELY(id3) ? (id3field) + 1 : 0); \
173 } \
174 if (LIKELY(id3)) \
175 { \
176 snprintf(buf, buf_size, "%ld", (id3field)); \
177 return buf; \
178 } \
179 return zero_str; \
180 } while (0)
181
182const char *get_token_value(struct gui_wps *gwps, 352const char *get_token_value(struct gui_wps *gwps,
183 struct wps_token *token, 353 struct wps_token *token,
184 char *buf, int buf_size, 354 char *buf, int buf_size,
@@ -189,30 +359,19 @@ const char *get_token_value(struct gui_wps *gwps,
189 359
190 struct wps_data *data = gwps->data; 360 struct wps_data *data = gwps->data;
191 struct wps_state *state = gwps->state; 361 struct wps_state *state = gwps->state;
192 int elapsed, length; 362 struct mp3entry *id3; /* Think very carefully about using this.
193 static const char * const zero_str = "0"; 363 maybe get_id3_token() is the better place? */
364 const char *out_text = NULL;
194 365
195 if (!data || !state) 366 if (!data || !state)
196 return NULL; 367 return NULL;
197 368
198 struct mp3entry *id3;
199 369
200 if (token->next) 370 if (token->next)
201 id3 = state->nid3; 371 id3 = state->nid3;
202 else 372 else
203 id3 = state->id3; 373 id3 = state->id3;
204 374
205 if (id3)
206 {
207 elapsed = id3->elapsed;
208 length = id3->length;
209 }
210 else
211 {
212 elapsed = 0;
213 length = 0;
214 }
215
216#if CONFIG_RTC 375#if CONFIG_RTC
217 struct tm* tm = NULL; 376 struct tm* tm = NULL;
218 377
@@ -234,6 +393,10 @@ const char *get_token_value(struct gui_wps *gwps,
234 limit = *intval; 393 limit = *intval;
235 *intval = -1; 394 *intval = -1;
236 } 395 }
396
397 out_text = get_id3_token(token, id3, buf, buf_size, limit, intval);
398 if (out_text)
399 return out_text;
237 400
238 switch (token->type) 401 switch (token->type)
239 { 402 {
@@ -248,21 +411,6 @@ const char *get_token_value(struct gui_wps *gwps,
248 case WPS_TOKEN_TRANSLATEDSTRING: 411 case WPS_TOKEN_TRANSLATEDSTRING:
249 return (char*)P2STR(ID2P(token->value.i)); 412 return (char*)P2STR(ID2P(token->value.i));
250 413
251 case WPS_TOKEN_TRACK_TIME_ELAPSED:
252 format_time(buf, buf_size,
253 elapsed + state->ff_rewind_count);
254 return buf;
255
256 case WPS_TOKEN_TRACK_TIME_REMAINING:
257 format_time(buf, buf_size,
258 length - elapsed -
259 state->ff_rewind_count);
260 return buf;
261
262 case WPS_TOKEN_TRACK_LENGTH:
263 format_time(buf, buf_size, length);
264 return buf;
265
266 case WPS_TOKEN_PLAYLIST_ENTRIES: 414 case WPS_TOKEN_PLAYLIST_ENTRIES:
267 snprintf(buf, buf_size, "%d", playlist_amount()); 415 snprintf(buf, buf_size, "%d", playlist_amount());
268 return buf; 416 return buf;
@@ -305,105 +453,6 @@ const char *get_token_value(struct gui_wps *gwps,
305 } 453 }
306 } 454 }
307 return buf; 455 return buf;
308
309 case WPS_TOKEN_TRACK_ELAPSED_PERCENT:
310 if (length <= 0)
311 return NULL;
312
313 if (intval)
314 {
315 *intval = limit * (elapsed + state->ff_rewind_count)
316 / length + 1;
317 }
318 snprintf(buf, buf_size, "%d",
319 100*(elapsed + state->ff_rewind_count) / length);
320 return buf;
321
322 case WPS_TOKEN_METADATA_ARTIST:
323 return HANDLE_NULL_ID3(id3->artist);
324
325 case WPS_TOKEN_METADATA_COMPOSER:
326 return HANDLE_NULL_ID3(id3->composer);
327
328 case WPS_TOKEN_METADATA_ALBUM:
329 return HANDLE_NULL_ID3(id3->album);
330
331 case WPS_TOKEN_METADATA_ALBUM_ARTIST:
332 return HANDLE_NULL_ID3(id3->albumartist);
333
334 case WPS_TOKEN_METADATA_GROUPING:
335 return HANDLE_NULL_ID3(id3->grouping);
336
337 case WPS_TOKEN_METADATA_GENRE:
338 return HANDLE_NULL_ID3(id3->genre_string);
339
340 case WPS_TOKEN_METADATA_DISC_NUMBER:
341 if (LIKELY(id3)) {
342 if (id3->disc_string)
343 return id3->disc_string;
344 if (id3->discnum) {
345 snprintf(buf, buf_size, "%d", id3->discnum);
346 return buf;
347 }
348 }
349 return NULL;
350
351 case WPS_TOKEN_METADATA_TRACK_NUMBER:
352 if (LIKELY(id3)) {
353 if (id3->track_string)
354 return id3->track_string;
355
356 if (id3->tracknum) {
357 snprintf(buf, buf_size, "%d", id3->tracknum);
358 return buf;
359 }
360 }
361 return NULL;
362
363 case WPS_TOKEN_METADATA_TRACK_TITLE:
364 return HANDLE_NULL_ID3(id3->title);
365
366 case WPS_TOKEN_METADATA_VERSION:
367 if (LIKELY(id3))
368 {
369 switch (id3->id3version)
370 {
371 case ID3_VER_1_0:
372 return "1";
373
374 case ID3_VER_1_1:
375 return "1.1";
376
377 case ID3_VER_2_2:
378 return "2.2";
379
380 case ID3_VER_2_3:
381 return "2.3";
382
383 case ID3_VER_2_4:
384 return "2.4";
385
386 default:
387 break;
388 }
389 }
390 return NULL;
391
392 case WPS_TOKEN_METADATA_YEAR:
393 if (LIKELY(id3)) {
394 if( id3->year_string )
395 return id3->year_string;
396
397 if (id3->year) {
398 snprintf(buf, buf_size, "%d", id3->year);
399 return buf;
400 }
401 }
402 return NULL;
403
404 case WPS_TOKEN_METADATA_COMMENT:
405 return HANDLE_NULL_ID3(id3->comment);
406
407#ifdef HAVE_ALBUMART 456#ifdef HAVE_ALBUMART
408 case WPS_TOKEN_ALBUMART_FOUND: 457 case WPS_TOKEN_ALBUMART_FOUND:
409 if (data->albumart) { 458 if (data->albumart) {
@@ -420,75 +469,6 @@ const char *get_token_value(struct gui_wps *gwps,
420 return NULL; 469 return NULL;
421#endif 470#endif
422 471
423 case WPS_TOKEN_FILE_BITRATE:
424 if(id3 && id3->bitrate)
425 snprintf(buf, buf_size, "%d", id3->bitrate);
426 else
427 return "?";
428 return buf;
429
430 case WPS_TOKEN_FILE_CODEC:
431 if (intval)
432 {
433 if (UNLIKELY(!id3))
434 *intval = 0;
435 else if(id3->codectype == AFMT_UNKNOWN)
436 *intval = AFMT_NUM_CODECS;
437 else
438 *intval = id3->codectype;
439 }
440 return get_codectype(id3);
441
442 case WPS_TOKEN_FILE_FREQUENCY:
443 HANDLE_NULL_ID3_NUM_ZERO;
444 snprintf(buf, buf_size, "%ld", id3->frequency);
445 return buf;
446
447 case WPS_TOKEN_FILE_FREQUENCY_KHZ:
448 HANDLE_NULL_ID3_NUM_ZERO;
449 /* ignore remainders < 100, so 22050 Hz becomes just 22k */
450 if ((id3->frequency % 1000) < 100)
451 snprintf(buf, buf_size, "%ld", id3->frequency / 1000);
452 else
453 snprintf(buf, buf_size, "%ld.%d",
454 id3->frequency / 1000,
455 (id3->frequency % 1000) / 100);
456 return buf;
457
458 case WPS_TOKEN_FILE_NAME:
459 if (LIKELY(id3) && get_dir(buf, buf_size, id3->path, 0)) {
460 /* Remove extension */
461 char* sep = strrchr(buf, '.');
462 if (NULL != sep) {
463 *sep = 0;
464 }
465 return buf;
466 }
467 else {
468 return NULL;
469 }
470
471 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
472 if (LIKELY(id3))
473 return get_dir(buf, buf_size, id3->path, 0);
474 return NULL;
475
476 case WPS_TOKEN_FILE_PATH:
477 return HANDLE_NULL_ID3(id3->path);
478
479 case WPS_TOKEN_FILE_SIZE:
480 HANDLE_NULL_ID3_NUM_ZERO;
481 snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
482 return buf;
483
484 case WPS_TOKEN_FILE_VBR:
485 return (LIKELY(id3) && id3->vbr) ? "(avg)" : NULL;
486
487 case WPS_TOKEN_FILE_DIRECTORY:
488 if (LIKELY(id3))
489 return get_dir(buf, buf_size, id3->path, token->value.i);
490 return NULL;
491
492 case WPS_TOKEN_BATTERY_PERCENT: 472 case WPS_TOKEN_BATTERY_PERCENT:
493 { 473 {
494 int l = battery_level(); 474 int l = battery_level();
@@ -760,17 +740,7 @@ const char *get_token_value(struct gui_wps *gwps,
760 return buf; 740 return buf;
761#endif 741#endif
762 742
763
764#ifdef HAVE_TAGCACHE
765 case WPS_TOKEN_DATABASE_PLAYCOUNT:
766 HANDLE_NULL_ID3_NUM_INTVAL(id3->playcount);
767
768 case WPS_TOKEN_DATABASE_RATING:
769 HANDLE_NULL_ID3_NUM_INTVAL(id3->rating);
770 743
771 case WPS_TOKEN_DATABASE_AUTOSCORE:
772 HANDLE_NULL_ID3_NUM_INTVAL(id3->score);
773#endif
774 744
775#if (CONFIG_CODEC == SWCODEC) 745#if (CONFIG_CODEC == SWCODEC)
776 case WPS_TOKEN_CROSSFADE: 746 case WPS_TOKEN_CROSSFADE:
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index 362f3947e7..837e56eab1 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -358,6 +358,8 @@ const char *get_token_value(struct gui_wps *gwps,
358 char *buf, int buf_size, 358 char *buf, int buf_size,
359 int *intval); 359 int *intval);
360 360
361const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
362 char *buf, int buf_size, int limit, int *intval);
361 363
362 364
363struct gui_img* find_image(char label, struct wps_data *data); 365struct gui_img* find_image(char label, struct wps_data *data);
diff --git a/apps/playback.c b/apps/playback.c
index fca21ae1fb..b7078441c2 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -640,8 +640,8 @@ bool audio_peek_track(struct mp3entry* id3, int offset)
640 640
641 if (tracks[next_idx].id3_hid >= 0) 641 if (tracks[next_idx].id3_hid >= 0)
642 { 642 {
643 bufread(tracks[next_idx].id3_hid, sizeof(struct mp3entry), id3); 643 return bufread(tracks[next_idx].id3_hid, sizeof(struct mp3entry), id3)
644 return true; 644 == sizeof(struct mp3entry);
645 } 645 }
646 return false; 646 return false;
647} 647}