| 1770 | |
| 1771 | |
| 1772 | static int str_unpack (lua_State *L) { |
| 1773 | Header h; |
| 1774 | const char *fmt = luaL_checkstring(L, 1); |
| 1775 | size_t ld; |
| 1776 | const char *data = luaL_checklstring(L, 2, &ld); |
| 1777 | size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1; |
| 1778 | int n = 0; /* number of results */ |
| 1779 | luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); |
| 1780 | initheader(L, &h); |
| 1781 | while (*fmt != '\0') { |
| 1782 | unsigned ntoalign; |
| 1783 | size_t size; |
| 1784 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); |
| 1785 | luaL_argcheck(L, ntoalign + size <= ld - pos, 2, |
| 1786 | "data string too short"); |
| 1787 | pos += ntoalign; /* skip alignment */ |
| 1788 | /* stack space for item + next position */ |
| 1789 | luaL_checkstack(L, 2, "too many results"); |
| 1790 | n++; |
| 1791 | switch (opt) { |
| 1792 | case Kint: |
| 1793 | case Kuint: { |
| 1794 | lua_Integer res = unpackint(L, data + pos, h.islittle, |
| 1795 | cast_int(size), (opt == Kint)); |
| 1796 | lua_pushinteger(L, res); |
| 1797 | break; |
| 1798 | } |
| 1799 | case Kfloat: { |
| 1800 | float f; |
| 1801 | copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); |
| 1802 | lua_pushnumber(L, (lua_Number)f); |
| 1803 | break; |
| 1804 | } |
| 1805 | case Knumber: { |
| 1806 | lua_Number f; |
| 1807 | copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); |
| 1808 | lua_pushnumber(L, f); |
| 1809 | break; |
| 1810 | } |
| 1811 | case Kdouble: { |
| 1812 | double f; |
| 1813 | copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); |
| 1814 | lua_pushnumber(L, (lua_Number)f); |
| 1815 | break; |
| 1816 | } |
| 1817 | case Kchar: { |
| 1818 | lua_pushlstring(L, data + pos, size); |
| 1819 | break; |
| 1820 | } |
| 1821 | case Kstring: { |
| 1822 | lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos, |
| 1823 | h.islittle, cast_int(size), 0); |
| 1824 | luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); |
| 1825 | lua_pushlstring(L, data + pos + size, cast_sizet(len)); |
| 1826 | pos += cast_sizet(len); /* skip string */ |
| 1827 | break; |
| 1828 | } |
| 1829 | case Kzstr: { |
nothing calls this directly
no test coverage detected