188 lines
4.4 KiB
Go
188 lines
4.4 KiB
Go
package strutil
|
|
|
|
import (
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
// FillBytes fill the destination byte array with the given pattern.
|
|
func FillBytes(dst []byte, pattern []byte) {
|
|
for i := 0; i < len(dst); i++ {
|
|
dst[i] = pattern[i%len(pattern)]
|
|
}
|
|
}
|
|
|
|
// FillByte fills the destination byte array with a single byte.
|
|
func FillByte(dst []byte, pattern byte) {
|
|
for i := 0; i < len(dst); i++ {
|
|
dst[i] = pattern
|
|
}
|
|
}
|
|
|
|
// StrPad method pads the input string with the padString until the resulting string reaches the given length
|
|
func StrPad(input string, padLength int, padString string, rightPad bool) (output string) {
|
|
var (
|
|
inputLength = len(input)
|
|
padStringLength = len(padString)
|
|
)
|
|
if inputLength >= padLength {
|
|
return input
|
|
}
|
|
|
|
var (
|
|
repeat = int(math.Ceil(float64(1) + (float64(padLength-padStringLength))/float64(padStringLength)))
|
|
builder strings.Builder
|
|
)
|
|
builder.Grow(inputLength + padStringLength*repeat)
|
|
if rightPad {
|
|
builder.WriteString(input)
|
|
for i := 0; i < repeat; i++ {
|
|
builder.WriteString(padString)
|
|
}
|
|
output = builder.String()[:padLength]
|
|
} else {
|
|
for i := 0; i < repeat; i++ {
|
|
builder.WriteString(padString)
|
|
}
|
|
builder.WriteString(input)
|
|
output = builder.String()[builder.Len()-padLength:]
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// StrPadSingle method pads the input string with a single character until the resulting string reaches the given length
|
|
func StrPadSingle(input string, padLength int, pad byte, rightPad bool) (output string) {
|
|
var (
|
|
inputLength = len(input)
|
|
)
|
|
if inputLength >= padLength {
|
|
return input
|
|
}
|
|
|
|
var (
|
|
builder strings.Builder
|
|
)
|
|
builder.Grow(inputLength + padLength)
|
|
if rightPad {
|
|
builder.WriteString(input)
|
|
for i := 0; i < padLength; i++ {
|
|
builder.WriteByte(pad)
|
|
}
|
|
output = builder.String()[:padLength]
|
|
} else {
|
|
for i := 0; i < padLength; i++ {
|
|
builder.WriteByte(pad)
|
|
}
|
|
builder.WriteString(input)
|
|
output = builder.String()[builder.Len()-padLength:]
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// BytesPad method pads the input byte array with the padData byte array until the resulting string reaches the given length
|
|
func BytesPad(input []byte, padLength int, padData []byte, rightPad bool) (output []byte) {
|
|
var (
|
|
inputLength = len(input)
|
|
padDataLength = len(padData)
|
|
)
|
|
if inputLength >= padLength {
|
|
output = make([]byte, inputLength)
|
|
copy(output, input)
|
|
return
|
|
}
|
|
|
|
var (
|
|
repeat = int(math.Ceil(float64(1) + (float64(padLength-padDataLength))/float64(padDataLength)))
|
|
maxFillLength = repeat * padDataLength
|
|
bufSize = inputLength + repeat*padDataLength
|
|
padArea, fillArea []byte
|
|
)
|
|
|
|
output = make([]byte, bufSize)
|
|
|
|
if rightPad {
|
|
fillArea, padArea = output[0:inputLength], output[inputLength:bufSize]
|
|
output = output[:padLength]
|
|
} else {
|
|
fillArea, padArea = output[maxFillLength:bufSize], output[0:maxFillLength]
|
|
output = output[inputLength+maxFillLength-padLength:]
|
|
}
|
|
|
|
// copy data
|
|
copy(fillArea, input)
|
|
// fill pad
|
|
for i := 0; i < repeat; i++ {
|
|
copy(padArea[:padDataLength], padData)
|
|
padArea = padArea[padDataLength:]
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// BytesPad method pads the input byte array with a single byte until the resulting string reaches the given length
|
|
func BytesPadSingle(input []byte, padLength int, pad byte, rightPad bool) (output []byte) {
|
|
var (
|
|
inputLength = len(input)
|
|
)
|
|
if inputLength >= padLength {
|
|
output = make([]byte, inputLength)
|
|
copy(output, input)
|
|
return
|
|
}
|
|
|
|
var (
|
|
maxFillLength = padLength
|
|
bufSize = inputLength + padLength
|
|
padArea, fillArea []byte
|
|
)
|
|
|
|
output = make([]byte, bufSize)
|
|
|
|
if rightPad {
|
|
fillArea, padArea = output[0:inputLength], output[inputLength:bufSize]
|
|
output = output[:padLength]
|
|
} else {
|
|
fillArea, padArea = output[maxFillLength:bufSize], output[0:maxFillLength]
|
|
output = output[inputLength+maxFillLength-padLength:]
|
|
}
|
|
|
|
// copy data
|
|
copy(fillArea, input)
|
|
// fill pad
|
|
FillByte(padArea, pad)
|
|
return
|
|
}
|
|
|
|
// BytesUnPadSingle method removes a given pad character from both ends.
|
|
func BytesUnPadSingle(input []byte, pad byte, rightPad bool, copyData bool) (output []byte) {
|
|
var (
|
|
limit = len(input)
|
|
offset = 0
|
|
)
|
|
if rightPad {
|
|
for ; limit > offset; limit-- {
|
|
if input[limit-1] != pad {
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
for ; offset < limit; offset++ {
|
|
if input[offset] != pad {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if limit-offset < 1 {
|
|
return
|
|
}
|
|
if copyData {
|
|
output = make([]byte, limit-offset)
|
|
copy(output, input[offset:limit])
|
|
} else {
|
|
output = input[offset:limit]
|
|
}
|
|
return
|
|
}
|