Welcome, guest | Sign In | My Account | Store | Cart

There has been a receipe already, but not supporting zero terminated 'C' strings. Zerotermination is marked with 'z', number before 'z', say 2z is not supported. You can use 2 'z' positions, however. Set tu=True outputs to [] instead of record.

Python, 64 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from struct import calcsize, pack, unpack

class ConcreteRecord(list):

    def __init__(self, fields, data=None, tu = False):
        self._fields = fields
        #self.tup = ()
        varspace = 0
        if data == None: return
        for f in fields:
            name,fmt,start,stop = f
            if fmt == 'z':
                strlen = data.find('\0', (start+varspace))-(start+varspace)
                val = data[(start+varspace):(start+varspace+strlen)]
                varspace += strlen + 1
            else:    
                val = unpack(fmt, data[(start+varspace):(stop+varspace)])
                if len(val) == 1: val=val[0]
            if tu == True:
                self.append(val,)
            else: 
                self.__dict__[name] = val

class RecordFactory:

    def __init__(self,record_fmt):
        self.fields = []
        pos = 0
        for field in record_fmt.split():
            if field[0] == "#": continue
            fmt,name = field.split('.')
            if fmt == 'z':
                size = 0
            else:
                size = calcsize(fmt)
            self.fields += [(name,fmt,pos,pos+size)]
            pos += size

    def build(self, data, tu  = False):
        return ConcreteRecord(self.fields, data, tu)

#### EXAMPLE ##################################################################

if __name__ == '__main__':

    myrf = RecordFactory("""
        z.test
        4B.ip
        z.zeroterm
        z.abc
        >H.port
        >I.session_id
    """)

    r = myrf.build("teast\x00\x00\x01\x02\x03" + "test\x00" + "abc\x00" + "\x00\x04" + "\xFE\xDC\xBA\x98")
    print "test:      ", r.test
    print "ip:        ", r.ip
    print "zeroterm:  ", r.zeroterm
    print "second string:  ", r.abc
    print "port:      ", r.port
    print "session_id:", r.session_id

    r = myrf.build("teast\x00\x00\x01\x02\x03" + "test\x00" + "abc\x00" + "\x00\x04" + "\xFE\xDC\xBA\x98",True)
    print r
Created by Andre Pfeuffer on Sat, 25 Feb 2006 (PSF)
Python recipes (4591)
Andre Pfeuffer's recipes (1)

Required Modules

Other Information and Tasks