summaryrefslogtreecommitdiff
path: root/apps/plugins/text_viewer/tv_settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/text_viewer/tv_settings.c')
-rw-r--r--apps/plugins/text_viewer/tv_settings.c127
1 files changed, 83 insertions, 44 deletions
diff --git a/apps/plugins/text_viewer/tv_settings.c b/apps/plugins/text_viewer/tv_settings.c
index 3004ac3d60..20e8212147 100644
--- a/apps/plugins/text_viewer/tv_settings.c
+++ b/apps/plugins/text_viewer/tv_settings.c
@@ -120,6 +120,10 @@
120#define TV_SETTINGS_FIRST_VERSION 0x32 120#define TV_SETTINGS_FIRST_VERSION 0x32
121 121
122#define TV_PREFERENCES_SIZE (28 + MAX_PATH) 122#define TV_PREFERENCES_SIZE (28 + MAX_PATH)
123#define TV_MAX_FILE_RECORD_SIZE (MAX_PATH+2 + TV_PREFERENCES_SIZE + TV_MAX_BOOKMARKS*SERIALIZE_BOOKMARK_SIZE+1)
124
125static off_t stored_preferences_offset = 0;
126static int stored_preferences_size = 0;
123 127
124/* ---------------------------------------------------------------------------- 128/* ----------------------------------------------------------------------------
125 * read/write the preferences 129 * read/write the preferences
@@ -220,9 +224,8 @@ static bool tv_read_preferences(int pfd, int version, struct tv_preferences *pre
220 return true; 224 return true;
221} 225}
222 226
223static bool tv_write_preferences(int pfd, const struct tv_preferences *prefs) 227static void tv_serialize_preferences(unsigned char *buf, const struct tv_preferences *prefs)
224{ 228{
225 unsigned char buf[TV_PREFERENCES_SIZE];
226 unsigned char *p = buf; 229 unsigned char *p = buf;
227 230
228 rb->memset(buf, 0, TV_PREFERENCES_SIZE); 231 rb->memset(buf, 0, TV_PREFERENCES_SIZE);
@@ -248,6 +251,13 @@ static bool tv_write_preferences(int pfd, const struct tv_preferences *prefs)
248#ifdef HAVE_LCD_BITMAP 251#ifdef HAVE_LCD_BITMAP
249 rb->strlcpy(buf + 28, prefs->font_name, MAX_PATH); 252 rb->strlcpy(buf + 28, prefs->font_name, MAX_PATH);
250#endif 253#endif
254}
255
256static bool tv_write_preferences(int pfd, const struct tv_preferences *prefs)
257{
258 unsigned char buf[TV_PREFERENCES_SIZE];
259
260 tv_serialize_preferences(buf, prefs);
251 261
252 return (rb->write(pfd, buf, TV_PREFERENCES_SIZE) >= 0); 262 return (rb->write(pfd, buf, TV_PREFERENCES_SIZE) >= 0);
253} 263}
@@ -427,6 +437,7 @@ bool tv_load_settings(const unsigned char *file_name)
427 int version; 437 int version;
428 unsigned int size; 438 unsigned int size;
429 struct tv_preferences prefs; 439 struct tv_preferences prefs;
440 off_t current_pref_offset;
430 441
431 if (!rb->file_exists(TV_SETTINGS_FILE)) 442 if (!rb->file_exists(TV_SETTINGS_FILE))
432 tv_convert_settings_file(); 443 tv_convert_settings_file();
@@ -438,6 +449,8 @@ bool tv_load_settings(const unsigned char *file_name)
438 { 449 {
439 version = buf[TV_SETTINGS_HEADER_SIZE - 1] - TV_SETTINGS_FIRST_VERSION; 450 version = buf[TV_SETTINGS_HEADER_SIZE - 1] - TV_SETTINGS_FIRST_VERSION;
440 fcount = (buf[TV_SETTINGS_HEADER_SIZE] << 8) | buf[TV_SETTINGS_HEADER_SIZE+1]; 451 fcount = (buf[TV_SETTINGS_HEADER_SIZE] << 8) | buf[TV_SETTINGS_HEADER_SIZE+1];
452
453 current_pref_offset = rb->lseek(fd, 0, SEEK_CUR);
441 454
442 for (i = 0; i < fcount; i++) 455 for (i = 0; i < fcount; i++)
443 { 456 {
@@ -448,10 +461,15 @@ bool tv_load_settings(const unsigned char *file_name)
448 { 461 {
449 if (tv_read_preferences(fd, version, &prefs)) 462 if (tv_read_preferences(fd, version, &prefs))
450 res = tv_deserialize_bookmarks(fd); 463 res = tv_deserialize_bookmarks(fd);
464
465 if (res) {
466 stored_preferences_offset = current_pref_offset;
467 stored_preferences_size = size;
468 }
451 469
452 break; 470 break;
453 } 471 }
454 rb->lseek(fd, size, SEEK_CUR); 472 current_pref_offset = rb->lseek(fd, size, SEEK_CUR);
455 } 473 }
456 } 474 }
457 rb->close(fd); 475 rb->close(fd);
@@ -473,38 +491,74 @@ bool tv_load_settings(const unsigned char *file_name)
473 return tv_set_preferences(&prefs); 491 return tv_set_preferences(&prefs);
474} 492}
475 493
476static bool tv_copy_settings(int sfd, int dfd, int size)
477{
478 unsigned char buf[MAX_PATH];
479 int i = size / MAX_PATH;
480
481 size %= MAX_PATH;
482
483 while (i--)
484 {
485 if ((rb->read(sfd, buf, MAX_PATH) < 0) || (rb->write(dfd, buf, MAX_PATH) < 0))
486 return false;
487 }
488
489 return ((rb->read(sfd, buf, size) >= 0) && (rb->write(dfd, buf, size) >= 0));
490}
491
492bool tv_save_settings(void) 494bool tv_save_settings(void)
493{ 495{
494 unsigned char buf[MAX_PATH+2]; 496 unsigned char buf[TV_MAX_FILE_RECORD_SIZE];
497 unsigned char preferences_buf[TV_MAX_FILE_RECORD_SIZE];
495 unsigned int fcount = 0; 498 unsigned int fcount = 0;
499 unsigned int new_fcount = 0;
496 unsigned int i; 500 unsigned int i;
497 int ofd = -1; 501 int ofd = -1;
498 int tfd; 502 int tfd;
499 off_t size; 503 off_t size;
504 off_t preferences_buf_size;
500 bool res = true; 505 bool res = true;
501 506
502 /* add reading page to bookmarks */ 507 /* add reading page to bookmarks */
503 tv_create_system_bookmark(); 508 tv_create_system_bookmark();
504 509
510 /* storing preferences record in memory */
511 rb->memset(preferences_buf, 0, MAX_PATH);
512 rb->strlcpy(preferences_buf, preferences->file_name, MAX_PATH);
513 preferences_buf_size = MAX_PATH + 2;
514
515 tv_serialize_preferences(preferences_buf + preferences_buf_size, preferences);
516 preferences_buf_size += TV_PREFERENCES_SIZE;
517 preferences_buf_size += tv_serialize_bookmarks(preferences_buf + preferences_buf_size);
518 size = preferences_buf_size - (MAX_PATH + 2);
519 preferences_buf[MAX_PATH + 0] = size >> 8;
520 preferences_buf[MAX_PATH + 1] = size;
521
522
523 /* Just overwrite preferences if possible*/
524 if ( (stored_preferences_offset > 0) && (stored_preferences_size == size) )
525 {
526 DEBUGF("Saving preferences: overwriting\n");
527 if ((tfd = rb->open(TV_SETTINGS_FILE, O_WRONLY)) < 0)
528 return false;
529 rb->lseek(tfd, stored_preferences_offset, SEEK_SET);
530 res = (rb->write(tfd, preferences_buf, preferences_buf_size) >= 0);
531 rb->close(tfd);
532 return res;
533 }
534
535
505 if (!rb->file_exists(TV_SETTINGS_FILE)) 536 if (!rb->file_exists(TV_SETTINGS_FILE))
506 tv_convert_settings_file(); 537 tv_convert_settings_file();
507 538
539
540 /* Try appending preferences */
541 if ( (stored_preferences_offset == 0) &&
542 ( (tfd = rb->open(TV_SETTINGS_FILE, O_RDWR)) >= 0) )
543 {
544 DEBUGF("Saving preferences: appending\n");
545 rb->lseek(tfd, 0, SEEK_END);
546 if (rb->write(tfd, preferences_buf, preferences_buf_size) < 0)
547 return false;
548
549 rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
550 rb->read(tfd, buf, 2);
551 fcount = (buf[0] << 8) | buf[1];
552 fcount ++;
553 buf[0] = fcount >> 8;
554 buf[1] = fcount;
555 rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
556 res = rb->write(tfd, buf, 2) >= 0;
557
558 rb->close(tfd);
559 return res;
560 }
561
508 /* create header for the temporary file */ 562 /* create header for the temporary file */
509 rb->memcpy(buf, TV_SETTINGS_HEADER, TV_SETTINGS_HEADER_SIZE - 1); 563 rb->memcpy(buf, TV_SETTINGS_HEADER, TV_SETTINGS_HEADER_SIZE - 1);
510 buf[TV_SETTINGS_HEADER_SIZE - 1] = TV_SETTINGS_VERSION; 564 buf[TV_SETTINGS_HEADER_SIZE - 1] = TV_SETTINGS_VERSION;
@@ -539,12 +593,13 @@ bool tv_save_settings(void)
539 rb->lseek(ofd, size, SEEK_CUR); 593 rb->lseek(ofd, size, SEEK_CUR);
540 else 594 else
541 { 595 {
542 if ((rb->write(tfd, buf, MAX_PATH + 2) < 0) || 596 if ((rb->read(ofd, buf + (MAX_PATH + 2), size) < 0) ||
543 (!tv_copy_settings(ofd, tfd, size))) 597 (rb->write(tfd, buf, size + MAX_PATH + 2) < 0))
544 { 598 {
545 res = false; 599 res = false;
546 break; 600 break;
547 } 601 }
602 new_fcount++;
548 } 603 }
549 } 604 }
550 } 605 }
@@ -555,31 +610,15 @@ bool tv_save_settings(void)
555 { 610 {
556 /* save to current read file's preferences and bookmarks */ 611 /* save to current read file's preferences and bookmarks */
557 res = false; 612 res = false;
558 rb->memset(buf, 0, MAX_PATH);
559 rb->strlcpy(buf, preferences->file_name, MAX_PATH);
560 613
561 if (rb->write(tfd, buf, MAX_PATH + 2) >= 0) 614 if (rb->write(tfd, preferences_buf, preferences_buf_size) >= 0)
562 { 615 {
563 if (tv_write_preferences(tfd, preferences)) 616 rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
564 {
565 size = tv_serialize_bookmarks(tfd);
566 if (size > 0)
567 {
568 size += TV_PREFERENCES_SIZE;
569 rb->lseek(tfd, -size - 2, SEEK_CUR);
570 buf[0] = size >> 8;
571 buf[1] = size;
572 if (rb->write(tfd, buf, 2) >= 0)
573 {
574 rb->lseek(tfd, TV_SETTINGS_HEADER_SIZE, SEEK_SET);
575 617
576 fcount++; 618 new_fcount++;
577 buf[0] = fcount >> 8; 619 buf[0] = new_fcount >> 8;
578 buf[1] = fcount; 620 buf[1] = new_fcount;
579 res = (rb->write(tfd, buf, 2) >= 0); 621 res = (rb->write(tfd, buf, 2) >= 0);
580 }
581 }
582 }
583 } 622 }
584 } 623 }
585 rb->close(tfd); 624 rb->close(tfd);