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