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