package norm
import (
)
const MaxSegmentSize = maxByteBufferSize
type Iter struct {
rb reorderBuffer
buf [maxByteBufferSize]byte
info Properties
next iterFunc
asciiF iterFunc
p int
multiSeg []byte
}
type iterFunc func(*Iter) []byte
func ( *Iter) ( Form, []byte) {
.p = 0
if len() == 0 {
.setDone()
.rb.nsrc = 0
return
}
.multiSeg = nil
.rb.init(, )
.next = .rb.f.nextMain
.asciiF = nextASCIIBytes
.info = .rb.f.info(.rb.src, .p)
.rb.ss.first(.info)
}
func ( *Iter) ( Form, string) {
.p = 0
if len() == 0 {
.setDone()
.rb.nsrc = 0
return
}
.multiSeg = nil
.rb.initString(, )
.next = .rb.f.nextMain
.asciiF = nextASCIIString
.info = .rb.f.info(.rb.src, .p)
.rb.ss.first(.info)
}
func ( *Iter) ( int64, int) (int64, error) {
var int64
switch {
case 0:
=
case 1:
= int64(.p) +
case 2:
= int64(.rb.nsrc) +
default:
return 0, fmt.Errorf("norm: invalid whence")
}
if < 0 {
return 0, fmt.Errorf("norm: negative position")
}
if int() >= .rb.nsrc {
.setDone()
return int64(.p), nil
}
.p = int()
.multiSeg = nil
.next = .rb.f.nextMain
.info = .rb.f.info(.rb.src, .p)
.rb.ss.first(.info)
return , nil
}
func ( *Iter) (, int) []byte {
if .rb.src.bytes == nil {
return .buf[:copy(.buf[:], .rb.src.str[:])]
}
return .rb.src.bytes[:]
}
func ( *Iter) () int {
return .p
}
func ( *Iter) () {
.next = nextDone
.p = .rb.nsrc
}
func ( *Iter) () bool {
return .p >= .rb.nsrc
}
func ( *Iter) () []byte {
return .next()
}
func ( *Iter) []byte {
:= .p + 1
if >= .rb.nsrc {
:= .p
.setDone()
return .rb.src.bytes[:]
}
if .rb.src.bytes[] < utf8.RuneSelf {
:= .p
.p =
return .rb.src.bytes[:]
}
.info = .rb.f.info(.rb.src, .p)
.next = .rb.f.nextMain
return .next()
}
func ( *Iter) []byte {
:= .p + 1
if >= .rb.nsrc {
.buf[0] = .rb.src.str[.p]
.setDone()
return .buf[:1]
}
if .rb.src.str[] < utf8.RuneSelf {
.buf[0] = .rb.src.str[.p]
.p =
return .buf[:1]
}
.info = .rb.f.info(.rb.src, .p)
.next = .rb.f.nextMain
return .next()
}
func ( *Iter) []byte {
:= .p
:= + hangulUTF8Size
if >= .rb.nsrc {
.setDone()
} else if .rb.src.hangul() == 0 {
.rb.ss.next(.info)
.info = .rb.f.info(.rb.src, .p)
.next = .rb.f.nextMain
return .next()
}
.p =
return .buf[:decomposeHangul(.buf[:], .rb.src.hangul())]
}
func ( *Iter) []byte {
return nil
}
func ( *Iter) []byte {
:= 0
:= .multiSeg
for = 1; < len() && !utf8.RuneStart([]); ++ {
}
for < len() {
:= .rb.f.info(input{bytes: }, )
if .BoundaryBefore() {
.multiSeg = [:]
return [:]
}
+= int(.size)
}
.next = .rb.f.nextMain
return .next()
}
func ( *Iter) []byte {
:= 0
:= .multiSeg
for < len() {
:= .rb.f.info(input{bytes: }, )
if .BoundaryBefore() {
.rb.compose()
:= .buf[:.rb.flushCopy(.buf[:])]
.rb.insertUnsafe(input{bytes: }, , )
.multiSeg = [+int(.size):]
return
}
.rb.insertUnsafe(input{bytes: }, , )
+= int(.size)
}
.multiSeg = nil
.next = nextComposed
return doNormComposed()
}
func ( *Iter) ( []byte) {
:= 0
, := .p, 0
for {
if := int(.info.size); <= 1 {
.rb.ss = 0
:= .p
.p++
if .p >= .rb.nsrc {
.setDone()
return .returnSlice(, .p)
} else if .rb.src._byte(.p) < utf8.RuneSelf {
.next = .asciiF
return .returnSlice(, .p)
}
++
} else if := .info.Decomposition(); != nil {
:= + len()
if > 0 {
.rb.src.copySlice(.buf[:], , .p)
if > len(.buf) {
return .buf[:]
}
} else if .info.multiSegment() {
if .multiSeg == nil {
.multiSeg =
.next = nextMulti
return nextMulti()
}
= .multiSeg
.multiSeg = nil
= len()
}
:= .info.tccc
if .p += ; .p >= .rb.nsrc {
.setDone()
.info = Properties{}
} else {
.info = .rb.f.info(.rb.src, .p)
}
switch .rb.ss.next(.info) {
case ssOverflow:
.next = nextCGJDecompose
fallthrough
case ssStarter:
if > 0 {
copy(.buf[:], )
return .buf[:]
}
return
}
copy(.buf[:], )
=
, = .p,
if .info.ccc < {
goto
}
continue
} else if := .rb.src.hangul(.p); != 0 {
= decomposeHangul(.buf[:], )
.p += hangulUTF8Size
, = .p,
if .p >= .rb.nsrc {
.setDone()
break
} else if .rb.src.hangul(.p) != 0 {
.next = nextHangul
return .buf[:]
}
} else {
:= +
if > len(.buf) {
break
}
=
.p +=
}
if .p >= .rb.nsrc {
.setDone()
break
}
:= .info.tccc
.info = .rb.f.info(.rb.src, .p)
if := .rb.ss.next(.info); == ssStarter {
break
} else if == ssOverflow {
.next = nextCGJDecompose
break
}
if .info.ccc < {
goto
}
}
if == 0 {
return .returnSlice(, .p)
} else if < .p {
.rb.src.copySlice(.buf[:], , .p)
}
return .buf[:]
:
.rb.src.copySlice(.buf[:], , .p)
.rb.insertDecomposed(.buf[0:])
return doNormDecomposed()
}
func ( *Iter) []byte {
for {
.rb.insertUnsafe(.rb.src, .p, .info)
if .p += int(.info.size); .p >= .rb.nsrc {
.setDone()
break
}
.info = .rb.f.info(.rb.src, .p)
if .info.ccc == 0 {
break
}
if := .rb.ss.next(.info); == ssOverflow {
.next = nextCGJDecompose
break
}
}
return .buf[:.rb.flushCopy(.buf[:])]
}
func ( *Iter) []byte {
.rb.ss = 0
.rb.insertCGJ()
.next = nextDecomposed
.rb.ss.first(.info)
:= doNormDecomposed()
return
}
func ( *Iter) []byte {
, := 0, .p
var uint8
for {
if !.info.isYesC() {
goto
}
= .info.tccc
:= int(.info.size)
if == 0 {
= 1
}
:= +
if > len(.buf) {
break
}
=
.p +=
if .p >= .rb.nsrc {
.setDone()
break
} else if .rb.src._byte(.p) < utf8.RuneSelf {
.rb.ss = 0
.next = .asciiF
break
}
.info = .rb.f.info(.rb.src, .p)
if := .rb.ss.next(.info); == ssStarter {
break
} else if == ssOverflow {
.next = nextCGJCompose
break
}
if .info.ccc < {
goto
}
}
return .returnSlice(, .p)
:
.p =
.info = .rb.f.info(.rb.src, .p)
.rb.ss.first(.info)
if .info.multiSegment() {
:= .info.Decomposition()
:= .rb.f.info(input{bytes: }, 0)
.rb.insertUnsafe(input{bytes: }, 0, )
.multiSeg = [int(.size):]
.next = nextMultiNorm
return nextMultiNorm()
}
.rb.ss.first(.info)
.rb.insertUnsafe(.rb.src, .p, .info)
return doNormComposed()
}
func ( *Iter) []byte {
for {
if .p += int(.info.size); .p >= .rb.nsrc {
.setDone()
break
}
.info = .rb.f.info(.rb.src, .p)
if := .rb.ss.next(.info); == ssStarter {
break
} else if == ssOverflow {
.next = nextCGJCompose
break
}
.rb.insertUnsafe(.rb.src, .p, .info)
}
.rb.compose()
:= .buf[:.rb.flushCopy(.buf[:])]
return
}
func ( *Iter) []byte {
.rb.ss = 0
.rb.insertCGJ()
.next = nextComposed
.rb.ss.first(.info)
.rb.insertUnsafe(.rb.src, .p, .info)
return doNormComposed()
}