Buffer to string

  • Thread starter Jari Williamsson
  • Start date
J

Jari Williamsson

I have a buffer (stored in a String class) with a NULL-terminated
C-style string inside, what's the most efficient approach to get that
text string up to the NULL?


Best regards,

Jari Williamsson
 
E

elof

Hi

One approach could be to use split and a regexp:

s = "hi"
s << 0.chr
s << "there"
p s
p s.split(/\000/).first

Kristian
 
P

Paul Irofti

I have a buffer (stored in a String class) with a NULL-terminated
C-style string inside, what's the most efficient approach to get that
text string up to the NULL?

$ irb
irb(main):001:0> s = "hello\0"
=> "hello\000"
irb(main):002:0> s.chomp("\0")
=> "hello"
irb(main):003:0>

See String#chomp(!) for more details.
 
E

elof

If you really only ever care about the first string then

s.match(/\000/).pre_match

is an alternative which looks like it could be less work for the machine
since it can stop after the first \000 rather than have to split the entire
string.

Are you looking at strings huge enough that efficiency at this level
matters?

Kristian
 
P

Paul Irofti

If you really only ever care about the first string then

s.match(/\000/).pre_match

is an alternative which looks like it could be less work for the machine
since it can stop after the first \000 rather than have to split the entire
string.

Are you looking at strings huge enough that efficiency at this level
matters?

I think the OP made it pretty clear: there is *one* C-Style string
inside a String Class buffer and wants to retrive it w/o the zero
termination.
 
T

Tom M

I have a buffer (stored in a String class) with a NULL-terminated
C-style string inside, what's the most efficient approach to get that
text string up to the NULL?

Best regards,

Jari Williamsson

Would buf.unpack("a*") work?
 
J

Jari Williamsson

Paul said:
$ irb
irb(main):001:0> s = "hello\0"
=> "hello\000"
irb(main):002:0> s.chomp("\0")
=> "hello"

This particular approach wouldn't work, since it can't be guaranteed
that every byte remaining in the buffer (after the termination) is NULL:
irb(main):001:0> s = "Hello\0\1\0"
=> "Hello\000\001\000"
irb(main):002:0> s.chomp("\0")
=> "Hello\000\001"

But the other suggestions work. Thanks!


Best regards,

Jari Williamsson
 
P

Paul Irofti

Would buf.unpack("a*") work?

Depends on the raw data contained within the C zero terminated string.
If its plain text "a*" wouldn't work, but "Z*" might.

For unpack I'd suggest seeing String#unpack for other formating and the
way to combine the different format markers in order to retrieve the
wanted data.

$ irb
irb(main):001:0> s = "Hello\0"
=> "Hello\000"
irb(main):002:0> s.unpack("a*")
=> ["Hello\000"]
irb(main):003:0> s.unpack("Z*")
=> ["Hello"]
 
P

Paul Irofti

This particular approach wouldn't work, since it can't be guaranteed
that every byte remaining in the buffer (after the termination) is NULL:
irb(main):001:0> s = "Hello\0\1\0"
=> "Hello\000\001\000"
irb(main):002:0> s.chomp("\0")
=> "Hello\000\001"

But the other suggestions work. Thanks!

I did not consider trailing garbage, sorry about that. I thought, from
your original question, that you only have a NULL terminated string and
not anything else.
 
P

Paolo Bonzini

Would buf.unpack("a*") work?

No, that's buf.unpack("Z*") that you want

irb(main):001:0> s = "hi"
=> "hi"
irb(main):002:0> s << 0.chr
=> "hi\000"
irb(main):003:0> s << "there"
=> "hi\000there"
irb(main):007:0> s.unpack("a*")
=> ["hi\000there"]
irb(main):014:0> s.unpack("Z*")
=> ["hi"]
 

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

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top