+class UUID:
+ x = "[0-9a-fA-f]"
+ uuidRE = re.compile("^(%s{8})-(%s{4})-(%s{4})-(%s{4})-(%s{4})(%s{8})$"
+ % (x, x, x, x, x, x))
+
+ def __init__(self, value):
+ self.value = value
+
+ @staticmethod
+ def fromString(s):
+ if not uuidRE.match(s):
+ raise Error("%s is not a valid UUID" % s)
+ return UUID(s)
+
+ @staticmethod
+ def fromJson(json):
+ if UUID.isValidJson(json):
+ return UUID(json[1])
+ else:
+ raise Error("%s is not valid JSON for a UUID" % json)
+
+ @staticmethod
+ def isValidJson(json):
+ return len(json) == 2 and json[0] == "uuid" and uuidRE.match(json[1])
+
+ def toJson(self):
+ return ["uuid", self.value]
+
+ def cInitUUID(self, var):
+ m = re.match(self.value)
+ return ["%s.parts[0] = 0x%s;" % (var, m.group(1)),
+ "%s.parts[1] = 0x%s%s;" % (var, m.group(2), m.group(3)),
+ "%s.parts[2] = 0x%s%s;" % (var, m.group(4), m.group(5)),
+ "%s.parts[3] = 0x%s;" % (var, m.group(6))]
+
+class Atom:
+ def __init__(self, type, value):
+ self.type = type
+ self.value = value
+
+ @staticmethod
+ def fromJson(type_, json):
+ if ((type_ == 'integer' and type(json) in [int, long])
+ or (type_ == 'real' and type(json) in [int, long, float])
+ or (type_ == 'boolean' and json in [True, False])
+ or (type_ == 'string' and type(json) in [str, unicode])):
+ return Atom(type_, json)
+ elif type_ == 'uuid':
+ return UUID.fromJson(json)
+ else:
+ raise Error("%s is not valid JSON for type %s" % (json, type_))
+
+ def toJson(self):
+ if self.type == 'uuid':
+ return self.value.toString()
+ else:
+ return self.value
+
+ def cInitAtom(self, var):
+ if self.type == 'integer':
+ return ['%s.integer = %d;' % (var, self.value)]
+ elif self.type == 'real':
+ return ['%s.real = %.15g;' % (var, self.value)]
+ elif self.type == 'boolean':
+ if self.value:
+ return ['%s.boolean = true;']
+ else:
+ return ['%s.boolean = false;']
+ elif self.type == 'string':
+ return ['%s.string = xstrdup("%s");'
+ % (var, escapeCString(self.value))]
+ elif self.type == 'uuid':
+ return self.value.cInitUUID(var)
+