diff --git a/private/pkg/app/appproto/appproto.go b/private/pkg/app/appproto/appproto.go index ef1435dd2c..ec59bcf118 100644 --- a/private/pkg/app/appproto/appproto.go +++ b/private/pkg/app/appproto/appproto.go @@ -20,14 +20,10 @@ package appproto import ( - "bufio" - "bytes" "context" "fmt" "io" "path/filepath" - "unicode" - "unicode/utf8" "github.com/bufbuild/buf/private/pkg/app" "github.com/bufbuild/buf/private/pkg/protodescriptor" @@ -256,43 +252,3 @@ func newRunFunc(handler Handler) func(context.Context, app.Container) error { func NewResponseBuilder(container app.StderrContainer) ResponseBuilder { return newResponseBuilder(container) } - -// leadingWhitespace iterates through the given string, -// and returns the leading whitespace substring, if any, -// respecting utf-8 encoding. -// -// leadingWhitespace("\u205F foo ") -> "\u205F " -func leadingWhitespace(buf []byte) []byte { - leadingSize := 0 - iterBuf := buf - for len(iterBuf) > 0 { - r, size := utf8.DecodeRune(iterBuf) - // protobuf strings must always be valid UTF8 - // https://developers.google.com/protocol-buffers/docs/proto3#scalar - // Additionally, utf8.RuneError is not a space so we'll terminate - // and return the leading, valid, UTF8 whitespace sequence. - if !unicode.IsSpace(r) { - out := make([]byte, leadingSize) - copy(out, buf) - return out - } - leadingSize += size - iterBuf = iterBuf[size:] - } - return buf -} - -// scanWithPrefixAndLineEnding iterates over each of the given scanner's lines -// prepends prefix, and appends the newline sequence. -func scanWithPrefixAndLineEnding(scanner *bufio.Scanner, prefix []byte, newline []byte) []byte { - result := bytes.NewBuffer(nil) - result.Grow(averageInsertionPointSize) - for scanner.Scan() { - // These writes cannot fail, they will panic if they cannot - // allocate - _, _ = result.Write(prefix) - _, _ = result.Write(scanner.Bytes()) - _, _ = result.Write(newline) - } - return result.Bytes() -} diff --git a/private/pkg/app/appproto/response_writer.go b/private/pkg/app/appproto/response_writer.go index 72a3aa04d1..c6b1a6ddcc 100644 --- a/private/pkg/app/appproto/response_writer.go +++ b/private/pkg/app/appproto/response_writer.go @@ -19,6 +19,8 @@ import ( "bytes" "context" "io" + "unicode" + "unicode/utf8" "github.com/bufbuild/buf/private/pkg/storage" "go.uber.org/multierr" @@ -145,6 +147,46 @@ func writeInsertionPoint( return postInsertionBytes[:len(postInsertionBytes)-1], nil } +// leadingWhitespace iterates through the given string, +// and returns the leading whitespace substring, if any, +// respecting utf-8 encoding. +// +// leadingWhitespace("\u205F foo ") -> "\u205F " +func leadingWhitespace(buf []byte) []byte { + leadingSize := 0 + iterBuf := buf + for len(iterBuf) > 0 { + r, size := utf8.DecodeRune(iterBuf) + // protobuf strings must always be valid UTF8 + // https://developers.google.com/protocol-buffers/docs/proto3#scalar + // Additionally, utf8.RuneError is not a space so we'll terminate + // and return the leading, valid, UTF8 whitespace sequence. + if !unicode.IsSpace(r) { + out := make([]byte, leadingSize) + copy(out, buf) + return out + } + leadingSize += size + iterBuf = iterBuf[size:] + } + return buf +} + +// scanWithPrefixAndLineEnding iterates over each of the given scanner's lines +// prepends prefix, and appends the newline sequence. +func scanWithPrefixAndLineEnding(scanner *bufio.Scanner, prefix []byte, newline []byte) []byte { + result := bytes.NewBuffer(nil) + result.Grow(averageInsertionPointSize) + for scanner.Scan() { + // These writes cannot fail, they will panic if they cannot + // allocate + _, _ = result.Write(prefix) + _, _ = result.Write(scanner.Bytes()) + _, _ = result.Write(newline) + } + return result.Bytes() +} + type writeResponseOptions struct { insertionPointReadBucket storage.ReadBucket }