Package Peach :: Package Transformers :: Module type
[hide private]

Source Code for Module Peach.Transformers.type

  1   
  2  ''' 
  3  Type transforms (atoi, itoa, etc). 
  4  ''' 
  5   
  6  # 
  7  # Copyright (c) 2005-2008 Michael Eddington 
  8  # Copyright (c) 2004-2005 IOActive Inc. 
  9  # 
 10  # Permission is hereby granted, free of charge, to any person obtaining a copy  
 11  # of this software and associated documentation files (the "Software"), to deal 
 12  # in the Software without restriction, including without limitation the rights  
 13  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
 14  # copies of the Software, and to permit persons to whom the Software is  
 15  # furnished to do so, subject to the following conditions: 
 16  # 
 17  # The above copyright notice and this permission notice shall be included in     
 18  # all copies or substantial portions of the Software. 
 19  # 
 20  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 21  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 22  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 23  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 24  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 25  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 26  # SOFTWARE. 
 27  # 
 28   
 29  # Authors: 
 30  #   Michael Eddington (mike@phed.org) 
 31   
 32  # $Id: Peach.Transformers.type-pysrc.html 1138 2008-08-16 19:39:03Z meddingt $ 
 33   
 34  import  struct,types, sys 
 35  from types import * 
 36  from Peach.transformer import Transformer 
 37   
38 -class Pack(Transformer):
39 '''Simple pack transform. Only a single piece of data can be used. 40 Usefull to generate binary data from a generator. 41 42 Format C Type Python Notes 43 x pad byte no value 44 c char string of length 1 45 b signed char integer 46 B unsigned char integer 47 h short integer 48 H unsigned short integer 49 i int integer 50 I unsigned int long 51 l long integer 52 L unsigned long long 53 q long long long (1) 54 Q unsigned long long long (1) 55 f float float 56 d double float 57 s char[] string 58 p char[] string 59 P void * integer 60 ''' 61
62 - def __init__(self, packFormat):
63 '''Create a Pack trasnformer. packFormat is a standard pack 64 format string. Format string should only contain a single 65 data place holder.''' 66 Transformer.__init__(self) 67 self._packFormat = packFormat
68
69 - def realEncode(self, data):
70 '''Run pack on data''' 71 72 return struct.pack(self._packFormat, data)
73 74
75 -class NumberToString(Transformer):
76 '''Transforms any type of number (int, long, float) to string.''' 77
78 - def __init__(self, formatString = None):
79 '''Create NumberToString Instance. formatString is a standard 80 Python string formater (optional).''' 81 Transformer.__init__(self) 82 self._formatString = formatString
83
84 - def realEncode(self, data):
85 '''Convert number to string. If no formatString was specified 86 in class contructor data type is dynamicly determined and converted 87 using a default formatString of "%d", "%f", or "%d" for Int, Float, 88 and Long respectively.''' 89 90 if self._formatString == None: 91 retType = type(data) 92 if retType is IntType: 93 return "%d" % data 94 elif retType is FloatType: 95 return "%f" % data 96 elif retType is LongType: 97 return "%d" % data 98 else: 99 return data 100 101 return self._formatString % data
102 103
104 -class StringToInt(Transformer):
105 '''Transform a string into an integer (atoi).'''
106 - def realEncode(self, data):
107 return long(data)
108 109
110 -class StringToFloat(Transformer):
111 '''Transform a string into an float (atof).'''
112 - def realEncode(self, data):
113 return float(data)
114 115
116 -class IntToHex(Transformer):
117 '''Transform an integer into hex.''' 118
119 - def __init__(self, withPrefix = 0):
120 '''Create IntToHex object. withPrefix flag indicates if 121 0x prefix should be tagged onto string. Default is no.''' 122 Transformer.__init__(self) 123 self._withPrefix = withPrefix
124
125 - def realEncode(self, data):
126 127 if type(data) == StringType: 128 data = long(data) 129 130 ret = hex(data) 131 if self._withPrefix == 0: 132 return ret[2:] 133 134 return ret
135
136 -class _AsNumber(Transformer):
137 '''Transform an number to a specific size 'n stuff''' 138
139 - def __init__(self, isSigned = 1, isLittleEndian = 1):
140 ''' 141 @type isSigned: number 142 @param isSigned: 1 for signed, 0 for unsigned 143 @type isLittleEndian: number 144 @param isLittleEndian: 1 for signed, 0 for unsigned 145 ''' 146 147 Transformer.__init__(self) 148 self._isSigned = isSigned 149 self._isLittleEndian = isLittleEndian
150
151 - def _unfuglyNumber(self, data):
152 ''' 153 Will attempt to figure out if the incoming data 154 is a byte stream that must be converted to get our 155 number we will then cast. Due to StaticBinary issues. 156 157 Chears to Blake for pointing this out. 158 ''' 159 160 try: 161 # First check to see if we need todo this 162 if long(data) == long(str(data)): 163 return long(data) 164 except: 165 pass 166 167 #print "_unfuglyNumber(%s)" % repr(data), data 168 169 # Now lets unfugly the thing 170 hexString = "" 171 for c in data: 172 h = hex(ord(c))[2:] 173 if len(h) < 2: 174 h = "0" + h 175 176 hexString += h 177 178 return long(hexString, 16)
179
180 - def realEncode(self, data):
181 182 data = self._unfuglyNumber(data) 183 184 packStr = '' 185 186 if self._isLittleEndian == 1: 187 packStr = '<' 188 else: 189 packStr = '>' 190 191 if self._isSigned == 1: 192 packStr += self._packFormat.lower() 193 else: 194 packStr += self._packFormat.upper() 195 196 try: 197 return struct.pack(packStr, long(data)) 198 except: 199 return struct.pack(packStr, 0)
200
201 - def realDecode(self, data):
202 203 packStr = '' 204 205 if self._isLittleEndian == 1: 206 packStr = '<' 207 else: 208 packStr = '>' 209 210 if self._isSigned == 1: 211 packStr += self._packFormat.lower() 212 else: 213 packStr += self._packFormat.upper() 214 215 try: 216 return struct.unpack(packStr, data)[0] 217 except: 218 return 0
219 220
221 -class AsInt8(_AsNumber):
222 '''Transform an number to an INT8 or UINT8 223 ''' 224 _packFormat = 'b'
225
226 -class AsInt16(_AsNumber):
227 '''Transform an number to an INT16 or UINT16 228 ''' 229 _packFormat = 'h'
230
231 -class AsInt24(Transformer):
232 '''Transform an number to a UINT24 (don't ask) 233 ''' 234
235 - def __init__(self, isSigned = 1, isLittleEndian = 1):
236 ''' 237 @type isSigned: number 238 @param isSigned: 1 for signed, 0 for unsigned (we ignore this) 239 @type isLittleEndian: number 240 @param isLittleEndian: 1 for signed, 0 for unsigned 241 ''' 242 243 Transformer.__init__(self) 244 self._isLittleEndian = isLittleEndian
245
246 - def realEncode(self, data):
247 248 try: 249 data = long(data) 250 packStr = '' 251 252 if self._isLittleEndian == 1: 253 packStr = '<' 254 else: 255 packStr = '>' 256 257 packStr += 'L' 258 v = struct.pack(packStr, data) 259 260 if self._isLittleEndian == 1: 261 return v[:3] 262 else: 263 return v[1:] 264 except: 265 return 0
266
267 -class AsInt32(_AsNumber):
268 '''Transform an number to an INT32 or UINT32 269 ''' 270 _packFormat = 'l'
271
272 -class AsInt64(_AsNumber):
273 '''Transform an number to an INT64 or UINT64 274 ''' 275 _packFormat = 'q'
276 277 278 279 # end 280