Skip to content

Commit

Permalink
Merge pull request #3 from clear-street/skurella/add-raw-value-trim-m…
Browse files Browse the repository at this point in the history
…ethods

Add raw value trim methods
  • Loading branch information
sidkurella authored Feb 8, 2024
2 parents 26c0724 + d929357 commit a12d767
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 38 deletions.
49 changes: 49 additions & 0 deletions buff.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fixedwidth
import (
"bytes"
"errors"
"strings"
"unicode/utf8"
)

Expand Down Expand Up @@ -183,6 +184,54 @@ type rawValue struct {
codepointIndices []int
}

func (r rawValue) trimLeft(cutset string) rawValue {
newData := strings.TrimLeft(r.data, cutset)
leftRemovedBytes := len(r.data) - len(newData)

if r.codepointIndices == nil {
return rawValue{data: newData}
}

newIndices := r.trimCodepointIndices(leftRemovedBytes, 0)
return rawValue{data: newData, codepointIndices: newIndices}
}

func (r rawValue) trimRight(cutset string) rawValue {
newData := strings.TrimRight(r.data, cutset)
rightRemovedBytes := len(r.data) - len(newData)

if r.codepointIndices == nil {
return rawValue{data: newData}
}

newIndices := r.trimCodepointIndices(0, rightRemovedBytes)
return rawValue{data: newData, codepointIndices: newIndices}
}

func (r rawValue) trim(cutset string) rawValue {
leftTrimmed := strings.TrimLeft(r.data, cutset)
leftRemovedBytes := len(r.data) - len(leftTrimmed)
bothTrimmed := strings.TrimRight(leftTrimmed, cutset)
rightRemovedBytes := len(leftTrimmed) - len(bothTrimmed)

if r.codepointIndices == nil {
return rawValue{data: bothTrimmed}
}

newIndices := r.trimCodepointIndices(leftRemovedBytes, rightRemovedBytes)
return rawValue{data: bothTrimmed, codepointIndices: newIndices}
}

func (r rawValue) trimCodepointIndices(leftRemovedBytes int, rightRemovedBytes int) []int {
newIndices := make([]int, 0, len(r.codepointIndices))
for _, idx := range r.codepointIndices {
if idx >= leftRemovedBytes && idx < len(r.data)-rightRemovedBytes {
newIndices = append(newIndices, idx-leftRemovedBytes)
}
}
return newIndices
}

func newRawValue(data string, useCodepointIndices bool) (rawValue, error) {
value := rawValue{
data: data,
Expand Down
49 changes: 11 additions & 38 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"
"reflect"
"strconv"
"strings"
)

var (
Expand Down Expand Up @@ -197,26 +196,20 @@ func (d *Decoder) readLine(v reflect.Value) (err error, ok bool) {
}

func rawValueFromLine(value rawValue, startPos, endPos int, format format) rawValue {
var trimFunc func(in string) (out string, leftRemoved int, rightRemoved int)
var trimFunc func(r rawValue) rawValue

switch format.alignment {
case left:
trimFunc = func(s string) (out string, leftRemoved int, rightRemoved int) {
out = strings.TrimRight(s, string(format.padChar))
return out, 0, len(s) - len(out)
case left: // Aligned left, so trim from right side.
trimFunc = func(r rawValue) rawValue {
return r.trimRight(string(format.padChar))
}
case right:
trimFunc = func(s string) (out string, leftRemoved int, rightRemoved int) {
out = strings.TrimLeft(s, string(format.padChar))
return out, len(s) - len(out), 0
case right: // Aligned right, so trim from left side.
trimFunc = func(r rawValue) rawValue {
return r.trimLeft(string(format.padChar))
}
default:
trimFunc = func(s string) (out string, leftRemoved int, rightRemoved int) {
leftTrimmed := strings.TrimLeft(s, string(format.padChar))
leftRemoved = len(s) - len(leftTrimmed)
rightTrimmed := strings.TrimRight(leftTrimmed, string(format.padChar))
rightRemoved = len(leftTrimmed) - len(rightTrimmed)
return rightTrimmed, leftRemoved, rightRemoved
trimFunc = func(r rawValue) rawValue {
return r.trim(string(format.padChar))
}
}

Expand Down Expand Up @@ -245,35 +238,15 @@ func rawValueFromLine(value rawValue, startPos, endPos int, format format) rawVa
}
}

// Trim the new line data.
newLineData, leftRemovedBytes, rightRemovedBytes := trimFunc(lineData)
trimmedIndices := newIndices
if leftRemovedBytes > 0 || rightRemovedBytes > 0 {
// We must trim our codepoint indices list in order to match
// the newly trimmed line data string.
trimmedIndices = []int{}
for _, idx := range newIndices {
if idx >= leftRemovedBytes && idx < len(lineData)-rightRemovedBytes {
trimmedIndices = append(trimmedIndices, idx-leftRemovedBytes)
}
}
}

return rawValue{
data: newLineData,
codepointIndices: trimmedIndices,
}
return trimFunc(rawValue{data: lineData, codepointIndices: newIndices})
} else {
if len(value.data) == 0 || startPos > len(value.data) {
return rawValue{data: ""}
}
if endPos > len(value.data) {
endPos = len(value.data)
}
newLineData, _, _ := trimFunc(value.data[startPos-1 : endPos])
return rawValue{
data: newLineData,
}
return trimFunc(rawValue{data: value.data[startPos-1 : endPos]})
}
}

Expand Down

0 comments on commit a12d767

Please sign in to comment.