include "primitives.alh" include "services.alh" include "constructors.alh" include "modelling.alh" String function json_connect(): String port port = "" while (port == ""): port = comm_connect("JSON") return port! Void function json_send_data(port : String, data : Element): // Send the current value to the service // First determine what it is! if (is_physical_none(data)): comm_set(port, "N") elif (has_value(data)): // Primitive value, so send as-is comm_set(port, "P") comm_set(port, data) else: // Is a dict or list // Problem is that we don't know which it is, as everything is a dictionary in the Modelverse... // 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! Element keys Element expected Element copy Element entry Element key keys = dict_keys(data) expected = list_to_set(range(dict_len(data))) if (set_equality(keys, expected)): // Equal, so we are (most likely...) dealing with a list comm_set(port, "L") comm_set(port, list_len(data)) copy = list_copy(data) while (list_len(copy) > 0): entry = list_pop(copy, 0) json_send_data(port, entry) else: // Not equal, so we are surely dealing with a dict comm_set(port, "D") comm_set(port, dict_len(data)) while (set_len(keys) > 0): key = set_pop(keys) comm_set(port, key) json_send_data(port, data[key]) return! Element function process_JSON_data(port : String): String type Element result type = comm_get(port) if (type == "P"): // Primitive data type, so just return as-is result = comm_get(port) elif (type == "N"): result = !none elif (type == "L"): // List, so fetch elements in turn Integer length length = comm_get(port) result = list_create() while (length > 0): list_append(result, process_JSON_data(port)) length = length - 1 elif (type == "D"): // Dict, so fetch elements in turn Integer length length = comm_get(port) result = dict_create() while (length > 0): dict_add(result, comm_get(port), process_JSON_data(port)) length = length - 1 return result! String function json_serialize(data : Element): String port String response port = json_connect() comm_set(port, "encode") response = comm_get(port) if (response == "OK"): // Send data to the service... json_send_data(port, data) response = comm_get(port) comm_close(port) return response! else: log("Error: " + response) comm_close(port) return ""! Element function json_deserialize(str : String): String port String response Element rval port = json_connect() comm_set(port, "decode") response = comm_get(port) if (response == "OK"): comm_set(port, str) rval = process_JSON_data(port) comm_close(port) return rval! else: log("Error: " + response) comm_close(port) return read_root()!