7zStream.c (4366B)
1 /* 7zStream.c -- 7z Stream functions 2 2017-04-03 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 #include <string.h> 7 8 #include "7zTypes.h" 9 10 SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType) 11 { 12 while (size != 0) 13 { 14 size_t processed = size; 15 RINOK(ISeqInStream_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(const 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(const ISeqInStream *stream, Byte *buf) 30 { 31 size_t processed = 1; 32 RINOK(ISeqInStream_Read(stream, buf, &processed)); 33 return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; 34 } 35 36 37 38 SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset) 39 { 40 Int64 t = offset; 41 return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); 42 } 43 44 SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size) 45 { 46 const void *lookBuf; 47 if (*size == 0) 48 return SZ_OK; 49 RINOK(ILookInStream_Look(stream, &lookBuf, size)); 50 memcpy(buf, lookBuf, *size); 51 return ILookInStream_Skip(stream, *size); 52 } 53 54 SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType) 55 { 56 while (size != 0) 57 { 58 size_t processed = size; 59 RINOK(ILookInStream_Read(stream, buf, &processed)); 60 if (processed == 0) 61 return errorType; 62 buf = (void *)((Byte *)buf + processed); 63 size -= processed; 64 } 65 return SZ_OK; 66 } 67 68 SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size) 69 { 70 return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 71 } 72 73 74 75 #define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt); 76 77 static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size) 78 { 79 SRes res = SZ_OK; 80 GET_LookToRead2 81 size_t size2 = p->size - p->pos; 82 if (size2 == 0 && *size != 0) 83 { 84 p->pos = 0; 85 p->size = 0; 86 size2 = p->bufSize; 87 res = ISeekInStream_Read(p->realStream, p->buf, &size2); 88 p->size = size2; 89 } 90 if (*size > size2) 91 *size = size2; 92 *buf = p->buf + p->pos; 93 return res; 94 } 95 96 static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size) 97 { 98 SRes res = SZ_OK; 99 GET_LookToRead2 100 size_t size2 = p->size - p->pos; 101 if (size2 == 0 && *size != 0) 102 { 103 p->pos = 0; 104 p->size = 0; 105 if (*size > p->bufSize) 106 *size = p->bufSize; 107 res = ISeekInStream_Read(p->realStream, p->buf, size); 108 size2 = p->size = *size; 109 } 110 if (*size > size2) 111 *size = size2; 112 *buf = p->buf + p->pos; 113 return res; 114 } 115 116 static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset) 117 { 118 GET_LookToRead2 119 p->pos += offset; 120 return SZ_OK; 121 } 122 123 static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) 124 { 125 GET_LookToRead2 126 size_t rem = p->size - p->pos; 127 if (rem == 0) 128 return ISeekInStream_Read(p->realStream, buf, size); 129 if (rem > *size) 130 rem = *size; 131 memcpy(buf, p->buf + p->pos, rem); 132 p->pos += rem; 133 *size = rem; 134 return SZ_OK; 135 } 136 137 static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin) 138 { 139 GET_LookToRead2 140 p->pos = p->size = 0; 141 return ISeekInStream_Seek(p->realStream, pos, origin); 142 } 143 144 void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead) 145 { 146 p->vt.Look = lookahead ? 147 LookToRead2_Look_Lookahead : 148 LookToRead2_Look_Exact; 149 p->vt.Skip = LookToRead2_Skip; 150 p->vt.Read = LookToRead2_Read; 151 p->vt.Seek = LookToRead2_Seek; 152 } 153 154 155 156 static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size) 157 { 158 CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt); 159 return LookInStream_LookRead(p->realStream, buf, size); 160 } 161 162 void SecToLook_CreateVTable(CSecToLook *p) 163 { 164 p->vt.Read = SecToLook_Read; 165 } 166 167 static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size) 168 { 169 CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt); 170 return ILookInStream_Read(p->realStream, buf, size); 171 } 172 173 void SecToRead_CreateVTable(CSecToRead *p) 174 { 175 p->vt.Read = SecToRead_Read; 176 }