k8s.io/kubernetes@v1.29.3/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 ) 23 24 // LineBuffer is an interface for writing lines of input to a bytes.Buffer 25 type LineBuffer interface { 26 // Write takes a list of arguments, each a string or []string, joins all the 27 // individual strings with spaces, terminates with newline, and writes them to the 28 // buffer. Any other argument type will panic. 29 Write(args ...interface{}) 30 31 // WriteBytes writes bytes to the buffer, and terminates with newline. 32 WriteBytes(bytes []byte) 33 34 // Reset clears the buffer 35 Reset() 36 37 // Bytes returns the contents of the buffer as a []byte 38 Bytes() []byte 39 40 // String returns the contents of the buffer as a string 41 String() string 42 43 // Lines returns the number of lines in the buffer. Note that more precisely, this 44 // returns the number of times Write() or WriteBytes() was called; it assumes that 45 // you never wrote any newlines to the buffer yourself. 46 Lines() int 47 } 48 49 type realLineBuffer struct { 50 b bytes.Buffer 51 lines int 52 } 53 54 // NewLineBuffer returns a new "real" LineBuffer 55 func NewLineBuffer() LineBuffer { 56 return &realLineBuffer{} 57 } 58 59 // Write is part of LineBuffer 60 func (buf *realLineBuffer) Write(args ...interface{}) { 61 for i, arg := range args { 62 if i > 0 { 63 buf.b.WriteByte(' ') 64 } 65 switch x := arg.(type) { 66 case string: 67 buf.b.WriteString(x) 68 case []string: 69 for j, s := range x { 70 if j > 0 { 71 buf.b.WriteByte(' ') 72 } 73 buf.b.WriteString(s) 74 } 75 default: 76 panic(fmt.Sprintf("unknown argument type: %T", x)) 77 } 78 } 79 buf.b.WriteByte('\n') 80 buf.lines++ 81 } 82 83 // WriteBytes is part of LineBuffer 84 func (buf *realLineBuffer) WriteBytes(bytes []byte) { 85 buf.b.Write(bytes) 86 buf.b.WriteByte('\n') 87 buf.lines++ 88 } 89 90 // Reset is part of LineBuffer 91 func (buf *realLineBuffer) Reset() { 92 buf.b.Reset() 93 buf.lines = 0 94 } 95 96 // Bytes is part of LineBuffer 97 func (buf *realLineBuffer) Bytes() []byte { 98 return buf.b.Bytes() 99 } 100 101 // String is part of LineBuffer 102 func (buf *realLineBuffer) String() string { 103 return buf.b.String() 104 } 105 106 // Lines is part of LineBuffer 107 func (buf *realLineBuffer) Lines() int { 108 return buf.lines 109 } 110 111 type discardLineBuffer struct { 112 lines int 113 } 114 115 // NewDiscardLineBuffer returns a dummy LineBuffer that counts the number of writes but 116 // throws away the data. (This is used for iptables proxy partial syncs, to keep track of 117 // how many rules we managed to avoid having to sync.) 118 func NewDiscardLineBuffer() LineBuffer { 119 return &discardLineBuffer{} 120 } 121 122 // Write is part of LineBuffer 123 func (buf *discardLineBuffer) Write(args ...interface{}) { 124 buf.lines++ 125 } 126 127 // WriteBytes is part of LineBuffer 128 func (buf *discardLineBuffer) WriteBytes(bytes []byte) { 129 buf.lines++ 130 } 131 132 // Reset is part of LineBuffer 133 func (buf *discardLineBuffer) Reset() { 134 buf.lines = 0 135 } 136 137 // Bytes is part of LineBuffer 138 func (buf *discardLineBuffer) Bytes() []byte { 139 return []byte{} 140 } 141 142 // String is part of LineBuffer 143 func (buf *discardLineBuffer) String() string { 144 return "" 145 } 146 147 // Lines is part of LineBuffer 148 func (buf *discardLineBuffer) Lines() int { 149 return buf.lines 150 }