k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/proxy/util/linebuffer.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "bytes" 21 "fmt" 22 "strings" 23 24 "github.com/go-logr/logr" 25 ) 26 27 // LineBuffer is an interface for writing lines of input to a bytes.Buffer 28 type LineBuffer interface { 29 // Write takes a list of arguments, each a string or []string, joins all the 30 // individual strings with spaces, terminates with newline, and writes them to the 31 // buffer. Any other argument type will panic. 32 Write(args ...interface{}) 33 34 // WriteBytes writes bytes to the buffer, and terminates with newline. 35 WriteBytes(bytes []byte) 36 37 // Reset clears the buffer 38 Reset() 39 40 // Bytes returns the contents of the buffer as a []byte 41 Bytes() []byte 42 43 // String returns the contents of the buffer as a string 44 String() string 45 46 // Lines returns the number of lines in the buffer. Note that more precisely, this 47 // returns the number of times Write() or WriteBytes() was called; it assumes that 48 // you never wrote any newlines to the buffer yourself. 49 Lines() int 50 } 51 52 var _ logr.Marshaler = &realLineBuffer{} 53 54 type realLineBuffer struct { 55 b bytes.Buffer 56 lines int 57 } 58 59 // NewLineBuffer returns a new "real" LineBuffer 60 func NewLineBuffer() LineBuffer { 61 return &realLineBuffer{} 62 } 63 64 // Write is part of LineBuffer 65 func (buf *realLineBuffer) Write(args ...interface{}) { 66 for i, arg := range args { 67 if i > 0 { 68 buf.b.WriteByte(' ') 69 } 70 switch x := arg.(type) { 71 case string: 72 buf.b.WriteString(x) 73 case []string: 74 for j, s := range x { 75 if j > 0 { 76 buf.b.WriteByte(' ') 77 } 78 buf.b.WriteString(s) 79 } 80 default: 81 panic(fmt.Sprintf("unknown argument type: %T", x)) 82 } 83 } 84 buf.b.WriteByte('\n') 85 buf.lines++ 86 } 87 88 // WriteBytes is part of LineBuffer 89 func (buf *realLineBuffer) WriteBytes(bytes []byte) { 90 buf.b.Write(bytes) 91 buf.b.WriteByte('\n') 92 buf.lines++ 93 } 94 95 // Reset is part of LineBuffer 96 func (buf *realLineBuffer) Reset() { 97 buf.b.Reset() 98 buf.lines = 0 99 } 100 101 // Bytes is part of LineBuffer 102 func (buf *realLineBuffer) Bytes() []byte { 103 return buf.b.Bytes() 104 } 105 106 // String is part of LineBuffer 107 func (buf *realLineBuffer) String() string { 108 return buf.b.String() 109 } 110 111 // Lines is part of LineBuffer 112 func (buf *realLineBuffer) Lines() int { 113 return buf.lines 114 } 115 116 // Implements the logs.Marshaler interface 117 func (buf *realLineBuffer) MarshalLog() any { 118 return strings.Split(buf.b.String(), "\n") 119 } 120 121 type discardLineBuffer struct { 122 lines int 123 } 124 125 // NewDiscardLineBuffer returns a dummy LineBuffer that counts the number of writes but 126 // throws away the data. (This is used for iptables proxy partial syncs, to keep track of 127 // how many rules we managed to avoid having to sync.) 128 func NewDiscardLineBuffer() LineBuffer { 129 return &discardLineBuffer{} 130 } 131 132 // Write is part of LineBuffer 133 func (buf *discardLineBuffer) Write(args ...interface{}) { 134 buf.lines++ 135 } 136 137 // WriteBytes is part of LineBuffer 138 func (buf *discardLineBuffer) WriteBytes(bytes []byte) { 139 buf.lines++ 140 } 141 142 // Reset is part of LineBuffer 143 func (buf *discardLineBuffer) Reset() { 144 buf.lines = 0 145 } 146 147 // Bytes is part of LineBuffer 148 func (buf *discardLineBuffer) Bytes() []byte { 149 return []byte{} 150 } 151 152 // String is part of LineBuffer 153 func (buf *discardLineBuffer) String() string { 154 return "" 155 } 156 157 // Lines is part of LineBuffer 158 func (buf *discardLineBuffer) Lines() int { 159 return buf.lines 160 }