package binarystr import ( `errors` `io` `strings` ) /* Read conforms to an [io.Reader]. It returns plain data decoded from bitstring encoding in e's read source. IMPORTANT: Read will return a [BadNumOctErr] if the amount of data in e's read source is not at least len(b) * 8! ONE BYTE in b equals EIGHT BYTES from e's read source! Likewise, n will ALWAYS be len(b), but the number of bytes actually read from e's internal reader will ALWAYS be n*8! In this case, b will still be populated with the available decoded data, and err ([BadNumOctErr])'s [BadNumOctErr.Rem] method will contain the remaining bitstring (if there is any left over) after decoding the octets that were returned (if any). IMPORTANT: Read will return a [BadBinCharErr] if it encounters any character in e's read source that is not '0' or '1'! THIS INCLUDES WHITESPACE due to the buffer size calculation (unlike [StrToBytes]); it is NOT skipped! */ func (e *Decoder) Read(b []byte) (n int, err error) { var inN int var s string var endIdx int var rem string var buf []byte defer func() { if b != nil && buf != nil { s = BytesToStr(buf) copy(b, []byte(s)) } }() if len(b) == 0 { return } buf = make([]byte, len(b)*8) if inN, err = e.r.Read(buf); err != nil { // This is caught/handled below. if errors.Is(err, io.EOF) { err = nil } else { return } } if inN < len(buf) { } if inN != len(buf) { err = &BadNumOctErr{ posByte: uint64(inN), posRune: uint64(inN), rem: rem, // We hit the end too "early" so there is no "remaining". } return } return } /* ReadString returns a bitstring-encoded [string] from the entirety of the data in the source reader of e. IMPORTANT: If e's source reader is a non-terminating stream (e.g. a [math/rand.Rand]), this function will NEVER RETURN (and will likely consume all memory). YOU HAVE BEEN WARNED. n is the number of bytes read from e's source reader. */ func (e *Decoder) ReadString() (s string, n uint64, err error) { var inN int var buf []byte var rErr error var sb *strings.Builder = new(strings.Builder) defer func() { if sb != nil { s = sb.String() } }() for { buf = make([]byte, bufSz) inN, rErr = e.r.Read(buf) n += uint64(inN) if inN != 0 { if inN < bufSz { buf = buf[:inN] } sb.WriteString(BytesToStr(buf)) } else { if errors.Is(rErr, io.EOF) { rErr = nil } break } if rErr != nil { err = rErr return } } return }