Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: bytes, strings: add ReadBytes(byte) ([]byte, error), ReadString(byte) (string, error) to Reader #13889

Closed
hirochachacha opened this issue Jan 9, 2016 · 4 comments

Comments

@hirochachacha
Copy link
Contributor

One of the use-cases of byte.Reader is parsing a binary format.
There are some formats use an unpredictable length structure such as NUL-terminated string.
Unfortunately, current API set doesn't treat it well.

For example:

br := byte.NewReader(data)

func decodeCString(br *bytes.Reader, data []byte) string {
  rest := data[br.Size()-br.Len():]

  i := bytes.IndexByte(rest, 0x0)
  if i == -1 {
    panic("invalid")
  }

  br.Seek(i+1, 1)

  return string(rest[:i])
}

I think decodeCString has 2 problems.

  1. it still need to keep data variable.
  2. it manually update internal state by .Size, .Len and .Seek.

I want to write it like this:

func decodeCString(br *bytes.Reader) string {
  bs, err := br.ReadBytes(0x0)
  if err != nil {
    panic("invalid")
  }

  return string(bs[:len(bs)-1])
}

I know some people prefer bytes.Buffer because of convenience, even if data is read only.
I want to discourage such a situation.

Same things are also applicable to strings.Reader.

Thank you.

hiro

@hirochachacha hirochachacha changed the title proposal: bytes, strings, io: add ReadBytes(byte) ([]byte, error), ReadString(byte) (string, error) to Reader proposal: bytes, strings: add ReadBytes(byte) ([]byte, error), ReadString(byte) (string, error) to Reader Jan 9, 2016
@bradfitz
Copy link
Contributor

bradfitz commented Jan 9, 2016

Here's a simpler, faster version:

func cstr(b []byte) string {
    if i := bytes.IndexByte(b, 0); i != -1 {
        return string(b[:i])
    }
    return ""
}

Notice that not only does it not need any changed to bytes.Reader, it also doesn't even need bytes.Reader.

And if you needed to parse these from a stream, you can use bufio.Reader.ReadBytes:

https://golang.org/pkg/bufio/#Reader.ReadBytes

I think there's nothing to do here.

@hirochachacha
Copy link
Contributor Author

The problem in my mind is use with binary.Read.

https://github.com/golang/go/blob/master/src/debug/elf/file.go#L480-L508

And if you needed to parse these from a stream, you can use bufio.Reader.ReadBytes:

I think so, but it is bigger than problem itself, I think. That's my point.

@hirochachacha
Copy link
Contributor Author

And if you needed to parse these from a stream, you can use bufio.Reader.ReadBytes:

I think so, but it is bigger than problem itself, I think. That's my point.

Sorry, I was mistaken.

@hirochachacha
Copy link
Contributor Author

Thank you for commenting.

@golang golang locked and limited conversation to collaborators Jan 17, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants