diff options
author | Guido van Rossum <guido@python.org> | 1995-01-30 11:53:55 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1995-01-30 11:53:55 (GMT) |
commit | 17448e24081eb713ac00d7bcb681f4f0d8abfcbf (patch) | |
tree | 4f9d6768ef326173e1141b1a92af63247a42b13a /Mac/Lib/toolbox/aetools.py | |
parent | 80ffd6683ca7b06ed743c629459b06b07defbfb3 (diff) | |
download | cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.zip cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.tar.gz cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.tar.bz2 |
Committed a more or less working version.
Diffstat (limited to 'Mac/Lib/toolbox/aetools.py')
-rw-r--r-- | Mac/Lib/toolbox/aetools.py | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/Mac/Lib/toolbox/aetools.py b/Mac/Lib/toolbox/aetools.py new file mode 100644 index 0000000..745bce7 --- /dev/null +++ b/Mac/Lib/toolbox/aetools.py @@ -0,0 +1,296 @@ +import struct +import types +import AE +import MacOS +import StringIO + +AEDescType = type(AE.AECreateDesc('TEXT', '')) + +def pack(x): + if x == None: + return AE.AECreateDesc('null', '') + t = type(x) + if t == AEDescType: + return x + if t == types.IntType: + return AE.AECreateDesc('long', struct.pack('l', x)) + if t == types.FloatType: + return AE.AECreateDesc('exte', struct.pack('d', x)[2:]) + if t == types.StringType: + return AE.AECreateDesc('TEXT', x) + if t == types.ListType: + list = AE.AECreateList('', 0) + for item in x: + list.AEPutDesc(0, pack(item)) + return list + if t == types.TupleType: + t, d = x + return AE.AECreateDesc(t, d) + if t == types.DictionaryType: + record = AE.AECreateList('', 1) + for key, value in x.items(): + record.AEPutKeyDesc(key, pack(value)) + if t == types.InstanceType and hasattr(x, '__aepack__'): + return x.__aepack__() + return AE.AECreateDesc('TEXT', repr(x)) # Copout + +def unpack(desc): + t = desc.type + if t == 'TEXT': + return desc.data + if t == 'fals': + return 0 + if t == 'true': + return 1 + if t == 'long': + return struct.unpack('l', desc.data)[0] + if t == 'shor': + return struct.unpack('h', desc.data)[0] + if t == 'sing': + return struct.unpack('f', desc.data)[0] + if t == 'exte': + data = desc.data + return struct.unpack('d', data[:2] + data)[0] + if t in ('doub', 'comp', 'magn'): + return unpack(desc.AECoerceDesc('exte')) + if t == 'enum': + return ('enum', desc.data) + if t == 'null': + return None + if t == 'list': + l = [] + for i in range(desc.AECountItems()): + keyword, item = desc.AEGetNthDesc(i+1, '****') + l.append(unpack(item)) + return l + if t == 'reco': + d = {} + for i in range(desc.AECountItems()): + keyword, item = desc.AEGetNthDesc(i+1, '****') + d[keyword] = unpack(item) + return d + if t == 'obj ': + return unpackobject(desc.data) + return desc.type, desc.data # Copout + +class Object: + def __init__(self, dict = {}): + self.dict = dict + for key, value in dict.items(): + self.dict[key] = value + def __repr__(self): + return "Object(%s)" % `self.dict` + def __str__(self): + want = self.dict['want'] + form = self.dict['form'] + seld = self.dict['seld'] + s = "%s %s %s" % (nicewant(want), niceform(form), niceseld(seld)) + fr = self.dict['from'] + if fr: + s = s + " of " + str(fr) + return s + def __aepack__(self): + f = StringIO.StringIO() + putlong(f, len(self.dict)) + putlong(f, 0) + for key, value in self.dict.items(): + putcode(f, key) + desc = pack(value) + putcode(f, desc.type) + data = desc.data + putlong(f, len(data)) + f.write(data) + return AE.AECreateDesc('obj ', f.getvalue()) + +def nicewant(want): + if type(want) == types.TupleType and len(want) == 2: + return reallynicewant(want) + else: + return `want` + +def reallynicewant((t, w)): + if t != 'type': return `t, w` + # These should be taken from the "elements" of the 'aete' resource + if w == 'cins': return 'insertion point' + if w == 'cha ': return 'character' + if w == 'word': return 'word' + if w == 'para': return 'paragraph' + if w == 'ccel': return 'cell' + if w == 'ccol': return 'column' + if w == 'crow': return 'row' + if w == 'crng': return 'range' + if w == 'wind': return 'window' + if w == 'docu': return 'document' + return `w` + +def niceform(form): + if type(form) == types.TupleType and len(form) == 2: + return reallyniceform(form) + else: + return `form` + +def reallyniceform((t, f)): + if t <> 'enum': return `t, f` + if f == 'indx': return '' + if f == 'name': return '' + if f == 'rele': return '' + return `f` + +def niceseld(seld): + if type(seld) == types.TupleType and len(seld) == 2: + return reallyniceseld(seld) + else: + return `seld` + +def reallyniceseld((t, s)): + if t == 'long': return `s` + if t == 'TEXT': return `s` + if t == 'enum': + if s == 'next': return 'after' + if s == 'prev': return 'before' + return `t, s` + +def unpackobject(data): + f = StringIO.StringIO(data) + nkey = getlong(f) + dumm = getlong(f) + dict = {} + for i in range(nkey): + keyw = getcode(f) + type = getcode(f) + size = getlong(f) + if size: + data = f.read(size) + else: + data = '' + desc = AE.AECreateDesc(type, data) + dict[keyw] = unpack(desc) + return Object(dict) + + +# --- get various data types from a "file" + +def getword(f, *args): + getalgn(f) + s = f.read(2) + if len(s) < 2: + raise EOFError, 'in getword' + str(args) + return (ord(s[0])<<8) | ord(s[1]) + +def getlong(f, *args): + getalgn(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getlong' + str(args) + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def getcode(f, *args): + getalgn(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getcode' + str(args) + return s + +def getpstr(f, *args): + c = f.read(1) + if len(c) < 1: + raise EOFError, 'in getpstr[1]' + str(args) + nbytes = ord(c) + if nbytes == 0: return '' + s = f.read(nbytes) + if len(s) < nbytes: + raise EOFError, 'in getpstr[2]' + str(args) + return s + +def getalgn(f): + if f.tell() & 1: + c = f.read(1) + ##if c <> '\0': + ## print 'align:', `c` + +# ---- end get routines + + +# ---- put various data types to a "file" + +def putlong(f, value): + putalgn(f) + f.write(chr((value>>24)&0xff)) + f.write(chr((value>>16)&0xff)) + f.write(chr((value>>8)&0xff)) + f.write(chr(value&0xff)) + +def putword(f, value): + putalgn(f) + f.write(chr((value>>8)&0xff)) + f.write(chr(value&0xff)) + +def putcode(f, value): + if type(value) != types.StringType or len(value) != 4: + raise TypeError, "ostype must be 4-char string" + putalgn(f) + f.write(value) + +def putpstr(f, value): + if type(value) != types.StringType or len(value) > 255: + raise TypeError, "pstr must be string <= 255 chars" + f.write(chr(len(value)) + value) + +def putalgn(f): + if f.tell() & 1: + f.write('\0') + +# ---- end put routines + + +aekeywords = [ + 'tran', + 'rtid', + 'evcl', + 'evid', + 'addr', + 'optk', + 'timo', + 'inte', # this attribute is read only - will be set in AESend + 'esrc', # this attribute is read only + 'miss', # this attribute is read only + 'from' # new in 1.0.1 +] + +def missed(ae): + try: + desc = ae.AEGetAttributeDesc('miss', 'keyw') + except AE.Error, msg: + return None + return desc.data + +def unpackevent(ae): + parameters = {} + while 1: + key = missed(ae) + if not key: break + parameters[key] = unpack(ae.AEGetParamDesc(key, '****')) + attributes = {} + for key in aekeywords: + try: + desc = ae.AEGetAttributeDesc(key, '****') + except (AE.Error, MacOS.Error), msg: + if msg[0] != -1701: + raise sys.exc_type, sys.exc_value + continue + attributes[key] = unpack(desc) + return parameters, attributes + +def packevent(ae, parameters = {}, attributes = {}): + for key, value in parameters.items(): + ae.AEPutParamDesc(key, pack(value)) + for key, value in attributes.items(): + ae.AEPutAttributeDesc(key, pack(value)) + +def test(): + target = AE.AECreateDesc('sign', 'KAHL') + ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0) + print unpackevent(ae) + +if __name__ == '__main__': + test() |