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