1 /* 7zStream.c -- 7z Stream functions
2 2023-04-02 : Igor Pavlov : Public domain */
3
4 #include "Precomp.h"
5
6 #include <string.h>
7
8 #include "7zTypes.h"
9
10
SeqInStream_ReadMax(ISeqInStreamPtr stream,void * buf,size_t * processedSize)11 SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize)
12 {
13 size_t size = *processedSize;
14 *processedSize = 0;
15 while (size != 0)
16 {
17 size_t cur = size;
18 const SRes res = ISeqInStream_Read(stream, buf, &cur);
19 *processedSize += cur;
20 buf = (void *)((Byte *)buf + cur);
21 size -= cur;
22 if (res != SZ_OK)
23 return res;
24 if (cur == 0)
25 return SZ_OK;
26 }
27 return SZ_OK;
28 }
29
30 /*
31 SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType)
32 {
33 while (size != 0)
34 {
35 size_t processed = size;
36 RINOK(ISeqInStream_Read(stream, buf, &processed))
37 if (processed == 0)
38 return errorType;
39 buf = (void *)((Byte *)buf + processed);
40 size -= processed;
41 }
42 return SZ_OK;
43 }
44
45 SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size)
46 {
47 return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
48 }
49 */
50
51
SeqInStream_ReadByte(ISeqInStreamPtr stream,Byte * buf)52 SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf)
53 {
54 size_t processed = 1;
55 RINOK(ISeqInStream_Read(stream, buf, &processed))
56 return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
57 }
58
59
60
LookInStream_SeekTo(ILookInStreamPtr stream,UInt64 offset)61 SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset)
62 {
63 Int64 t = (Int64)offset;
64 return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
65 }
66
LookInStream_LookRead(ILookInStreamPtr stream,void * buf,size_t * size)67 SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size)
68 {
69 const void *lookBuf;
70 if (*size == 0)
71 return SZ_OK;
72 RINOK(ILookInStream_Look(stream, &lookBuf, size))
73 memcpy(buf, lookBuf, *size);
74 return ILookInStream_Skip(stream, *size);
75 }
76
LookInStream_Read2(ILookInStreamPtr stream,void * buf,size_t size,SRes errorType)77 SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType)
78 {
79 while (size != 0)
80 {
81 size_t processed = size;
82 RINOK(ILookInStream_Read(stream, buf, &processed))
83 if (processed == 0)
84 return errorType;
85 buf = (void *)((Byte *)buf + processed);
86 size -= processed;
87 }
88 return SZ_OK;
89 }
90
LookInStream_Read(ILookInStreamPtr stream,void * buf,size_t size)91 SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size)
92 {
93 return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
94 }
95
96
97
98 #define GET_LookToRead2 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLookToRead2)
99
LookToRead2_Look_Lookahead(ILookInStreamPtr pp,const void ** buf,size_t * size)100 static SRes LookToRead2_Look_Lookahead(ILookInStreamPtr pp, const void **buf, size_t *size)
101 {
102 SRes res = SZ_OK;
103 GET_LookToRead2
104 size_t size2 = p->size - p->pos;
105 if (size2 == 0 && *size != 0)
106 {
107 p->pos = 0;
108 p->size = 0;
109 size2 = p->bufSize;
110 res = ISeekInStream_Read(p->realStream, p->buf, &size2);
111 p->size = size2;
112 }
113 if (*size > size2)
114 *size = size2;
115 *buf = p->buf + p->pos;
116 return res;
117 }
118
LookToRead2_Look_Exact(ILookInStreamPtr pp,const void ** buf,size_t * size)119 static SRes LookToRead2_Look_Exact(ILookInStreamPtr pp, const void **buf, size_t *size)
120 {
121 SRes res = SZ_OK;
122 GET_LookToRead2
123 size_t size2 = p->size - p->pos;
124 if (size2 == 0 && *size != 0)
125 {
126 p->pos = 0;
127 p->size = 0;
128 if (*size > p->bufSize)
129 *size = p->bufSize;
130 res = ISeekInStream_Read(p->realStream, p->buf, size);
131 size2 = p->size = *size;
132 }
133 if (*size > size2)
134 *size = size2;
135 *buf = p->buf + p->pos;
136 return res;
137 }
138
LookToRead2_Skip(ILookInStreamPtr pp,size_t offset)139 static SRes LookToRead2_Skip(ILookInStreamPtr pp, size_t offset)
140 {
141 GET_LookToRead2
142 p->pos += offset;
143 return SZ_OK;
144 }
145
LookToRead2_Read(ILookInStreamPtr pp,void * buf,size_t * size)146 static SRes LookToRead2_Read(ILookInStreamPtr pp, void *buf, size_t *size)
147 {
148 GET_LookToRead2
149 size_t rem = p->size - p->pos;
150 if (rem == 0)
151 return ISeekInStream_Read(p->realStream, buf, size);
152 if (rem > *size)
153 rem = *size;
154 memcpy(buf, p->buf + p->pos, rem);
155 p->pos += rem;
156 *size = rem;
157 return SZ_OK;
158 }
159
LookToRead2_Seek(ILookInStreamPtr pp,Int64 * pos,ESzSeek origin)160 static SRes LookToRead2_Seek(ILookInStreamPtr pp, Int64 *pos, ESzSeek origin)
161 {
162 GET_LookToRead2
163 p->pos = p->size = 0;
164 return ISeekInStream_Seek(p->realStream, pos, origin);
165 }
166
LookToRead2_CreateVTable(CLookToRead2 * p,int lookahead)167 void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
168 {
169 p->vt.Look = lookahead ?
170 LookToRead2_Look_Lookahead :
171 LookToRead2_Look_Exact;
172 p->vt.Skip = LookToRead2_Skip;
173 p->vt.Read = LookToRead2_Read;
174 p->vt.Seek = LookToRead2_Seek;
175 }
176
177
178
SecToLook_Read(ISeqInStreamPtr pp,void * buf,size_t * size)179 static SRes SecToLook_Read(ISeqInStreamPtr pp, void *buf, size_t *size)
180 {
181 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToLook)
182 return LookInStream_LookRead(p->realStream, buf, size);
183 }
184
SecToLook_CreateVTable(CSecToLook * p)185 void SecToLook_CreateVTable(CSecToLook *p)
186 {
187 p->vt.Read = SecToLook_Read;
188 }
189
SecToRead_Read(ISeqInStreamPtr pp,void * buf,size_t * size)190 static SRes SecToRead_Read(ISeqInStreamPtr pp, void *buf, size_t *size)
191 {
192 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToRead)
193 return ILookInStream_Read(p->realStream, buf, size);
194 }
195
SecToRead_CreateVTable(CSecToRead * p)196 void SecToRead_CreateVTable(CSecToRead *p)
197 {
198 p->vt.Read = SecToRead_Read;
199 }
200