| 1599 | |
| 1600 | |
| 1601 | static int str_pack (lua_State *L) { |
| 1602 | luaL_Buffer b; |
| 1603 | Header h; |
| 1604 | const char *fmt = luaL_checkstring(L, 1); /* format string */ |
| 1605 | int arg = 1; /* current argument to pack */ |
| 1606 | size_t totalsize = 0; /* accumulate total size of result */ |
| 1607 | initheader(L, &h); |
| 1608 | lua_pushnil(L); /* mark to separate arguments from string buffer */ |
| 1609 | luaL_buffinit(L, &b); |
| 1610 | while (*fmt != '\0') { |
| 1611 | int size, ntoalign; |
| 1612 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); |
| 1613 | totalsize += ntoalign + size; |
| 1614 | while (ntoalign-- > 0) |
| 1615 | luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ |
| 1616 | arg++; |
| 1617 | switch (opt) { |
| 1618 | case Kint: { /* signed integers */ |
| 1619 | lua_Integer n = luaL_checkinteger(L, arg); |
| 1620 | if (size < SZINT) { /* need overflow check? */ |
| 1621 | lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); |
| 1622 | luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); |
| 1623 | } |
| 1624 | packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); |
| 1625 | break; |
| 1626 | } |
| 1627 | case Kuint: { /* unsigned integers */ |
| 1628 | lua_Integer n = luaL_checkinteger(L, arg); |
| 1629 | if (size < SZINT) /* need overflow check? */ |
| 1630 | luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), |
| 1631 | arg, "unsigned overflow"); |
| 1632 | packint(&b, (lua_Unsigned)n, h.islittle, size, 0); |
| 1633 | break; |
| 1634 | } |
| 1635 | case Kfloat: { /* C float */ |
| 1636 | float f = (float)luaL_checknumber(L, arg); /* get argument */ |
| 1637 | char *buff = luaL_prepbuffsize(&b, sizeof(f)); |
| 1638 | /* move 'f' to final result, correcting endianness if needed */ |
| 1639 | copywithendian(buff, (char *)&f, sizeof(f), h.islittle); |
| 1640 | luaL_addsize(&b, size); |
| 1641 | break; |
| 1642 | } |
| 1643 | case Knumber: { /* Lua float */ |
| 1644 | lua_Number f = luaL_checknumber(L, arg); /* get argument */ |
| 1645 | char *buff = luaL_prepbuffsize(&b, sizeof(f)); |
| 1646 | /* move 'f' to final result, correcting endianness if needed */ |
| 1647 | copywithendian(buff, (char *)&f, sizeof(f), h.islittle); |
| 1648 | luaL_addsize(&b, size); |
| 1649 | break; |
| 1650 | } |
| 1651 | case Kdouble: { /* C double */ |
| 1652 | double f = (double)luaL_checknumber(L, arg); /* get argument */ |
| 1653 | char *buff = luaL_prepbuffsize(&b, sizeof(f)); |
| 1654 | /* move 'f' to final result, correcting endianness if needed */ |
| 1655 | copywithendian(buff, (char *)&f, sizeof(f), h.islittle); |
| 1656 | luaL_addsize(&b, size); |
| 1657 | break; |
| 1658 | } |
nothing calls this directly
no test coverage detected