json.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "json.h"
  2. #include "wrapper.h"
  3. #include <library/cpp/json/json_value.h>
  4. using namespace NJson;
  5. void NLua::PushJsonValue(TLuaStateHolder* state, const TJsonValue& json) {
  6. // each recursive call will explicitly push only a single element to stack relying on subcalls to reserve stack space for themselves
  7. // I.e. for a map {"a": "b"} the first call will ensure stack space for create_table, then call PushJsonValue for the string,
  8. // this PushJsonValue will ensure stack space for the string. Thus only a single ensure_stack at the start of the function is enough.
  9. state->ensure_stack(1);
  10. switch (json.GetType()) {
  11. case JSON_UNDEFINED:
  12. ythrow yexception() << "cannot push undefined json value";
  13. case JSON_NULL:
  14. state->push_nil();
  15. break;
  16. case JSON_BOOLEAN:
  17. state->push_bool(json.GetBoolean());
  18. break;
  19. case JSON_INTEGER:
  20. state->push_number(json.GetInteger());
  21. break;
  22. case JSON_UINTEGER:
  23. state->push_number(json.GetUInteger());
  24. break;
  25. case JSON_DOUBLE:
  26. state->push_number(json.GetDouble());
  27. break;
  28. case JSON_STRING:
  29. state->push_string(json.GetString());
  30. break;
  31. case JSON_MAP:
  32. state->create_table();
  33. for (const auto& pair : json.GetMap()) {
  34. PushJsonValue(state, pair.second); // Recursive call tests for stack space on its own
  35. state->set_field(-2, pair.first.data());
  36. }
  37. break;
  38. case JSON_ARRAY: {
  39. state->create_table();
  40. int index = 1; // lua arrays start from 1
  41. for (const auto& element : json.GetArray()) {
  42. PushJsonValue(state, element); // Recursive call tests for stack space on its own, no need to double check
  43. state->rawseti(-2, index++);
  44. }
  45. break;
  46. }
  47. default:
  48. ythrow yexception() << "Unexpected json value type";
  49. }
  50. }