1/* 7zStream.c -- 7z Stream functions
22013-11-12 : Igor Pavlov : Public domain */
3
4#include "Precomp.h"
5
6#include <string.h>
7
8#include "7zTypes.h"
9
10SRes 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
24SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
25{
26  return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
27}
28
29SRes 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
36SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
37{
38  Int64 t = offset;
39  return stream->Seek(stream, &t, SZ_SEEK_SET);
40}
41
42SRes 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
52SRes 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
66SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
67{
68  return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
69}
70
71static 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
89static 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
108static SRes LookToRead_Skip(void *pp, size_t offset)
109{
110  CLookToRead *p = (CLookToRead *)pp;
111  p->pos += offset;
112  return SZ_OK;
113}
114
115static 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
129static 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
136void 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
146void LookToRead_Init(CLookToRead *p)
147{
148  p->pos = p->size = 0;
149}
150
151static 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
157void SecToLook_CreateVTable(CSecToLook *p)
158{
159  p->s.Read = SecToLook_Read;
160}
161
162static 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
168void SecToRead_CreateVTable(CSecToRead *p)
169{
170  p->s.Read = SecToRead_Read;
171}
172