Line data Source code
1 : #include "fd_snapshot_istream.h"
2 : #include "../../util/fd_util.h"
3 : #include <errno.h>
4 :
5 : #if FD_HAS_ZSTD
6 :
7 : /* fd_io_istream_zstd_t ***********************************************/
8 :
9 : fd_io_istream_zstd_t *
10 : fd_io_istream_zstd_new( void * mem,
11 : fd_zstd_dstream_t * dstream,
12 0 : fd_io_istream_obj_t src ) {
13 0 : fd_io_istream_zstd_t * this = mem;
14 0 : *this = (fd_io_istream_zstd_t){
15 0 : .dstream = dstream,
16 0 : .src = src,
17 0 : .in_cur = this->in_buf,
18 0 : .in_end = this->in_buf,
19 0 : .dirty = 0
20 0 : };
21 0 : return this;
22 0 : }
23 :
24 : void *
25 0 : fd_io_istream_zstd_delete( fd_io_istream_zstd_t * this ) {
26 0 : fd_memset( this, 0, sizeof(fd_io_istream_zstd_t) );
27 0 : return (void *)this;
28 0 : }
29 :
30 : int
31 : fd_io_istream_zstd_read( void * _this,
32 : void * dst,
33 : ulong dst_max,
34 0 : ulong * dst_sz ) {
35 :
36 0 : fd_io_istream_zstd_t * restrict this = _this;
37 :
38 0 : if( (!this->dirty) & (this->in_cur == this->in_end) ) {
39 : /* needs refill */
40 0 : ulong in_sz = 0UL;
41 0 : int read_err = fd_io_istream_obj_read( &this->src, this->in_buf, FD_IO_ISTREAM_ZSTD_BUFSZ, &in_sz );
42 0 : if( FD_LIKELY( read_err==0 ) ) { /* ok */ }
43 0 : else if( read_err<0 ) { /* EOF */ return -1; /* TODO handle unexpected EOF case */ }
44 0 : else {
45 0 : FD_LOG_DEBUG(( "failed to read from source (%d-%s)", read_err, fd_io_strerror( read_err ) ));
46 0 : return read_err;
47 0 : }
48 0 : this->in_cur = this->in_buf;
49 0 : this->in_end = this->in_buf + in_sz;
50 0 : if( FD_UNLIKELY( in_sz==0 ) ) {
51 0 : *dst_sz = 0UL;
52 0 : return 0;
53 0 : }
54 0 : }
55 :
56 0 : uchar * out = dst;
57 0 : uchar * out_end = out + dst_max;
58 0 : int zstd_err = fd_zstd_dstream_read( this->dstream, (uchar const **)&this->in_cur, this->in_end, &out, out_end, NULL );
59 0 : if( FD_UNLIKELY( zstd_err>0 ) ) {
60 0 : FD_LOG_WARNING(( "fd_zstd_dstream_read failed" ));
61 : /* TODO set out pointers? */
62 0 : return EPROTO;
63 0 : }
64 0 : this->dirty = (out==out_end);
65 :
66 0 : *dst_sz = (ulong)out - (ulong)dst;
67 0 : return 0;
68 0 : }
69 :
70 : fd_io_istream_vt_t const fd_io_istream_zstd_vt =
71 : { .read = fd_io_istream_zstd_read };
72 :
73 : #endif /* FD_HAS_ZSTD */
74 :
75 : /* fd_io_istream_file_t ***********************************************/
76 :
77 : fd_io_istream_file_t *
78 : fd_io_istream_file_new( void * mem,
79 0 : int fd ) {
80 0 : fd_io_istream_file_t * this = mem;
81 0 : *this = (fd_io_istream_file_t){
82 0 : .fd = fd /* borrowed for lifetime */
83 0 : };
84 0 : return this;
85 0 : }
86 :
87 : void *
88 0 : fd_io_istream_file_delete( fd_io_istream_file_t * this ) {
89 0 : fd_memset( this, 0, sizeof(fd_io_istream_file_t) );
90 0 : return (void *)this;
91 0 : }
92 :
93 : int
94 : fd_io_istream_file_read( void * _this,
95 : void * dst,
96 : ulong dst_max,
97 0 : ulong * dst_sz ) {
98 0 : fd_io_istream_file_t * this = _this;
99 0 : return fd_io_read( this->fd, dst, 1UL, dst_max, dst_sz );
100 0 : }
101 :
102 : fd_io_istream_vt_t const fd_io_istream_file_vt =
103 : { .read = fd_io_istream_file_read };
104 :
105 :
106 : /* fd_tar_io_reader_t *************************************************/
107 :
108 : fd_tar_io_reader_t *
109 : fd_tar_io_reader_new( void * mem,
110 : fd_tar_reader_t * reader,
111 0 : fd_io_istream_obj_t src ) {
112 :
113 0 : if( FD_UNLIKELY( !reader ) ) {
114 0 : FD_LOG_WARNING(( "NULL reader" ));
115 0 : return NULL;
116 0 : }
117 0 : if( FD_UNLIKELY( !src.vt ) ) {
118 0 : FD_LOG_WARNING(( "NULL source" ));
119 0 : return NULL;
120 0 : }
121 :
122 0 : fd_tar_io_reader_t * this = mem;
123 0 : *this = (fd_tar_io_reader_t){
124 0 : .reader = reader,
125 0 : .src = src
126 0 : };
127 0 : return this;
128 0 : }
129 :
130 : void *
131 0 : fd_tar_io_reader_delete( fd_tar_io_reader_t * this ) {
132 0 : fd_memset( this, 0, sizeof(fd_tar_io_reader_t) );
133 0 : return (void *)this;
134 0 : }
135 :
136 : int
137 0 : fd_tar_io_reader_advance( fd_tar_io_reader_t * this ) {
138 :
139 0 : uchar buf[ 16384 ];
140 0 : ulong buf_sz = 0UL;
141 0 : int read_err = fd_io_istream_obj_read( &this->src, buf, sizeof(buf), &buf_sz );
142 0 : if( FD_LIKELY( read_err==0 ) ) { /* ok */ }
143 0 : else if( read_err<0 ) { /* EOF */ return -1; /* TODO handle unexpected EOF case */ }
144 0 : else {
145 0 : FD_LOG_WARNING(( "snapshot tar stream failed (%d-%s)", read_err, fd_io_strerror( read_err ) ));
146 0 : return read_err;
147 0 : }
148 :
149 0 : int tar_err = fd_tar_read( this->reader, buf, buf_sz );
150 0 : if( FD_UNLIKELY( tar_err>0 ) ) {
151 0 : FD_LOG_WARNING(( "snapshot tar stream failed (%d-%s)", tar_err, fd_io_strerror( tar_err ) ));
152 0 : return tar_err;
153 0 : }
154 0 : if( tar_err<0 ) {
155 0 : FD_LOG_NOTICE(( "encountered end of tar stream" ));
156 0 : return -1;
157 0 : }
158 :
159 0 : return 0;
160 0 : }
|