class TestAepack(unittest.TestCase): OBJECTS = [ aetypes.Enum('enum'), aetypes.Type('type'), aetypes.Keyword('kwrd'), aetypes.Range(1, 10), aetypes.Comparison(1, '< ', 10), aetypes.Logical('not ', 1), aetypes.IntlText(0, 0, 'international text'), aetypes.IntlWritingCode(0,0), aetypes.QDPoint(50,100), aetypes.QDRectangle(50,100,150,200), aetypes.RGBColor(0x7000, 0x6000, 0x5000), aetypes.Unknown('xxxx', 'unknown type data'), aetypes.Character(1), aetypes.Character(2, aetypes.Line(2)), ] def test_roundtrip_string(self): o = 'a string' packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_int(self): o = 12 packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_float(self): o = 12.1 packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_None(self): o = None packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_aeobjects(self): for o in self.OBJECTS: packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(repr(o), repr(unpacked)) def test_roundtrip_FSSpec(self): try: import Carbon.File except: return o = Carbon.File.FSSpec(os.curdir) packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o.as_pathname(), unpacked.as_pathname()) def test_roundtrip_Alias(self): try: import Carbon.File except: return o = Carbon.File.FSSpec(os.curdir).NewAliasMinimal() packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o.FSResolveAlias(None)[0].as_pathname(), unpacked.FSResolveAlias(None)[0].as_pathname())
def unpack(desc, formodulename=''): t = desc.type if t in unpacker_coercions: desc = desc.AECoerceDesc(unpacker_coercions[t]) t = desc.type if t == typeAEList: l = [] for i in range(desc.AECountItems()): keyword, item = desc.AEGetNthDesc(i + 1, '****') l.append(unpack(item, formodulename)) return l elif t == typeAERecord: d = {} for i in range(desc.AECountItems()): keyword, item = desc.AEGetNthDesc(i + 1, '****') d[keyword] = unpack(item, formodulename) return d elif t == typeAEText: record = desc.AECoerceDesc('reco') return mkaetext(unpack(record, formodulename)) elif t == typeAlias: return Carbon.File.Alias(rawdata=desc.data) elif t == typeBoolean: return struct.unpack('b', desc.data)[0] elif t == typeChar: return desc.data elif t == typeUnicodeText: return unicode(desc.data, 'utf16') elif t == typeEnumeration: return mkenum(desc.data) elif t == typeFalse: return 0 elif t == typeFloat: data = desc.data return struct.unpack('d', data)[0] elif t == typeFSS: return Carbon.File.FSSpec(rawdata=desc.data) elif t == typeFSRef: return Carbon.File.FSRef(rawdata=desc.data) elif t == typeInsertionLoc: record = desc.AECoerceDesc('reco') return mkinsertionloc(unpack(record, formodulename)) elif t == typeIntlText: script, language = struct.unpack('hh', desc.data[:4]) return aetypes.IntlText(script, language, desc.data[4:]) elif t == typeIntlWritingCode: script, language = struct.unpack('hh', desc.data) return aetypes.IntlWritingCode(script, language) elif t == typeKeyword: return mkkeyword(desc.data) elif t == typeLongInteger: return struct.unpack('l', desc.data)[0] elif t == typeLongDateTime: a, b = struct.unpack('lL', desc.data) return (long(a) << 32) + b elif t == typeNull: return None elif t == typeMagnitude: v = struct.unpack('l', desc.data) if v < 0: v = 4294967296L + v return v elif t == typeObjectSpecifier: record = desc.AECoerceDesc('reco') if formodulename: return mkobjectfrommodule(unpack(record, formodulename), formodulename) return mkobject(unpack(record, formodulename)) elif t == typeQDPoint: v, h = struct.unpack('hh', desc.data) return aetypes.QDPoint(v, h) elif t == typeQDRectangle: v0, h0, v1, h1 = struct.unpack('hhhh', desc.data) return aetypes.QDRectangle(v0, h0, v1, h1) elif t == typeRGBColor: r, g, b = struct.unpack('hhh', desc.data) return aetypes.RGBColor(r, g, b) elif t == typeShortFloat: return struct.unpack('f', desc.data)[0] elif t == typeShortInteger: return struct.unpack('h', desc.data)[0] elif t == typeTargetID: return mktargetid(desc.data) elif t == typeTrue: return 1 elif t == typeType: return mktype(desc.data, formodulename) elif t == 'rang': record = desc.AECoerceDesc('reco') return mkrange(unpack(record, formodulename)) elif t == 'cmpd': record = desc.AECoerceDesc('reco') return mkcomparison(unpack(record, formodulename)) elif t == 'logi': record = desc.AECoerceDesc('reco') return mklogical(unpack(record, formodulename)) else: return mkunknown(desc.type, desc.data)
def unpack(desc, formodulename=""): """Unpack an AE descriptor to a python object""" t = desc.type if t in unpacker_coercions: desc = desc.AECoerceDesc(unpacker_coercions[t]) t = desc.type # This is a guess by Jack.... if t == typeAEList: l = [] for i in range(desc.AECountItems()): keyword, item = desc.AEGetNthDesc(i + 1, '****') l.append(unpack(item, formodulename)) return l if t == typeAERecord: d = {} for i in range(desc.AECountItems()): keyword, item = desc.AEGetNthDesc(i + 1, '****') d[keyword] = unpack(item, formodulename) return d if t == typeAEText: record = desc.AECoerceDesc('reco') return mkaetext(unpack(record, formodulename)) if t == typeAlias: return Carbon.File.Alias(rawdata=desc.data) # typeAppleEvent returned as unknown if t == typeBoolean: return struct.unpack('b', desc.data)[0] if t == typeChar: return desc.data if t == typeUnicodeText: return unicode(desc.data, 'utf16') # typeColorTable coerced to typeAEList # typeComp coerced to extended # typeData returned as unknown # typeDrawingArea coerced to typeAERecord if t == typeEnumeration: return mkenum(desc.data) # typeEPS returned as unknown if t == typeFalse: return 0 if t == typeFloat: data = desc.data return struct.unpack('d', data)[0] if t == typeFSS: return Carbon.File.FSSpec(rawdata=desc.data) if t == typeFSRef: return Carbon.File.FSRef(rawdata=desc.data) if t == typeInsertionLoc: record = desc.AECoerceDesc('reco') return mkinsertionloc(unpack(record, formodulename)) # typeInteger equal to typeLongInteger if t == typeIntlText: script, language = struct.unpack('hh', desc.data[:4]) return aetypes.IntlText(script, language, desc.data[4:]) if t == typeIntlWritingCode: script, language = struct.unpack('hh', desc.data) return aetypes.IntlWritingCode(script, language) if t == typeKeyword: return mkkeyword(desc.data) if t == typeLongInteger: return struct.unpack('l', desc.data)[0] if t == typeLongDateTime: a, b = struct.unpack('lL', desc.data) return (long(a) << 32) + b if t == typeNull: return None if t == typeMagnitude: v = struct.unpack('l', desc.data) if v < 0: v = 0x100000000L + v return v if t == typeObjectSpecifier: record = desc.AECoerceDesc('reco') # If we have been told the name of the module we are unpacking aedescs for, # we can attempt to create the right type of python object from that module. if formodulename: return mkobjectfrommodule(unpack(record, formodulename), formodulename) return mkobject(unpack(record, formodulename)) # typePict returned as unknown # typePixelMap coerced to typeAERecord # typePixelMapMinus returned as unknown # typeProcessSerialNumber returned as unknown if t == typeQDPoint: v, h = struct.unpack('hh', desc.data) return aetypes.QDPoint(v, h) if t == typeQDRectangle: v0, h0, v1, h1 = struct.unpack('hhhh', desc.data) return aetypes.QDRectangle(v0, h0, v1, h1) if t == typeRGBColor: r, g, b = struct.unpack('hhh', desc.data) return aetypes.RGBColor(r, g, b) # typeRotation coerced to typeAERecord # typeScrapStyles returned as unknown # typeSessionID returned as unknown if t == typeShortFloat: return struct.unpack('f', desc.data)[0] if t == typeShortInteger: return struct.unpack('h', desc.data)[0] # typeSMFloat identical to typeShortFloat # typeSMInt indetical to typeShortInt # typeStyledText coerced to typeAERecord if t == typeTargetID: return mktargetid(desc.data) # typeTextStyles coerced to typeAERecord # typeTIFF returned as unknown if t == typeTrue: return 1 if t == typeType: return mktype(desc.data, formodulename) # # The following are special # if t == 'rang': record = desc.AECoerceDesc('reco') return mkrange(unpack(record, formodulename)) if t == 'cmpd': record = desc.AECoerceDesc('reco') return mkcomparison(unpack(record, formodulename)) if t == 'logi': record = desc.AECoerceDesc('reco') return mklogical(unpack(record, formodulename)) return mkunknown(desc.type, desc.data)
"""Tools for use in AppleEvent clients and servers: