On 26.08.2012 01:31, Dennis Lee Bieber wrote: > The struct module relies upon the user knowing the format of the data. > If your problem is that you have some null-terminated string data in a > variable width field, you will have to locate the position of the null > FIRST, and specify the appropriate "count" for the s format.
This gave me the idea of an Enhancement of the Struct class with an additional format character (perhaps 'n') which corresponds to a null-terminated string: ----- # -*- coding: utf-8 -*- import struct class Nstr(object): def __init__(self, ncount): self.ncount = ncount def unpack(self, s): s = s.split('\0') return s[:self.ncount], '\0'.join(s[self.ncount:]) def pack(self, *s): if len(s)!=self.ncount: raise ValueError for st in s: if '\0' in st: raise ValueError return '\0'.join(s)+'\0' def __repr__(self): return 'Nstr('+repr(self.ncount)+')' class NStruct(object): def __init__(self, format): self.format = format if format[0] in '!=<>@': self.endianness = format[0] format = format[1:] else: self.endianness = '' self.chunks = [] while len(format)>0: j = format.find('n') if j > -1: k = j-1 while format[k].isdigit(): k-=1 chunkformat, ncount, format = format[:k+1],\ format[k+1:j], format[j+1:] ncount = 1 if len(ncount)==0 else int(ncount) else: chunkformat, ncount, format = format, '', '' ncount = 0 stru = struct.Struct(self.endianness+chunkformat) l = len(stru.unpack("0"*stru.size)) self.chunks.append((stru, l)) if ncount > 0: self.chunks.append((Nstr(ncount), ncount)) def unpack(self, data): res = [] for sth, n in self.chunks: if isinstance(sth, struct.Struct): chunk, data = data[:sth.size], data[sth.size:] res.extend(sth.unpack(chunk)) elif isinstance(sth, Nstr): chunk, data = sth.unpack(data) res.extend(chunk) return res def pack(self, *data): res = [] for sth, n in self.chunks: chunk, data = data[:n], data[n:] res.append(sth.pack(*chunk)) return ''.join(res) def __repr__(self): return 'NStruct('+repr(self.format)+')' if __name__=="__main__": a = NStruct('h b 2n 2h') print repr(a) d = 'asdblah blah\0haha\0asdf' r = a.unpack(d) assert r == [29537, 100, 'blah blah', 'haha', 29537, 26212] print repr(d), repr(r) dd = a.pack(*r) print r, repr(dd) assert dd == d ----- beware of bugs in the above code, i haven't testet it much yet. Alex -- http://mail.python.org/mailman/listinfo/python-list