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} }