Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #27917

Re: issue with struct.unpack

Date 2012-08-26 14:53 +0200
From Alexander Blinne <news@blinne.net>
Newsgroups comp.lang.python
Subject Re: issue with struct.unpack
References <2cc8b390-0b7a-4a0f-ac88-113daf65eba5@googlegroups.com> <mailman.3818.1345938381.4697.python-list@python.org>
Message-ID <503a1c4a$0$6555$9b4e6d93@newsspool4.arcor-online.net> (permalink)
Organization Arcor

Show all headers | View raw


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

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

issue with struct.unpack 9bizy <a.m.akingbulu-11@student.lboro.ac.uk> - 2012-08-25 11:34 -0700
  Re: issue with struct.unpack Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-08-25 20:12 +0100
  Re: issue with struct.unpack MRAB <python@mrabarnett.plus.com> - 2012-08-25 20:16 +0100
    Re: issue with struct.unpack 9bizy <a.m.akingbulu-11@student.lboro.ac.uk> - 2012-08-28 15:35 -0700
      Re: issue with struct.unpack MRAB <python@mrabarnett.plus.com> - 2012-08-28 23:53 +0100
      Re: issue with struct.unpack Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-28 22:40 -0400
    Re: issue with struct.unpack 9bizy <a.m.akingbulu-11@student.lboro.ac.uk> - 2012-08-28 15:35 -0700
  Re: issue with struct.unpack Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-25 19:31 -0400
    Re: issue with struct.unpack Alexander Blinne <news@blinne.net> - 2012-08-26 14:53 +0200
  Re: issue with struct.unpack MRAB <python@mrabarnett.plus.com> - 2012-08-28 23:49 +0100
    Re: issue with struct.unpack 9bizy <a.m.akingbulu-11@student.lboro.ac.uk> - 2012-08-28 16:01 -0700
    Re: issue with struct.unpack MRAB <python@mrabarnett.plus.com> - 2012-08-29 00:36 +0100
      Re: issue with struct.unpack 9bizy <a.m.akingbulu-11@student.lboro.ac.uk> - 2012-08-28 16:55 -0700
      Re: issue with struct.unpack 9bizy <a.m.akingbulu-11@student.lboro.ac.uk> - 2012-08-28 16:55 -0700
  Re: issue with struct.unpack Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-28 22:31 -0400

csiph-web