##language:zh ''' pmsg-scon-opt.py ''' -- Zoom.Quiet [<>] <> {{{#!python # -*- coding: gbk -*- """minimic 协议信息包处理 Otter 目标代码优化尝试 """ import string import struct import zlib import cPickle pickle cPickle from minimic.message import bytemsg class minimicPMessage(bytemsg.ByteMessage): """minimicP 消息基类""" def __init__(self): # 消息头 self.head = bytemsg.ByteMessageHead(self) # 消息体 self.body = bytemsg.ByteMessageBody(self) # 消息工具 self.msgutilcls = minimicPMessageUtil # 协议名称 self.protocolname = 'minimicp' # 当前的消息名称 self.msgname = '' # 解包长度计数 self.lg = 0 def pack-s(self,key,value): """定长字串数据打包 """ return struct.pack(key,value) def unpack-s(self,key,value): """定长字串数据解包 """ pass def pack-I(self,value): """整数数据打包 """ return struct.pack("I",value) def unpack-I(self,key,value): """整数数据解包 """ pass def pack-v(self,fstr,lg,value): """变长字串数据打包 """ return struct.pack(fstr,lg,value) def unpack-v(self,key,value): """变长字串数据解包 """ pass def pack-z(self,fstr,lg,value): """压缩字符串打包 """ return struct.pack(fstr,lg,value) def unpack-z(self,key,value): """压缩字符串解包 """ pass def pack-Z(self,fstr,lg,value): """压缩序列化对象打包 """ return struct.pack(fstr,lg,value) def unpack-Z(self,key,value): """压缩序列化对象解包 """ pass def pack-F(self,fields,key,actdict): """浮动复合数据打包 - fields 应用传入的全部数据 - key "F"数据类别索引 - actdict 对应数据集合结构定义 """ body = '' body += struct.pack('I', len(fields[key])) i = 0 while i < len(fields[key]): body += self.smartpack(fields[key][i],actdict) i += 1 return body def agentfloatunp(self,field,datadict,bodyfield): """浮动复合数据解包辅助,专门进行复合包的内容解包 - field 应用传入的对应一段数据类型 - datadict 对应剩余数据 - bodyfield 回填对应的全局字典结点 """ if "s" == field[0]: packstr = datadict[self.lg:] stt = field[2]+field[0] lg = struct.calcsize(stt) bodyfield[field[1]] = struct.unpack(stt,packstr) return lg elif "I" == field[0]: packstr = datadict[self.lg:] lg = 4 bodyfield[field[1]] = struct.unpack("I",packstr) return lg elif "v" == field[0]: # "v"变长字串=4位整数长度信息+自声明长度 的字串 packet = packet[self.lg:] lg = struct.unpack('I', packet[:4]) packet = packet[4:] bodyfield[field[1]] = struct.unpack(str(lg)+'s', packet[:lg]) return 4+lg elif "z" == field[0]: # "v"变长字串=4位整数长度信息+自声明长度的压缩字串 packet = packet[self.lg:] lg = struct.unpack('I', packet[:4]) packet = packet[4:] bodyfield[field[1]] = zlib.decompress( \ struct.unpack(str(lg)+'s', packet[:lg])) return 4+lg elif "Z" == field[0]: # "v"变长字串=4位整数长度信息+自声明长度的串行化对象字串 packet = packet[self.lg:] lg = struct.unpack('I', packet[:4]) packet = packet[4:] bodyfield[field[1]] = pickle.loads( \ zlib.decompress(struct.unpack(str(lg)+'s', packet[:lg]) ) ) return 4+lg def smartfloatunp(self,dictli,packet,bodyfield): """智能浮动复合数据解包 - dictli 复合包结构声明字典列表 - packet 对应剩余数据 - bodyfield 回填对应的全局字典结点 """ for part in dictli self.lg += self.agentfloatunp(part,packet,bodyfield) def unpack-F(self,key,dictli,loop,value): """浮动复合数据解包 - key self.body.fields回填索引 - dictli 复合包结构声明字典列表 - loop 复合包总数! - value 对应剩余数据 """ packet = value self.body.fields[key] = [] i = 0 #fixedstt = '64s16sII' #fixedlen = struct.calcsize(fixedstt) while i < loop: for field in actdict: self.smartfloatunp(dictli,packet,self.body.fields[key][i]) i += 1 def smartagent(self,field,datadict,todotp): """智能代理,根据行为类型,以及数据类型自动分配处理函式 - field 应用传入的对应一段数据类型 - datadict 应用传入的数据包 - todotp [pack|unpack]即[进行打包|进行解包] """ if "pack" == todotp: # 进行数据打包 if "s" == field[0]: key = field[2]+field[0] return self.pack-s(key,datadict[field[1]]) elif "I" == field[0]: return self.pack-I(datadict[field[1]]) elif "v" == field[0]: lg = len(datadict[field[1]]) return self.pack-v('I'+str(lg)+'s',lg,datadict[field[1]]) elif "z" == field[0]: zdata = zlib.compress(datadict[field[1]]) lg = len(zdata) return self.pack-z('I'+str(lg)+'s',lg,zdata) elif "Z" == field[0]: zdata = zlib.compress(pickle.dumps(datadict[field[1]])) lg = len(zdata) return self.pack-Z('I'+str(lg)+'s',lg,zdata) else: # "F"浮动复合数据! return self.pack-F(datadict,field[1],field[2]) else: ## 对应解包处理 if "s" == field[0]: packstr = datadict[self.lg:] stt = field[2]+field[0] lg = struct.calcsize(stt) self.body.fields[field[1]] = struct.unpack(stt,packstr) return lg elif "I" == field[0]: packstr = datadict[self.lg:] lg = 4 self.body.fields[field[1]] = struct.unpack("I",packstr) return lg elif "v" == field[0]: # "v"变长字串=4位整数长度信息+自声明长度 的字串 packet = packet[self.lg:] lg = struct.unpack('I', packet[:4]) packet = packet[4:] self.body.fields[field[1]] = struct.unpack(str(lg)+'s', packet[:lg]) return 4+lg elif "z" == field[0]: # "v"变长字串=4位整数长度信息+自声明长度的压缩字串 packet = packet[self.lg:] lg = struct.unpack('I', packet[:4]) packet = packet[4:] self.body.fields[field[1]] = zlib.decompress( \ struct.unpack(str(lg)+'s', packet[:lg])) return 4+lg elif "Z" == field[0]: # "v"变长字串=4位整数长度信息+自声明长度的串行化对象字串 packet = packet[self.lg:] lg = struct.unpack('I', packet[:4]) packet = packet[4:] self.body.fields[field[1]] = pickle.loads( \ zlib.decompress(struct.unpack(str(lg)+'s', packet[:lg]) ) ) return 4+lg else: # "F"浮动复合数据! packet = packet[self.lg:] # 得到当前处理的剩余数据字串 floatlg = struct.unpack('I', packet[:4]) packet = packet[4:] lg = self.unpack-F(field[1],field[2],floatlg,packet) return lg def smartpack(self,fields,actdict): """智能打包 - 应用传入的值字典 - 对应的配置XML处理行为字典 """ mess = "" if 0 == len(actdict): #空报文 return None else: for actfield in actdict: mess +=self.smartagent(actfield,fields,"pack") return mess def smartunpack(self,packet,actdict): """智能数据解包 """ if 0 == len(actdict): #空报文 pass else: for field in actdict: self.lg += self.smartagent(field,packet,"unpack") ### 示范代码,列举最典型的三类数据包的处理! ## # def pack_minimicp_connect(self, fields): """connect报文打包""" actdict=[ ("s","system_id",6) ,("s","auth_source",16) ,("I","version",) ,("v","test",) ,("z","zip",) ,("Z","szip",) ,("s","time_stamp",8) ] message = self.smartpack(fields,actdict) return message def unpack_minimicp_connect(self, packet): """connect报文解包""" actdict=[ ("s","system_id",6) ,("s","auth_source",16) ,("I","version",) ,("v","test",) ,("z","zip",) ,("Z","szip",) ,("s","time_stamp",8) ] self.smartunpack(packet,actdict) def pack_minimicp_terminate(self, fields): """terminate报文体为空""" actdict=[] message = self.smartpack(fields,actdict) return message def unpack_minimicp_terminate(self, packet): """terminate报文体为空""" actdict=[] self.smartunpack(packet,actdict) def pack_minimicp_get_webmail_list_resp(self, fields): """含有 'F'的复合活动数据报文 """ if fields['status'] == 0: actdict=[ ("I","status",) ,("I","dataid",) ,("I","order",) ,("v","test",) ,("z","zip",) ,("Z","szip",) ,("F","maillist",[ ("s","filename",64) ,("v","subject",) ,("s","date",16) ,("I","size",) ,("I","flag",) ] ) ] message = self.smartpack(fields,actdict) return message else: return struct.pack('I', \ fields['status']) def unpack_minimicp_get_webmail_list_resp(self, packet): """含有 'F'的复合活动数据报文 """ (self.body.fields['status'],) = struct.unpack('I', packet) if self.body.fields['status'] == 0: actdict=[ ("I","status",) ,("I","dataid",) ,("I","order",) ,("v","test",) ,("z","zip",) ,("Z","szip",) ,("F","maillist",[ ("s","filename",64) ,("v","subject",) ,("s","date",16) ,("I","size",) ,("I","flag",) ] ) ] message = self.smartunpack(fields,actdict) else: pass }}}