Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > pythonic malloc

Reply
Thread Tools

pythonic malloc

 
 
kjockey
Guest
Posts: n/a
 
      07-21-2003
I have some simple UDP code that does:
s.sendto("\xf0\x00\x02\x00rachel\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",addr)

This is OK, except that I'd like to change the text in the middle ("rachel",
which is the hostname FWIW), and the NUL padding needs to go out to make
the length 25 bytes (so the padding depends on the length of the name).

So I could do something like:
retpacket = "\xf0\x00\x02\x00"+socket.gethostname()
while len(retpacket) < 26:
retpacket += "\x00"
s.sendto(retpacket, addr)

But that feels "wrong". And Python in a Nutshell says its a bad idea -
"anti-idiom".

Can anyone show me the true path?

Brad
 
Reply With Quote
 
 
 
 
Karl Scalet
Guest
Posts: n/a
 
      07-21-2003
kjockey schrieb:
> I have some simple UDP code that does:
> s.sendto("\xf0\x00\x02\x00rachel\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",addr)
>
> This is OK, except that I'd like to change the text in the middle ("rachel",
> which is the hostname FWIW), and the NUL padding needs to go out to make
> the length 25 bytes (so the padding depends on the length of the name).
>
> So I could do something like:
> retpacket = "\xf0\x00\x02\x00"+socket.gethostname()
> while len(retpacket) < 26:


shouldn't that be 25?

> retpacket += "\x00"
> s.sendto(retpacket, addr)
>
> But that feels "wrong". And Python in a Nutshell says its a bad idea -
> "anti-idiom".
>
> Can anyone show me the true path?


No idea, if it's the true path:

hn = socket.gethostname()
retpacket = '\xf0\x00\x02\x00%s%s' % (hn, (25-4-len(hn))*chr(0))
s.sendto(retpacket, addr)

Karl


>
> Brad


 
Reply With Quote
 
 
 
 
Brad Hards
Guest
Posts: n/a
 
      07-21-2003
Karl Scalet wrote:

> kjockey schrieb:
>> I have some simple UDP code that does:
>>

s.sendto("\xf0\x00\x02\x00rachel\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",addr)
>>
>> This is OK, except that I'd like to change the text in the middle
>> ("rachel", which is the hostname FWIW), and the NUL padding needs to go
>> out to make the length 25 bytes (so the padding depends on the length of
>> the name).
>>
>> So I could do something like:
>> retpacket = "\xf0\x00\x02\x00"+socket.gethostname()
>> while len(retpacket) < 26:

>
> shouldn't that be 25?

Yes.

>> retpacket += "\x00"
>> s.sendto(retpacket, addr)
>>
>> But that feels "wrong". And Python in a Nutshell says its a bad idea -
>> "anti-idiom".
>>
>> Can anyone show me the true path?

>
> No idea, if it's the true path:
>
> hn = socket.gethostname()
> retpacket = '\xf0\x00\x02\x00%s%s' % (hn, (25-4-len(hn))*chr(0))
> s.sendto(retpacket, addr)

Probably better for efficiency, but not much for readability....

Anyone else?
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      07-21-2003
On Mon, 21 Jul 2003 10:32:08 GMT, Brad Hards <> wrote:

>Karl Scalet wrote:
>
>> kjockey schrieb:
>>> I have some simple UDP code that does:
>>>

>s.sendto("\xf0\x00\x02\x00rachel\x00\x00\x00\x00\ x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",addr)
>>>
>>> This is OK, except that I'd like to change the text in the middle
>>> ("rachel", which is the hostname FWIW), and the NUL padding needs to go
>>> out to make the length 25 bytes (so the padding depends on the length of
>>> the name).
>>>
>>> So I could do something like:
>>> retpacket = "\xf0\x00\x02\x00"+socket.gethostname()
>>> while len(retpacket) < 26:

>>
>> shouldn't that be 25?

>Yes.
>
>>> retpacket += "\x00"
>>> s.sendto(retpacket, addr)
>>>
>>> But that feels "wrong". And Python in a Nutshell says its a bad idea -
>>> "anti-idiom".

Well, adding the same character one by one is about as ugly as
sum = 14
while sum <25:
sum += 1
(Of course, if the original 14 units are also the same, as in integers,
sum += 25-sum
is not much better

But for small strings, I don't think it should be a big deal to do something like

retpacket = "\xf0\x00\x02\x00"+socket.gethostname()
retpacket += '\x00'*(25-len(retpacket))


>>>
>>> Can anyone show me the true path?

>>
>> No idea, if it's the true path:
>>
>> hn = socket.gethostname()
>> retpacket = '\xf0\x00\x02\x00%s%s' % (hn, (25-4-len(hn))*chr(0))
>> s.sendto(retpacket, addr)

>Probably better for efficiency, but not much for readability....
>
>Anyone else?


another alternative (untested!):

fmt = '\xf0\x00\x02\x00%s'+21*'\x00' # or write it out
...
retpacket = (fmt%socket.gethostname())[:25]
s.sendto(retpacket, addr)

Regards,
Bengt Richter
 
Reply With Quote
 
eichin@metacarta.com
Guest
Posts: n/a
 
      07-22-2003
I was going to suggest struct.pack:

>>> import struct
>>> struct.pack("<HH21s", 0xf0, 2, "rachel")

'\xf0\x00\x02\x00rachel\x00\x00\x00\x00\x00\x00\x0 0\x00\x00\x00\x00\x00\x00\x00\x00'

but it is, umm, "kind of perlish" - note also that the "21s" is
basically "string of up to 21 chars, pad with NUL if we run out" which
is probably what you wanted, but is saying it another way.

Another approach is the overpad and truncate:

msglen = 25
header = struct.pack("<HH", 0xf0, 2)
msg = header + "rachel" + "\0" * msglen
s.sendto(msg[0:msglen], addr)

ie. you know there will never be more than 25 bytes of pad (really,
more than 21, but "eww, literal numbers" presumably in your real code
you have some name attached to either the field length (which is
sufficient) in stead of the message length I've used here.)

 
Reply With Quote
 
Brad Hards
Guest
Posts: n/a
 
      07-22-2003
wrote:

>
>>>> import struct
>>>> struct.pack("<HH21s", 0xf0, 2, "rachel")

>

'\xf0\x00\x02\x00rachel\x00\x00\x00\x00\x00\x00\x0 0\x00\x00\x00\x00\x00\x00\x00\x00'
>
> but it is, umm, "kind of perlish" - note also that the "21s" is
> basically "string of up to 21 chars, pad with NUL if we run out" which
> is probably what you wanted, but is saying it another way.

This is nice, because it also deals with the case where the hostname would
otherwise overflow. It also matches my mental model - this isn't really a
string, its really a fixed length binary structure. Note that I don't
really know what it is - I'm trying to figure out a proprietary network
protocol.

Now I just have a question about portability. Will this break on a
big-endian box? That is, does:
struct.pack("<HH", 0xf0, 0x02)
produce:
'\x00\xf0\x00\x02'?

Would I be better off using "BBBB 21s" or "L 21s" as the format?

Brad

 
Reply With Quote
 
eichin@metacarta.com
Guest
Posts: n/a
 
      07-22-2003

> Now I just have a question about portability. Will this break on a
> big-endian box? That is, does:


read struct.__doc__, it explains about endianness in detail (in
particular, that's what the "<" at the beginning is all about.)
 
Reply With Quote
 
Brad Hards
Guest
Posts: n/a
 
      07-23-2003
wrote:

>
>> Now I just have a question about portability. Will this break on a
>> big-endian box? That is, does:

>
> read struct.__doc__, it explains about endianness in detail (in
> particular, that's what the "<" at the beginning is all about.)

Thankyou for your patience. Now that you mention it, I do remember reading
about that in the past, but I guess I'm more rusty than I thought.

Brad
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Object Oriented vs Pythonic Code, and Pythonic standards Carl J. Van Arsdall Python 4 02-07-2006 10:15 PM
porting non-malloc code to malloc micromysore@gmail.com C Programming 3 02-19-2005 05:39 AM
Malloc/Free - freeing memory allocated by malloc Peter C Programming 34 10-22-2004 10:23 AM
free'ing malloc'd structure with malloc'd members John C Programming 13 08-02-2004 11:45 AM
Re: free'ing malloc'd structure with malloc'd members ravi C Programming 0 07-30-2004 12:42 PM



Advertisments
 



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