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