crossplane

Форк
0
116 строк · 2.8 Кб
1
/*
2
Copyright 2022 The Crossplane 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 xpkg
18

19
import (
20
	"compress/gzip"
21
	"io"
22
)
23

24
var _ io.ReadCloser = &gzipReadCloser{}
25

26
// gzipReadCloser reads compressed contents from a file.
27
type gzipReadCloser struct {
28
	rc   io.ReadCloser
29
	gzip *gzip.Reader
30
}
31

32
// GzipReadCloser constructs a new gzipReadCloser from the passed file.
33
func GzipReadCloser(rc io.ReadCloser) (io.ReadCloser, error) {
34
	r, err := gzip.NewReader(rc)
35
	if err != nil {
36
		return nil, err
37
	}
38
	return &gzipReadCloser{
39
		rc:   rc,
40
		gzip: r,
41
	}, nil
42
}
43

44
// Read calls the underlying gzip reader's Read method.
45
func (g *gzipReadCloser) Read(p []byte) (n int, err error) {
46
	return g.gzip.Read(p)
47
}
48

49
// Close first closes the gzip reader, then closes the underlying closer.
50
func (g *gzipReadCloser) Close() error {
51
	if err := g.gzip.Close(); err != nil {
52
		_ = g.rc.Close()
53
		return err
54
	}
55
	return g.rc.Close()
56
}
57

58
var _ io.ReadCloser = &teeReadCloser{}
59

60
// teeReadCloser is a TeeReader that also closes the underlying writer.
61
type teeReadCloser struct {
62
	w io.WriteCloser
63
	r io.ReadCloser
64
	t io.Reader
65
}
66

67
// TeeReadCloser constructs a teeReadCloser from the passed reader and writer.
68
func TeeReadCloser(r io.ReadCloser, w io.WriteCloser) io.ReadCloser {
69
	return &teeReadCloser{
70
		w: w,
71
		r: r,
72
		t: io.TeeReader(r, w),
73
	}
74
}
75

76
// Read calls the underlying TeeReader Read method.
77
func (t *teeReadCloser) Read(b []byte) (int, error) {
78
	return t.t.Read(b)
79
}
80

81
// Close closes the underlying ReadCloser, then the Writer for the TeeReader.
82
func (t *teeReadCloser) Close() error {
83
	if err := t.r.Close(); err != nil {
84
		_ = t.w.Close()
85
		return err
86
	}
87
	return t.w.Close()
88
}
89

90
var _ io.ReadCloser = &joinedReadCloser{}
91

92
// joinedReadCloster joins a reader and a closer. It is typically used in the
93
// context of a ReadCloser being wrapped by a Reader.
94
type joinedReadCloser struct {
95
	r io.Reader
96
	c io.Closer
97
}
98

99
// JoinedReadCloser constructs a new joinedReadCloser from the passed reader and
100
// closer.
101
func JoinedReadCloser(r io.Reader, c io.Closer) io.ReadCloser {
102
	return &joinedReadCloser{
103
		r: r,
104
		c: c,
105
	}
106
}
107

108
// Read calls the underlying reader Read method.
109
func (r *joinedReadCloser) Read(b []byte) (int, error) {
110
	return r.r.Read(b)
111
}
112

113
// Close closes the closer for the JoinedReadCloser.
114
func (r *joinedReadCloser) Close() error {
115
	return r.c.Close()
116
}
117

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.