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