json.alc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 (has_value(data)):
  15. // Primitive value, so send as-is
  16. comm_set(port, "P")
  17. comm_set(port, data)
  18. else:
  19. // Is a dict or list
  20. // Problem is that we don't know which it is, as everything is a dictionary in the Modelverse...
  21. // 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!
  22. Element keys
  23. Element expected
  24. Element copy
  25. Element entry
  26. String key
  27. keys = dict_keys(data)
  28. expected = list_to_set(range(dict_len(data)))
  29. if (set_equality(keys, expected)):
  30. // Equal, so we are (most likely...) dealing with a list
  31. comm_set(port, "L")
  32. copy = list_copy(data)
  33. while (list_len(copy) > 0):
  34. entry = list_pop(copy, 0)
  35. json_send_data(port, entry)
  36. else:
  37. // Not equal, so we are surely dealing with a dict
  38. comm_set(port, "D")
  39. while (set_len(keys) > 0):
  40. key = set_pop(keys)
  41. comm_set(port, key)
  42. json_send_data(port, data[key])
  43. return!
  44. Element function process_JSON_data(port : String):
  45. String type
  46. Element result
  47. type = comm_get(port)
  48. if (type == "P"):
  49. // Primitive data type, so just return as-is
  50. result = comm_get(port)
  51. elif (type == "L"):
  52. // List, so fetch elements in turn
  53. Integer length
  54. length = comm_get(port)
  55. result = list_create()
  56. while (length > 0):
  57. list_append(result, process_JSON_data(port))
  58. length = length - 1
  59. elif (type == "D"):
  60. // Dict, so fetch elements in turn
  61. Integer length
  62. length = comm_get(port)
  63. result = dict_create()
  64. while (length > 0):
  65. dict_add(result, comm_get(port), process_JSON_data(port))
  66. length = length - 1
  67. return result!
  68. String function json_serialize(data : Element):
  69. String port
  70. String response
  71. port = json_connect()
  72. comm_set(port, "encode")
  73. response = comm_get(port)
  74. if (response == "OK"):
  75. // Send data to the service...
  76. json_send_data(port, data)
  77. response = comm_get(port)
  78. comm_close(port)
  79. return response!
  80. else:
  81. log("Error: " + response)
  82. comm_close(port)
  83. return ""!
  84. Element function json_deserialize(str : String):
  85. String port
  86. String response
  87. Element rval
  88. port = json_connect()
  89. comm_set(port, "decode")
  90. response = comm_get(port)
  91. if (response == "OK"):
  92. comm_set(port, str)
  93. rval = process_JSON_data(port)
  94. comm_close(port)
  95. return rval!
  96. else:
  97. log("Error: " + response)
  98. comm_close(port)
  99. return read_root()!