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