json.alc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. include "primitives.alh"
  2. include "services.alh"
  3. include "constructors.alh"
  4. include "modelling.alh"
  5. String function json_connect():
  6. String port
  7. port = ""
  8. while (port == ""):
  9. port = comm_connect("JSON")
  10. return port!
  11. Void function json_send_data(port : String, data : Element):
  12. // Send the current value to the service
  13. // First determine what it is!
  14. if (is_physical_none(data)):
  15. comm_set(port, "N")
  16. elif (has_value(data)):
  17. // Primitive value, so send as-is
  18. comm_set(port, "P")
  19. comm_set(port, data)
  20. else:
  21. // Is a dict or list
  22. // Problem is that we don't know which it is, as everything is a dictionary in the Modelverse...
  23. // We will do a simple check: if it is a dictionary with keys the contiguous range of integers from 0 to length - 1, it is a list!
  24. Element keys
  25. Element expected
  26. Element copy
  27. Element entry
  28. Element key
  29. keys = dict_keys(data)
  30. expected = list_to_set(range(dict_len(data)))
  31. if (set_equality(keys, expected)):
  32. // Equal, so we are (most likely...) dealing with a list
  33. comm_set(port, "L")
  34. comm_set(port, list_len(data))
  35. copy = list_copy(data)
  36. while (list_len(copy) > 0):
  37. entry = list_pop(copy, 0)
  38. json_send_data(port, entry)
  39. else:
  40. // Not equal, so we are surely dealing with a dict
  41. comm_set(port, "D")
  42. comm_set(port, dict_len(data))
  43. while (set_len(keys) > 0):
  44. key = set_pop(keys)
  45. comm_set(port, key)
  46. json_send_data(port, data[key])
  47. return!
  48. Element function process_JSON_data(port : String):
  49. String type
  50. Element result
  51. type = comm_get(port)
  52. if (type == "P"):
  53. // Primitive data type, so just return as-is
  54. result = comm_get(port)
  55. elif (type == "N"):
  56. result = !none
  57. elif (type == "L"):
  58. // List, so fetch elements in turn
  59. Integer length
  60. length = comm_get(port)
  61. result = list_create()
  62. while (length > 0):
  63. list_append(result, process_JSON_data(port))
  64. length = length - 1
  65. elif (type == "D"):
  66. // Dict, so fetch elements in turn
  67. Integer length
  68. length = comm_get(port)
  69. result = dict_create()
  70. while (length > 0):
  71. dict_add(result, comm_get(port), process_JSON_data(port))
  72. length = length - 1
  73. return result!
  74. String function json_serialize(data : Element):
  75. String port
  76. String response
  77. port = json_connect()
  78. comm_set(port, "encode")
  79. response = comm_get(port)
  80. if (response == "OK"):
  81. // Send data to the service...
  82. json_send_data(port, data)
  83. response = comm_get(port)
  84. comm_close(port)
  85. return response!
  86. else:
  87. log("Error: " + response)
  88. comm_close(port)
  89. return ""!
  90. Element function json_deserialize(str : String):
  91. String port
  92. String response
  93. Element rval
  94. port = json_connect()
  95. comm_set(port, "decode")
  96. response = comm_get(port)
  97. if (response == "OK"):
  98. comm_set(port, str)
  99. rval = process_JSON_data(port)
  100. comm_close(port)
  101. return rval!
  102. else:
  103. log("Error: " + response)
  104. comm_close(port)
  105. return read_root()!