| 1752 | |
| 1753 | |
| 1754 | static int str_unpack (lua_State *L) { |
| 1755 | Header h; |
| 1756 | const char *fmt = luaL_checkstring(L, 1); |
| 1757 | size_t ld; |
| 1758 | const char *data = luaL_checklstring(L, 2, &ld); |
| 1759 | size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1; |
| 1760 | int n = 0; /* number of results */ |
| 1761 | luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); |
| 1762 | initheader(L, &h); |
| 1763 | while (*fmt != '\0') { |
| 1764 | int size, ntoalign; |
| 1765 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); |
| 1766 | luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, |
| 1767 | "data string too short"); |
| 1768 | pos += ntoalign; /* skip alignment */ |
| 1769 | /* stack space for item + next position */ |
| 1770 | luaL_checkstack(L, 2, "too many results"); |
| 1771 | n++; |
| 1772 | switch (opt) { |
| 1773 | case Kint: |
| 1774 | case Kuint: { |
| 1775 | lua_Integer res = unpackint(L, data + pos, h.islittle, size, |
| 1776 | (opt == Kint)); |
| 1777 | lua_pushinteger(L, res); |
| 1778 | break; |
| 1779 | } |
| 1780 | case Kfloat: { |
| 1781 | float f; |
| 1782 | copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); |
| 1783 | lua_pushnumber(L, (lua_Number)f); |
| 1784 | break; |
| 1785 | } |
| 1786 | case Knumber: { |
| 1787 | lua_Number f; |
| 1788 | copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); |
| 1789 | lua_pushnumber(L, f); |
| 1790 | break; |
| 1791 | } |
| 1792 | case Kdouble: { |
| 1793 | double f; |
| 1794 | copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); |
| 1795 | lua_pushnumber(L, (lua_Number)f); |
| 1796 | break; |
| 1797 | } |
| 1798 | case Kchar: { |
| 1799 | lua_pushlstring(L, data + pos, size); |
| 1800 | break; |
| 1801 | } |
| 1802 | case Kstring: { |
| 1803 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); |
| 1804 | luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); |
| 1805 | lua_pushlstring(L, data + pos + size, len); |
| 1806 | pos += len; /* skip string */ |
| 1807 | break; |
| 1808 | } |
| 1809 | case Kzstr: { |
| 1810 | size_t len = strlen(data + pos); |
| 1811 | luaL_argcheck(L, pos + len < ld, 2, |
nothing calls this directly
no test coverage detected