You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wc-go/pkg/wc/complex-counter.go

69 lines
1.4 KiB

package wc
import (
"bytes"
"unicode"
)
type ComplexCount struct {
CharCount int64
WordCount int64
LineCount int64
MaxLineLength int64
}
type ComplexChunk struct {
PrevRune rune
Chunk []byte
}
func GetComplexCount(chunk ComplexChunk) ComplexCount {
var count = ComplexCount{}
var lineLength int64
runes := bytes.Runes(chunk.Chunk)
prevRuneIsSpace := unicode.IsSpace(chunk.PrevRune)
var linepos int64
for _, b := range runes {
count.CharCount++
if b == '\n' || b == '\r' || b == '\f' {
if linepos > lineLength {
lineLength = linepos
}
linepos = 0
if b == '\n' {
count.LineCount++
}
}
if unicode.IsSpace(b) {
if b == '\t' {
linepos += 8 - (linepos % 8)
} else if b != '\n' && b != '\r' && b != '\f' && b != '\v' {
linepos++
}
prevRuneIsSpace = true
} else {
linepos++
if prevRuneIsSpace {
count.WordCount++
}
prevRuneIsSpace = false
}
}
count.MaxLineLength = lineLength
return count
}
func ConcurrentComplexChunkCounter(chunks <-chan ComplexChunk, counts chan<- ComplexCount) {
var totalCount ComplexCount
for chunk := range chunks {
count := GetComplexCount(chunk)
totalCount.CharCount += count.CharCount
totalCount.WordCount += count.WordCount
totalCount.LineCount += count.LineCount
if count.MaxLineLength > totalCount.MaxLineLength {
totalCount.MaxLineLength = count.MaxLineLength
}
}
counts <- totalCount
}