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 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 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 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 36 SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) 37 { 38 Int64 t = offset; 39 return stream->Seek(stream, &t, SZ_SEEK_SET); 40 } 41 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 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 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 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 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 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 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 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 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 146 void LookToRead_Init(CLookToRead *p) 147 { 148 p->pos = p->size = 0; 149 } 150 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 157 void SecToLook_CreateVTable(CSecToLook *p) 158 { 159 p->s.Read = SecToLook_Read; 160 } 161 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 168 void SecToRead_CreateVTable(CSecToRead *p) 169 { 170 p->s.Read = SecToRead_Read; 171 } 172