| 1542 | |
| 1543 | |
| 1544 | static int str_pack (lua_State *L) { |
| 1545 | luaL_Buffer b; |
| 1546 | Header h; |
| 1547 | const char *fmt = luaL_checkstring(L, 1); /* format string */ |
| 1548 | int arg = 1; /* current argument to pack */ |
| 1549 | size_t totalsize = 0; /* accumulate total size of result */ |
| 1550 | initheader(L, &h); |
| 1551 | lua_pushnil(L); /* mark to separate arguments from string buffer */ |
| 1552 | luaL_buffinit(L, &b); |
| 1553 | while (*fmt != '\0') { |
| 1554 | int size, ntoalign; |
| 1555 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); |
| 1556 | totalsize += ntoalign + size; |
| 1557 | while (ntoalign-- > 0) |
| 1558 | luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ |
| 1559 | arg++; |
| 1560 | switch (opt) { |
| 1561 | case Kint: { /* signed integers */ |
| 1562 | lua_Integer n = luaL_checkinteger(L, arg); |
| 1563 | if (size < SZINT) { /* need overflow check? */ |
| 1564 | lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); |
| 1565 | luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); |
| 1566 | } |
| 1567 | packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); |
| 1568 | break; |
| 1569 | } |
| 1570 | case Kuint: { /* unsigned integers */ |
| 1571 | lua_Integer n = luaL_checkinteger(L, arg); |
| 1572 | if (size < SZINT) /* need overflow check? */ |
| 1573 | luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), |
| 1574 | arg, "unsigned overflow"); |
| 1575 | packint(&b, (lua_Unsigned)n, h.islittle, size, 0); |
| 1576 | break; |
| 1577 | } |
| 1578 | case Kfloat: { /* C float */ |
| 1579 | float f = (float)luaL_checknumber(L, arg); /* get argument */ |
| 1580 | char *buff = luaL_prepbuffsize(&b, sizeof(f)); |
| 1581 | /* move 'f' to final result, correcting endianness if needed */ |
| 1582 | copywithendian(buff, (char *)&f, sizeof(f), h.islittle); |
| 1583 | luaL_addsize(&b, size); |
| 1584 | break; |
| 1585 | } |
| 1586 | case Knumber: { /* Lua float */ |
| 1587 | lua_Number f = luaL_checknumber(L, arg); /* get argument */ |
| 1588 | char *buff = luaL_prepbuffsize(&b, sizeof(f)); |
| 1589 | /* move 'f' to final result, correcting endianness if needed */ |
| 1590 | copywithendian(buff, (char *)&f, sizeof(f), h.islittle); |
| 1591 | luaL_addsize(&b, size); |
| 1592 | break; |
| 1593 | } |
| 1594 | case Kdouble: { /* C double */ |
| 1595 | double f = (double)luaL_checknumber(L, arg); /* get argument */ |
| 1596 | char *buff = luaL_prepbuffsize(&b, sizeof(f)); |
| 1597 | /* move 'f' to final result, correcting endianness if needed */ |
| 1598 | copywithendian(buff, (char *)&f, sizeof(f), h.islittle); |
| 1599 | luaL_addsize(&b, size); |
| 1600 | break; |
| 1601 | } |
nothing calls this directly
no test coverage detected