| 236 | } |
| 237 | |
| 238 | static void deserializeImpl( |
| 239 | lua_State* lua, std::string_view& binaryData, const UserdataSerializer* customSerializer, bool readOnly) |
| 240 | { |
| 241 | if (binaryData.empty()) |
| 242 | throw std::runtime_error("Unexpected end of serialized data."); |
| 243 | unsigned char type = binaryData[0]; |
| 244 | binaryData = binaryData.substr(1); |
| 245 | if (type & (CUSTOM_COMPACT_FLAG | CUSTOM_FULL_FLAG)) |
| 246 | { |
| 247 | size_t typeNameSize, dataSize; |
| 248 | if (type & CUSTOM_COMPACT_FLAG) |
| 249 | { // Compact form: 0b1SSSSTTT. SSSS = dataSize, TTT = (typeName size - 1). |
| 250 | typeNameSize = (type & 7) + 1; |
| 251 | dataSize = (type >> 3) & 15; |
| 252 | } |
| 253 | else |
| 254 | { // Full form: 0b01TTTTTT + 32bit dataSize. |
| 255 | typeNameSize = (type & 63) + 1; |
| 256 | dataSize = getValue<uint32_t>(binaryData); |
| 257 | } |
| 258 | std::string_view typeName = binaryData.substr(0, typeNameSize); |
| 259 | std::string_view data = binaryData.substr(typeNameSize, dataSize); |
| 260 | binaryData = binaryData.substr(typeNameSize + dataSize); |
| 261 | if (!customSerializer || !customSerializer->deserialize(typeName, data, lua)) |
| 262 | throw std::runtime_error("Unknown type in serialized data: " + std::string(typeName)); |
| 263 | return; |
| 264 | } |
| 265 | if (type & SHORT_STRING_FLAG) |
| 266 | { |
| 267 | size_t size = type & 0x1f; |
| 268 | sol::stack::push<std::string_view>(lua, binaryData.substr(0, size)); |
| 269 | binaryData = binaryData.substr(size); |
| 270 | return; |
| 271 | } |
| 272 | switch (static_cast<SerializedType>(type)) |
| 273 | { |
| 274 | case SerializedType::NUMBER: |
| 275 | sol::stack::push<double>(lua, getValue<double>(binaryData)); |
| 276 | return; |
| 277 | case SerializedType::BOOLEAN: |
| 278 | sol::stack::push<bool>(lua, getValue<char>(binaryData) != 0); |
| 279 | return; |
| 280 | case SerializedType::LONG_STRING: |
| 281 | { |
| 282 | uint32_t size = getValue<uint32_t>(binaryData); |
| 283 | sol::stack::push<std::string_view>(lua, binaryData.substr(0, size)); |
| 284 | binaryData = binaryData.substr(size); |
| 285 | return; |
| 286 | } |
| 287 | case SerializedType::TABLE_START: |
| 288 | { |
| 289 | lua_createtable(lua, 0, 0); |
| 290 | while (!binaryData.empty() && binaryData[0] != char(SerializedType::TABLE_END)) |
| 291 | { |
| 292 | deserializeImpl(lua, binaryData, customSerializer, readOnly); |
| 293 | deserializeImpl(lua, binaryData, customSerializer, readOnly); |
| 294 | lua_settable(lua, -3); |
| 295 | } |
no test coverage detected