| 1474 | |
| 1475 | |
| 1476 | static int str_unpack (lua_State *L) { |
| 1477 | Header h; |
| 1478 | const char *fmt = luaL_checkstring(L, 1); |
| 1479 | size_t ld; |
| 1480 | const char *data = luaL_checklstring(L, 2, &ld); |
| 1481 | size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; |
| 1482 | int n = 0; /* number of results */ |
| 1483 | luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); |
| 1484 | initheader(L, &h); |
| 1485 | while (*fmt != '\0') { |
| 1486 | int size, ntoalign; |
| 1487 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); |
| 1488 | if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) |
| 1489 | luaL_argerror(L, 2, "data string too short"); |
| 1490 | pos += ntoalign; /* skip alignment */ |
| 1491 | /* stack space for item + next position */ |
| 1492 | luaL_checkstack(L, 2, "too many results"); |
| 1493 | n++; |
| 1494 | switch (opt) { |
| 1495 | case Kint: |
| 1496 | case Kuint: { |
| 1497 | lua_Integer res = unpackint(L, data + pos, h.islittle, size, |
| 1498 | (opt == Kint)); |
| 1499 | lua_pushinteger(L, res); |
| 1500 | break; |
| 1501 | } |
| 1502 | case Kfloat: { |
| 1503 | volatile Ftypes u; |
| 1504 | lua_Number num; |
| 1505 | copywithendian(u.buff, data + pos, size, h.islittle); |
| 1506 | if (size == sizeof(u.f)) num = (lua_Number)u.f; |
| 1507 | else if (size == sizeof(u.d)) num = (lua_Number)u.d; |
| 1508 | else num = u.n; |
| 1509 | lua_pushnumber(L, num); |
| 1510 | break; |
| 1511 | } |
| 1512 | case Kchar: { |
| 1513 | lua_pushlstring(L, data + pos, size); |
| 1514 | break; |
| 1515 | } |
| 1516 | case Kstring: { |
| 1517 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); |
| 1518 | luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); |
| 1519 | lua_pushlstring(L, data + pos + size, len); |
| 1520 | pos += len; /* skip string */ |
| 1521 | break; |
| 1522 | } |
| 1523 | case Kzstr: { |
| 1524 | size_t len = (int)strlen(data + pos); |
| 1525 | lua_pushlstring(L, data + pos, len); |
| 1526 | pos += len + 1; /* skip string plus final '\0' */ |
| 1527 | break; |
| 1528 | } |
| 1529 | case Kpaddalign: case Kpadding: case Knop: |
| 1530 | n--; /* undo increment */ |
| 1531 | break; |
| 1532 | } |
| 1533 | pos += size; |
nothing calls this directly
no test coverage detected