Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from base import SIMPLE_TYPES_DICT
00034
00035 _context_patterns = []
00036 def add_pattern(p):
00037 """
00038 Record struct pattern that's been used for (de)serialization
00039 """
00040 _context_patterns.append(p)
00041 def clear_patterns():
00042 """
00043 Clear record of struct pattern that have been used for (de)serialization
00044 """
00045 del _context_patterns[:]
00046 def get_patterns():
00047 """
00048 :returns: record of struct pattern that have been used for (de)serialization
00049 """
00050 return _context_patterns[:]
00051
00052 def compute_struct_pattern(types):
00053 """
00054 :param types: type names, ``[str]``
00055 :returns: format string for struct if types are all simple. Otherwise, return None, ``str``
00056 """
00057 if not types:
00058 return None
00059 try:
00060 return ''.join([SIMPLE_TYPES_DICT[t] for t in types])
00061 except:
00062 return None
00063
00064 def reduce_pattern(pattern):
00065 """
00066 Optimize the struct format pattern.
00067 :param pattern: struct pattern, ``str``
00068 :returns: optimized struct pattern, ``str``
00069 """
00070 if not pattern or len(pattern) == 1 or '%' in pattern:
00071 return pattern
00072 prev = pattern[0]
00073 count = 1
00074 new_pattern = ''
00075 nums = [str(i) for i in range(0, 9)]
00076 for c in pattern[1:]:
00077 if c == prev and not c in nums:
00078 count += 1
00079 else:
00080 if count > 1:
00081 new_pattern = new_pattern + str(count) + prev
00082 else:
00083 new_pattern = new_pattern + prev
00084 prev = c
00085 count = 1
00086 if count > 1:
00087 new_pattern = new_pattern + str(count) + c
00088 else:
00089 new_pattern = new_pattern + prev
00090 return new_pattern
00091
00092
00093
00094 def serialize(expr):
00095 return "buff.write(%s)"%expr
00096
00097
00098 def int32_pack(var):
00099 """
00100 :param var: variable name, ``str``
00101 :returns: struct packing code for an int32
00102 """
00103 return serialize('_struct_I.pack(%s)'%var)
00104
00105
00106 def int32_unpack(var, buff):
00107 """
00108 :param var: variable name, ``str``
00109 :returns: struct unpacking code for an int32
00110 """
00111 return '(%s,) = _struct_I.unpack(%s)'%(var, buff)
00112
00113
00114 def pack(pattern, vars):
00115 """
00116 create struct.pack call for when pattern is a string pattern
00117 :param pattern: pattern for pack, ``str``
00118 :param vars: name of variables to pack, ``str``
00119 """
00120
00121 pattern = reduce_pattern(pattern)
00122 add_pattern(pattern)
00123 return serialize("_struct_%s.pack(%s)"%(pattern, vars))
00124 def pack2(pattern, vars):
00125 """
00126 create struct.pack call for when pattern is the name of a variable
00127 :param pattern: name of variable storing string pattern, ``struct``
00128 :param vars: name of variables to pack, ``str``
00129 """
00130 return serialize("struct.pack(%s, %s)"%(pattern, vars))
00131
00132 def unpack(var, pattern, buff):
00133 """
00134 create struct.unpack call for when pattern is a string pattern
00135 :param var: name of variable to unpack, ``str``
00136 :param pattern: pattern for pack, ``str``
00137 :param buff: buffer to unpack from, ``str``
00138 """
00139
00140 pattern = reduce_pattern(pattern)
00141 add_pattern(pattern)
00142 return var + " = _struct_%s.unpack(%s)"%(pattern, buff)
00143
00144 def unpack2(var, pattern, buff):
00145 """
00146 Create struct.unpack call for when pattern refers to variable
00147 :param var: variable the stores the result of unpack call, ``str``
00148 :param pattern: name of variable that unpack will read from, ``str``
00149 :param buff: buffer that the unpack reads from, ``StringIO``
00150 """
00151 return "%s = struct.unpack(%s, %s)"%(var, pattern, buff)
00152