diff options
Diffstat (limited to 'apps/plugins/lua/rocklib.c')
-rw-r--r-- | apps/plugins/lua/rocklib.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c index a6a23f3381..6c96f37a94 100644 --- a/apps/plugins/lua/rocklib.c +++ b/apps/plugins/lua/rocklib.c | |||
@@ -564,6 +564,137 @@ RB_WRAP(strncasecmp) | |||
564 | return 1; | 564 | return 1; |
565 | } | 565 | } |
566 | 566 | ||
567 | static int mem_read_write(lua_State *L, uintptr_t address, size_t maxsize) | ||
568 | { | ||
569 | intptr_t offset = (intptr_t) luaL_optint(L, 1, 0); | ||
570 | size_t size = (size_t) luaL_optint(L, 2, maxsize); | ||
571 | size_t written; | ||
572 | int type = lua_type(L, 3); | ||
573 | |||
574 | if(offset < 0) | ||
575 | { | ||
576 | /* allows pointer within structure to be calculated offset */ | ||
577 | offset = -(address + offset); | ||
578 | size = (size_t) maxsize - offset; | ||
579 | } | ||
580 | |||
581 | luaL_argcheck(L, ((uintptr_t) offset) + size <= maxsize, 2, ERR_IDX_RANGE); | ||
582 | |||
583 | char *mem = (char*) address + ((uintptr_t) offset); | ||
584 | const void *value = NULL; | ||
585 | |||
586 | lua_Integer var_luaint; | ||
587 | #ifdef UINT64_MAX | ||
588 | int64_t var_64; | ||
589 | #endif | ||
590 | int32_t var_32; | ||
591 | int16_t var_16; | ||
592 | int8_t var_8; | ||
593 | bool var_bool; | ||
594 | |||
595 | switch(type) | ||
596 | { | ||
597 | case LUA_TSTRING: | ||
598 | { | ||
599 | size_t len; | ||
600 | const char* str = lua_tolstring (L, 3, &len); | ||
601 | |||
602 | luaL_argcheck(L, len + 1 <= size, 3, ERR_DATA_OVF); | ||
603 | size = len + 1; /* include \0 */ | ||
604 | value = str; | ||
605 | break; | ||
606 | } | ||
607 | case LUA_TBOOLEAN: | ||
608 | { | ||
609 | var_bool = (bool) lua_toboolean(L, 3); | ||
610 | value = &var_bool; | ||
611 | break; | ||
612 | } | ||
613 | case LUA_TNUMBER: | ||
614 | { | ||
615 | var_luaint = lua_tointeger(L, 3); | ||
616 | switch(size) | ||
617 | { | ||
618 | case sizeof(var_8): | ||
619 | var_8 = (int8_t) var_luaint; | ||
620 | value = &var_8; | ||
621 | break; | ||
622 | case sizeof(var_16): | ||
623 | var_16 = (int16_t) var_luaint; | ||
624 | value = &var_16; | ||
625 | break; | ||
626 | case sizeof(var_32): | ||
627 | var_32 = (int32_t) var_luaint; | ||
628 | value = &var_32; | ||
629 | break; | ||
630 | #ifdef UINT64_MAX | ||
631 | case sizeof(var_64): | ||
632 | var_64 = (int64_t) var_luaint; | ||
633 | value = &var_64; | ||
634 | break; | ||
635 | #endif | ||
636 | } /* switch size */ | ||
637 | break; | ||
638 | } | ||
639 | case LUA_TNIL: | ||
640 | case LUA_TNONE: /* reader */ | ||
641 | { | ||
642 | luaL_Buffer b; | ||
643 | luaL_buffinit(L, &b); | ||
644 | while(size > 0) | ||
645 | { | ||
646 | written = MIN(LUAL_BUFFERSIZE, size); | ||
647 | luaL_addlstring (&b, mem, written); | ||
648 | mem += written; | ||
649 | size -= written; | ||
650 | } | ||
651 | |||
652 | luaL_pushresult(&b); | ||
653 | return 1; | ||
654 | } | ||
655 | |||
656 | default: | ||
657 | break; | ||
658 | } /* switch type */ | ||
659 | |||
660 | /* writer */ | ||
661 | luaL_argcheck(L, value != NULL, 3, "Unknown Type"); | ||
662 | rb->memcpy(mem, value, size); | ||
663 | lua_pushinteger(L, 1); | ||
664 | |||
665 | return 1; | ||
666 | } | ||
667 | |||
668 | RB_WRAP(global_status) | ||
669 | { | ||
670 | const uintptr_t address = (uintptr_t) rb->global_status; | ||
671 | const size_t maxsize = sizeof(struct system_status); | ||
672 | return mem_read_write(L, address, maxsize); | ||
673 | } | ||
674 | |||
675 | RB_WRAP(global_settings) | ||
676 | { | ||
677 | const uintptr_t address = (uintptr_t) rb->global_settings; | ||
678 | const size_t maxsize = sizeof(struct user_settings); | ||
679 | return mem_read_write(L, address, maxsize); | ||
680 | } | ||
681 | |||
682 | RB_WRAP(audio_next_track) | ||
683 | { | ||
684 | lua_settop(L, 2); /* no writes allowed */ | ||
685 | const uintptr_t address = (uintptr_t) rb->audio_next_track(); | ||
686 | const size_t maxsize = sizeof(struct mp3entry); | ||
687 | return mem_read_write(L, address, maxsize); | ||
688 | } | ||
689 | |||
690 | RB_WRAP(audio_current_track) | ||
691 | { | ||
692 | lua_settop(L, 2); /* no writes allowed */ | ||
693 | const uintptr_t address = (uintptr_t) rb->audio_current_track(); | ||
694 | const size_t maxsize = sizeof(struct mp3entry); | ||
695 | return mem_read_write(L, address, maxsize); | ||
696 | } | ||
697 | |||
567 | #define RB_FUNC(func) {#func, rock_##func} | 698 | #define RB_FUNC(func) {#func, rock_##func} |
568 | #define RB_ALIAS(name, func) {name, rock_##func} | 699 | #define RB_ALIAS(name, func) {name, rock_##func} |
569 | static const luaL_Reg rocklib[] = | 700 | static const luaL_Reg rocklib[] = |
@@ -625,6 +756,12 @@ static const luaL_Reg rocklib[] = | |||
625 | RB_FUNC(utf8encode), | 756 | RB_FUNC(utf8encode), |
626 | RB_FUNC(strncasecmp), | 757 | RB_FUNC(strncasecmp), |
627 | 758 | ||
759 | /* ROCKBOX SETTINGS / INFO */ | ||
760 | RB_FUNC(global_status), | ||
761 | RB_FUNC(global_settings), | ||
762 | RB_FUNC(audio_next_track), | ||
763 | RB_FUNC(audio_current_track), | ||
764 | |||
628 | {NULL, NULL} | 765 | {NULL, NULL} |
629 | }; | 766 | }; |
630 | #undef RB_FUNC | 767 | #undef RB_FUNC |