aepack.py :  » Language-Interface » ChinesePython » chinesepython2.1.3-0.4 » Mac » Lib » lib-toolbox » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Language Interface » ChinesePython 
ChinesePython » chinesepython2.1.3 0.4 » Mac » Lib » lib toolbox » aepack.py
"""Tools for use in AppleEvent clients and servers:
conversion between AE types and python types

pack(x) converts a Python object to an AEDesc object
unpack(desc) does the reverse
coerce(x, wanted_sample) coerces a python object to another python object
"""

#
# This code was originally written by Guido, and modified/extended by Jack
# to include the various types that were missing. The reference used is
# Apple Event Registry, chapter 9.
#

import struct
import string
import types
from string import strip
from types import *
import AE
from AppleEvents import *
import MacOS
import macfs
import StringIO
import aetypes
from aetypes import mkenum,mktype

# These ones seem to be missing from AppleEvents
# (they're in AERegistry.h)

#typeColorTable = 'clrt'
#typeDrawingArea = 'cdrw'
#typePixelMap = 'cpix'
#typePixelMapMinus = 'tpmm'
#typeRotation = 'trot'
#typeTextStyles = 'tsty'
#typeStyledText = 'STXT'
#typeAEText = 'tTXT'
#typeEnumeration = 'enum'

#
# Some AE types are immedeately coerced into something
# we like better (and which is equivalent)
#
unpacker_coercions = {
  typeComp : typeFloat,
  typeColorTable : typeAEList,
  typeDrawingArea : typeAERecord,
  typeFixed : typeFloat,
  typeExtended : typeFloat,
  typePixelMap : typeAERecord,
  typeRotation : typeAERecord,
  typeStyledText : typeAERecord,
  typeTextStyles : typeAERecord,
};

#
# Some python types we need in the packer:
#
AEDescType = type(AE.AECreateDesc('TEXT', ''))
_sample_fss = macfs.FSSpec(':')
_sample_alias = _sample_fss.NewAliasMinimal()
FSSType = type(_sample_fss)
AliasType = type(_sample_alias)

def pack(x, forcetype = None):
  """Pack a python object into an AE descriptor"""
  
  if forcetype:
    if type(x) is StringType:
      return AE.AECreateDesc(forcetype, x)
    else:
      return pack(x).AECoerceDesc(forcetype)
      
  if x == None:
    return AE.AECreateDesc('null', '')
    
  t = type(x)
  if t == AEDescType:
    return x
  if t == FSSType:
    return AE.AECreateDesc('fss ', x.data)
  if t == AliasType:
    return AE.AECreateDesc('alis', x.data)
  if t == IntType:
    return AE.AECreateDesc('long', struct.pack('l', x))
  if t == FloatType:
    return AE.AECreateDesc('doub', struct.pack('d', x))
  if t == StringType:
    return AE.AECreateDesc('TEXT', x)
  if t == ListType:
    list = AE.AECreateList('', 0)
    for item in x:
      list.AEPutDesc(0, pack(item))
    return list
  if t == DictionaryType:
    record = AE.AECreateList('', 1)
    for key, value in x.items():
      record.AEPutParamDesc(key, pack(value))
    return record
  if t == InstanceType and hasattr(x, '__aepack__'):
    return x.__aepack__()
  return AE.AECreateDesc('TEXT', repr(x)) # Copout

def unpack(desc):
  """Unpack an AE descriptor to a python object"""
  t = desc.type
  
  if unpacker_coercions.has_key(t):
    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))
    return l
  if t == typeAERecord:
    d = {}
    for i in range(desc.AECountItems()):
      keyword, item = desc.AEGetNthDesc(i+1, '****')
      d[keyword] = unpack(item)
    return d
  if t == typeAEText:
    record = desc.AECoerceDesc('reco')
    return mkaetext(unpack(record))
  if t == typeAlias:
    return macfs.RawAlias(desc.data)
  # typeAppleEvent returned as unknown
  if t == typeBoolean:
    return struct.unpack('b', desc.data)[0]
  if t == typeChar:
    return desc.data
  # 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 macfs.RawFSSpec(desc.data)
  if t == typeInsertionLoc:
    record = desc.AECoerceDesc('reco')
    return mkinsertionloc(unpack(record))
  # 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')
    return mkobject(unpack(record))
  # 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)
  #
  # The following are special
  #
  if t == 'rang':
    record = desc.AECoerceDesc('reco')
    return mkrange(unpack(record))
  if t == 'cmpd':
    record = desc.AECoerceDesc('reco')
    return mkcomparison(unpack(record))
  if t == 'logi':
    record = desc.AECoerceDesc('reco')
    return mklogical(unpack(record))
  return mkunknown(desc.type, desc.data)
  
def coerce(data, egdata):
  """Coerce a python object to another type using the AE coercers"""
  pdata = pack(data)
  pegdata = pack(egdata)
  pdata = pdata.AECoerceDesc(pegdata.type)
  return unpack(pdata)

#
# Helper routines for unpack
#
def mktargetid(data):
  sessionID = getlong(data[:4])
  name = mkppcportrec(data[4:4+72])
  location = mklocationnamerec(data[76:76+36])
  rcvrName = mkppcportrec(data[112:112+72])
  return sessionID, name, location, rcvrName

def mkppcportrec(rec):
  namescript = getword(rec[:2])
  name = getpstr(rec[2:2+33])
  portkind = getword(rec[36:38])
  if portkind == 1:
    ctor = rec[38:42]
    type = rec[42:46]
    identity = (ctor, type)
  else:
    identity = getpstr(rec[38:38+33])
  return namescript, name, portkind, identity

def mklocationnamerec(rec):
  kind = getword(rec[:2])
  stuff = rec[2:]
  if kind == 0: stuff = None
  if kind == 2: stuff = getpstr(stuff)
  return kind, stuff

def mkunknown(type, data):
  return aetypes.Unknown(type, data)

def getpstr(s):
  return s[1:1+ord(s[0])]

def getlong(s):
  return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])

def getword(s):
  return (ord(s[0])<<8) | (ord(s[1])<<0)

def mkkeyword(keyword):
  return aetypes.Keyword(keyword)

def mkrange(dict):
  return aetypes.Range(dict['star'], dict['stop'])

def mkcomparison(dict):
  return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])

def mklogical(dict):
  return aetypes.Logical(dict['logc'], dict['term'])

def mkstyledtext(dict):
  return aetypes.StyledText(dict['ksty'], dict['ktxt'])
  
def mkaetext(dict):
  return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])
  
def mkinsertionloc(dict):
  return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])

def mkobject(dict):
  want = dict['want'].type
  form = dict['form'].enum
  seld = dict['seld']
  fr   = dict['from']
  if form in ('name', 'indx', 'rang', 'test'):
    if want == 'text': return aetypes.Text(seld, fr)
    if want == 'cha ': return aetypes.Character(seld, fr)
    if want == 'cwor': return aetypes.Word(seld, fr)
    if want == 'clin': return aetypes.Line(seld, fr)
    if want == 'cpar': return aetypes.Paragraph(seld, fr)
    if want == 'cwin': return aetypes.Window(seld, fr)
    if want == 'docu': return aetypes.Document(seld, fr)
    if want == 'file': return aetypes.File(seld, fr)
    if want == 'cins': return aetypes.InsertionPoint(seld, fr)
  if want == 'prop' and form == 'prop' and aetypes.IsType(seld):
    return aetypes.Property(seld.type, fr)
  return aetypes.ObjectSpecifier(want, form, seld, fr)

def _test():
  """Test program. Pack and unpack various things"""
  objs = [
    'a string',
    12,
    12.0,
    None,
    ['a', 'list', 'of', 'strings'],
    {'key1': 'value1', 'key2':'value2'},
    macfs.FSSpec(':'),
    macfs.FSSpec(':').NewAliasMinimal(),
    aetypes.Enum('enum'),
    aetypes.Type('type'),
    aetypes.Keyword('kwrd'),
    aetypes.Range(1, 10),
    aetypes.Comparison(1, '<   ', 10),
    aetypes.Logical('not ', 1),
    # Cannot do StyledText
    # Cannot do AEText
    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)),
  ]
  for o in objs:
    print 'BEFORE', o, `o`
    packed = pack(o)
    unpacked = unpack(packed)
    print 'AFTER ', unpacked, `unpacked`
  import sys
  sys.exit(1)
  
if __name__ == '__main__':
  _test()
  
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.