1/* 7zStream.c -- 7z Stream functions 22013-11-12 : Igor Pavlov : Public domain */ 3 4#include "Precomp.h" 5 6#include <string.h> 7 8#include "7zTypes.h" 9 10SRes 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 24SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) 25{ 26 return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 27} 28 29SRes 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 36SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) 37{ 38 Int64 t = offset; 39 return stream->Seek(stream, &t, SZ_SEEK_SET); 40} 41 42SRes 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 52SRes 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 66SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) 67{ 68 return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 69} 70 71static 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 89static 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 108static SRes LookToRead_Skip(void *pp, size_t offset) 109{ 110 CLookToRead *p = (CLookToRead *)pp; 111 p->pos += offset; 112 return SZ_OK; 113} 114 115static 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 129static 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 136void 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 146void LookToRead_Init(CLookToRead *p) 147{ 148 p->pos = p->size = 0; 149} 150 151static 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 157void SecToLook_CreateVTable(CSecToLook *p) 158{ 159 p->s.Read = SecToLook_Read; 160} 161 162static 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 168void SecToRead_CreateVTable(CSecToRead *p) 169{ 170 p->s.Read = SecToRead_Read; 171} 172