processors/dissect/delimiter.go (83 lines of code) (raw):
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package dissect
import (
"fmt"
"strings"
)
//delimiter represents a text section after or before a key, it keeps track of the needle and allows
// to retrieve the position where it starts from a haystack.
type delimiter interface {
// IndexOf receives the haystack and a offset position and will return the absolute position where
// the needle is found.
IndexOf(haystack string, offset int) int
// Len returns the length of the needle used to calculate boundaries.
Len() int
// String displays debugging information.
String() string
// Delimiter returns the actual delimiter string.
Delimiter() string
// IsGreedy return true if the next key should be greedy (end of string) or when explicitly
// configured.
IsGreedy() bool
// MarkGreedy marks this delimiter as greedy.
MarkGreedy()
// Next returns the next delimiter in the chain.
Next() delimiter
//SetNext sets the next delimiter or nil if current delimiter is the last.
SetNext(d delimiter)
}
// zeroByte represents a zero string delimiter its usually start of the line.
type zeroByte struct {
needle string
greedy bool
next delimiter
}
func (z *zeroByte) IndexOf(haystack string, offset int) int {
return offset
}
func (z *zeroByte) Len() int {
return 0
}
func (z *zeroByte) String() string {
return "delimiter: zerobyte"
}
func (z *zeroByte) Delimiter() string {
return z.needle
}
func (z *zeroByte) IsGreedy() bool {
return z.greedy
}
func (z *zeroByte) MarkGreedy() {
z.greedy = true
}
func (z *zeroByte) Next() delimiter {
return z.next
}
func (z *zeroByte) SetNext(d delimiter) {
z.next = d
}
// multiByte represents a delimiter with at least one byte.
type multiByte struct {
needle string
greedy bool
next delimiter
}
func (m *multiByte) IndexOf(haystack string, offset int) int {
i := strings.Index(haystack[offset:], m.needle)
if i != -1 {
return i + offset
}
return -1
}
func (m *multiByte) Len() int {
return len(m.needle)
}
func (m *multiByte) IsGreedy() bool {
return m.greedy
}
func (m *multiByte) MarkGreedy() {
m.greedy = true
}
func (m *multiByte) String() string {
return fmt.Sprintf("delimiter: multibyte (match: '%s', len: %d)", m.needle, m.Len())
}
func (m *multiByte) Delimiter() string {
return m.needle
}
func (m *multiByte) Next() delimiter {
return m.next
}
func (m *multiByte) SetNext(d delimiter) {
m.next = d
}
func newDelimiter(needle string) delimiter {
if len(needle) == 0 {
return &zeroByte{}
}
return &multiByte{needle: needle}
}