mirror of https://github.com/python/cpython
297 lines
6.7 KiB
Python
297 lines
6.7 KiB
Python
|
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()
|