summaryrefslogtreecommitdiffstats
path: root/Mac/Lib/toolbox/aetools.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1995-01-30 11:53:55 (GMT)
committerGuido van Rossum <guido@python.org>1995-01-30 11:53:55 (GMT)
commit17448e24081eb713ac00d7bcb681f4f0d8abfcbf (patch)
tree4f9d6768ef326173e1141b1a92af63247a42b13a /Mac/Lib/toolbox/aetools.py
parent80ffd6683ca7b06ed743c629459b06b07defbfb3 (diff)
downloadcpython-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.py296
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()