Null-terminated strings with struct module?

R

Roy Smith

I need to generate packed binary data which includes null-terminated
strings mixed in with binary numbers. For example, the Python string
"foo" needs to become the 4-character binary string "foo\0", just like a
C string (don't ask, I didn't design the protocol).

What's the best way to do this? The "s" format specifier in struct
gives me fixed-length, non-null-terminated strings. Right now I'm doing:

s1 = self.directory + "\0"
s2 = self.fileName + "\0"
s3 = self.dateString + "\0"
s4 = self.name + "\0"
s5 = struct.pack ("!IB", self.id, self.perTargetFlag)
data = s1 + s2 + s3 + s4 + s5

which is pretty ugly. Is there a neater way to do this?

I know the string addition isn't the most efficient way to go, but for
this application, I prefer the clarity and don't mind the minor speed
hit.
 
P

Paul Rubin

Roy Smith said:
s1 = self.directory + "\0"
s2 = self.fileName + "\0"
s3 = self.dateString + "\0"
s4 = self.name + "\0"
s5 = struct.pack ("!IB", self.id, self.perTargetFlag)
data = s1 + s2 + s3 + s4 + s5

which is pretty ugly. Is there a neater way to do this?

Shrug.

data = "%s\0%s\0%s\0%s\0%s"% (self.directory, self.fileName,
self.dateString, self.name,
struct.pack (...))

Dunno if that's better or worse.
 
P

Peter Otten

Roy said:
I need to generate packed binary data which includes null-terminated
strings mixed in with binary numbers. For example, the Python string
"foo" needs to become the 4-character binary string "foo\0", just like a
C string (don't ask, I didn't design the protocol).

What's the best way to do this? The "s" format specifier in struct
gives me fixed-length, non-null-terminated strings. Right now I'm doing:

s1 = self.directory + "\0"
s2 = self.fileName + "\0"
s3 = self.dateString + "\0"
s4 = self.name + "\0"
s5 = struct.pack ("!IB", self.id, self.perTargetFlag)
data = s1 + s2 + s3 + s4 + s5

which is pretty ugly. Is there a neater way to do this?

I know the string addition isn't the most efficient way to go, but for
this application, I prefer the clarity and don't mind the minor speed
hit.

Does that rule out the following?

data = "\0".join([self.directory, self.fileName, ..., struct.pack(...)])

Or perhaps you could mangle attribute names (untested):

def __getattr__(self, name):
flag, name = name[0], name[1].lower() + name[2:]
value = getattr(self, name)
if flag == "Z":
return value + "\0"
else:
return struct.pack("!" + flag, value)

data = self.ZDirectory + ... + self.ZName + self.IId + self.BPerTargetFlag

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top