It feels like I must be missing where in the API this exists, but I'm looking for a way to create a Str from a Buf which contains my null-terminated Str values. I'm currently using InStream.readStrToken() but I hate to think of it checking each character for the terminating token when I already know how many bytes I'd like to pull out.
I can of course do InStream.readBuf() but I can't seem to find a nice way to generate a Str from a Buf, which seems a little strange.
Any tips? Thanks!
brianMon 7 Dec 2009
You can use sys::Buf.in to perform any I/O you want off a buf, plus almost all the InStream and OutStream methods are provided as convenience:
fansh> Buf().printLine("abc").flip.readAllStr
abc
Just remember that Buf works strictly in terms of bytes with some configurable charset (which defaults to UTF-8)
liamstaskMon 7 Dec 2009
Thanks for the quick response.
In that case, if I understand correctly, all the remaining data in the InStream will be extracted as Str, whereas there's plenty of remaining data in there that will not be part of the Str I'm interested in.
Is there a way to read just part of an InStream as a Str?
brianMon 7 Dec 2009
It depends on how you are breaking up bytes into chars:
if reading n bytes, then do readBuf(null, n).readAllStr (you are calling readAllStr on temp Buf, not the whole InStream)
Gotcha - it looks like readBufFully() is the API you sketched out there. It's not too big a deal, but having to block until all the data I asked for is received, without being able to specify a timeout feels slightly weird.
Otherwise, just using readBuf() I actually need to supply a Buf, but that's pretty OK since I know how big to make it and won't be too wasteful, etc. which looks something like:
b := Buf(expectedLen)
this.in.readBuf(b, b.capacity)
val := b.flip().readAllStr()
I realize that it's a little ridiculous to be complaining about an extra couple lines to extract this data, but with all the other tasty one-liners afforded by the API I figured I must be missing something! Obviously between these options, something will work nicely.
brianMon 7 Dec 2009
Yeah, I forgot that readBuf returns an Int rather than the Buf, so it makes a one liner tricky.
Maybe what we really need is something which mimics readBuf and readBufFully with char data?
virtual Int? readBuf(Buf buf, Int n)
Buf readBufFully(Buf? buf, Int n)
virtual Int? readStrBuf(StrBuf buf, Int n)
StrBuf readStrBufFully(StrBuf? buf, Int n)
What does everything think about those enhancements?
liamstaskTue 8 Dec 2009
Those sound pretty nice and consistent to me.
DanielFathTue 8 Dec 2009
They seem right. This is InStream, right?
brianTue 8 Dec 2009
Promoted to ticket #853 and assigned to brian
brianTue 8 Dec 2009
Renamed from Str direct from Buf? to InStream::readStrBuf, readStrBufFully
brianFri 18 Dec 2009
Renamed from InStream::readStrBuf, readStrBufFully to InStream::readChars
brianFri 18 Dec 2009
Ticket resolved in 1.0.48
I added a new method:
**
** Read the next n chars from the stream as a Str using the
** current `charset`. Block until exactly n chars have been
** read or throw IOErr if end of stream is reached first.
**
Str readChars(Int n)
A convenience also added to Buf.
The original idea of reading available chars into a StrBuf is problematic to deal with async availability when reading multiple-byte charsets. Having "read fully" semantics is consistent with all the other text based I/O.
liamstask Mon 7 Dec 2009
It feels like I must be missing where in the API this exists, but I'm looking for a way to create a Str from a Buf which contains my null-terminated Str values. I'm currently using
InStream.readStrToken()
but I hate to think of it checking each character for the terminating token when I already know how many bytes I'd like to pull out.I can of course do
InStream.readBuf()
but I can't seem to find a nice way to generate a Str from a Buf, which seems a little strange.Any tips? Thanks!
brian Mon 7 Dec 2009
You can use
sys::Buf.in
to perform any I/O you want off a buf, plus almost all the InStream and OutStream methods are provided as convenience:Just remember that Buf works strictly in terms of bytes with some configurable charset (which defaults to UTF-8)
liamstask Mon 7 Dec 2009
Thanks for the quick response.
In that case, if I understand correctly, all the remaining data in the InStream will be extracted as Str, whereas there's plenty of remaining data in there that will not be part of the Str I'm interested in.
Is there a way to read just part of an InStream as a Str?
brian Mon 7 Dec 2009
It depends on how you are breaking up bytes into chars:
sys::InStream.readStrToken
liamstask Mon 7 Dec 2009
Gotcha - it looks like readBufFully() is the API you sketched out there. It's not too big a deal, but having to block until all the data I asked for is received, without being able to specify a timeout feels slightly weird.
Otherwise, just using readBuf() I actually need to supply a Buf, but that's pretty OK since I know how big to make it and won't be too wasteful, etc. which looks something like:
I realize that it's a little ridiculous to be complaining about an extra couple lines to extract this data, but with all the other tasty one-liners afforded by the API I figured I must be missing something! Obviously between these options, something will work nicely.
brian Mon 7 Dec 2009
Yeah, I forgot that readBuf returns an Int rather than the Buf, so it makes a one liner tricky.
Maybe what we really need is something which mimics readBuf and readBufFully with char data?
What does everything think about those enhancements?
liamstask Tue 8 Dec 2009
Those sound pretty nice and consistent to me.
DanielFath Tue 8 Dec 2009
They seem right. This is
InStream
, right?brian Tue 8 Dec 2009
Promoted to ticket #853 and assigned to brian
brian Tue 8 Dec 2009
Renamed from Str direct from Buf? to InStream::readStrBuf, readStrBufFully
brian Fri 18 Dec 2009
Renamed from InStream::readStrBuf, readStrBufFully to InStream::readChars
brian Fri 18 Dec 2009
Ticket resolved in 1.0.48
I added a new method:
A convenience also added to Buf.
The original idea of reading available chars into a StrBuf is problematic to deal with async availability when reading multiple-byte charsets. Having "read fully" semantics is consistent with all the other text based I/O.
liamstask Sat 19 Dec 2009
Great - thanks!