gowebbuild/vendor/github.com/evanw/esbuild/internal/helpers/joiner.go

87 lines
1.8 KiB
Go
Raw Normal View History

package helpers
import (
"bytes"
"strings"
)
// This provides an efficient way to join lots of big string and byte slices
// together. It avoids the cost of repeatedly reallocating as the buffer grows
// by measuring exactly how big the buffer should be and then allocating once.
// This is a measurable speedup.
type Joiner struct {
lastByte byte
strings []joinerString
bytes []joinerBytes
length uint32
}
type joinerString struct {
data string
offset uint32
}
type joinerBytes struct {
data []byte
offset uint32
}
func (j *Joiner) AddString(data string) {
if len(data) > 0 {
j.lastByte = data[len(data)-1]
}
j.strings = append(j.strings, joinerString{data, j.length})
j.length += uint32(len(data))
}
func (j *Joiner) AddBytes(data []byte) {
if len(data) > 0 {
j.lastByte = data[len(data)-1]
}
j.bytes = append(j.bytes, joinerBytes{data, j.length})
j.length += uint32(len(data))
}
func (j *Joiner) LastByte() byte {
return j.lastByte
}
func (j *Joiner) Length() uint32 {
return j.length
}
func (j *Joiner) EnsureNewlineAtEnd() {
if j.length > 0 && j.lastByte != '\n' {
j.AddString("\n")
}
}
func (j *Joiner) Done() []byte {
if len(j.strings) == 0 && len(j.bytes) == 1 && j.bytes[0].offset == 0 {
// No need to allocate if there was only a single byte array written
return j.bytes[0].data
}
buffer := make([]byte, j.length)
for _, item := range j.strings {
copy(buffer[item.offset:], item.data)
}
for _, item := range j.bytes {
copy(buffer[item.offset:], item.data)
}
return buffer
}
func (j *Joiner) Contains(s string, b []byte) bool {
for _, item := range j.strings {
if strings.Contains(item.data, s) {
return true
}
}
for _, item := range j.bytes {
if bytes.Contains(item.data, b) {
return true
}
}
return false
}