github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/runtime/serializer/streaming/streaming.go (about) 1 /* 2 Copyright 2015 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 streaming implements encoder and decoder for streams 18 // of runtime.Objects over io.Writer/Readers. 19 package streaming 20 21 import ( 22 "bytes" 23 "fmt" 24 "io" 25 26 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime" 27 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/schema" 28 ) 29 30 // Encoder is a runtime.Encoder on a stream. 31 type Encoder interface { 32 // Encode will write the provided object to the stream or return an error. It obeys the same 33 // contract as runtime.VersionedEncoder. 34 Encode(obj runtime.Object) error 35 } 36 37 // Decoder is a runtime.Decoder from a stream. 38 type Decoder interface { 39 // Decode will return io.EOF when no more objects are available. 40 Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) 41 // Close closes the underlying stream. 42 Close() error 43 } 44 45 // Serializer is a factory for creating encoders and decoders that work over streams. 46 type Serializer interface { 47 NewEncoder(w io.Writer) Encoder 48 NewDecoder(r io.ReadCloser) Decoder 49 } 50 51 type decoder struct { 52 reader io.ReadCloser 53 decoder runtime.Decoder 54 buf []byte 55 maxBytes int 56 resetRead bool 57 } 58 59 // NewDecoder creates a streaming decoder that reads object chunks from r and decodes them with d. 60 // The reader is expected to return ErrShortRead if the provided buffer is not large enough to read 61 // an entire object. 62 func NewDecoder(r io.ReadCloser, d runtime.Decoder) Decoder { 63 return &decoder{ 64 reader: r, 65 decoder: d, 66 buf: make([]byte, 1024), 67 maxBytes: 16 * 1024 * 1024, 68 } 69 } 70 71 var ErrObjectTooLarge = fmt.Errorf("object to decode was longer than maximum allowed size") 72 73 // Decode reads the next object from the stream and decodes it. 74 func (d *decoder) Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) { 75 base := 0 76 for { 77 n, err := d.reader.Read(d.buf[base:]) 78 if err == io.ErrShortBuffer { 79 if n == 0 { 80 return nil, nil, fmt.Errorf("got short buffer with n=0, base=%d, cap=%d", base, cap(d.buf)) 81 } 82 if d.resetRead { 83 continue 84 } 85 // double the buffer size up to maxBytes 86 if len(d.buf) < d.maxBytes { 87 base += n 88 d.buf = append(d.buf, make([]byte, len(d.buf))...) 89 continue 90 } 91 // must read the rest of the frame (until we stop getting ErrShortBuffer) 92 d.resetRead = true 93 return nil, nil, ErrObjectTooLarge 94 } 95 if err != nil { 96 return nil, nil, err 97 } 98 if d.resetRead { 99 // now that we have drained the large read, continue 100 d.resetRead = false 101 continue 102 } 103 base += n 104 break 105 } 106 return d.decoder.Decode(d.buf[:base], defaults, into) 107 } 108 109 func (d *decoder) Close() error { 110 return d.reader.Close() 111 } 112 113 type encoder struct { 114 writer io.Writer 115 encoder runtime.Encoder 116 buf *bytes.Buffer 117 } 118 119 // NewEncoder returns a new streaming encoder. 120 func NewEncoder(w io.Writer, e runtime.Encoder) Encoder { 121 return &encoder{ 122 writer: w, 123 encoder: e, 124 buf: &bytes.Buffer{}, 125 } 126 } 127 128 // Encode writes the provided object to the nested writer. 129 func (e *encoder) Encode(obj runtime.Object) error { 130 if err := e.encoder.Encode(obj, e.buf); err != nil { 131 return err 132 } 133 _, err := e.writer.Write(e.buf.Bytes()) 134 e.buf.Reset() 135 return err 136 } 137 138 type encoderWithAllocator struct { 139 writer io.Writer 140 encoder runtime.EncoderWithAllocator 141 memAllocator runtime.MemoryAllocator 142 } 143 144 // NewEncoderWithAllocator returns a new streaming encoder 145 func NewEncoderWithAllocator(w io.Writer, e runtime.EncoderWithAllocator, a runtime.MemoryAllocator) Encoder { 146 return &encoderWithAllocator{ 147 writer: w, 148 encoder: e, 149 memAllocator: a, 150 } 151 } 152 153 // Encode writes the provided object to the nested writer 154 func (e *encoderWithAllocator) Encode(obj runtime.Object) error { 155 return e.encoder.EncodeWithAllocator(obj, e.writer, e.memAllocator) 156 }