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