15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7zStream.c -- 7z Stream functions 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)2010-03-11 : Igor Pavlov : Public domain */ 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Types.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (size != 0) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t processed = size; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(stream->Read(stream, buf, &processed)); 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (processed == 0) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return errorType; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = (void *)((Byte *)buf + processed); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size -= processed; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t processed = 1; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(stream->Read(stream, buf, &processed)); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Int64 t = offset; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return stream->Seek(stream, &t, SZ_SEEK_SET); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *lookBuf; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*size == 0) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(stream->Look(stream, &lookBuf, size)); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buf, lookBuf, *size); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return stream->Skip(stream, *size); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (size != 0) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t processed = size; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RINOK(stream->Read(stream, buf, &processed)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (processed == 0) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return errorType; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = (void *)((Byte *)buf + processed); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size -= processed; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res = SZ_OK; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLookToRead *p = (CLookToRead *)pp; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size2 = p->size - p->pos; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size2 == 0 && *size > 0) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pos = 0; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size2 = LookToRead_BUF_SIZE; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = p->realStream->Read(p->realStream, p->buf, &size2); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->size = size2; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size2 < *size) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = size2; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buf = p->buf + p->pos; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRes res = SZ_OK; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLookToRead *p = (CLookToRead *)pp; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size2 = p->size - p->pos; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size2 == 0 && *size > 0) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pos = 0; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*size > LookToRead_BUF_SIZE) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = LookToRead_BUF_SIZE; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = p->realStream->Read(p->realStream, p->buf, size); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size2 = p->size = *size; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size2 < *size) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = size2; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buf = p->buf + p->pos; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes LookToRead_Skip(void *pp, size_t offset) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLookToRead *p = (CLookToRead *)pp; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pos += offset; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes LookToRead_Read(void *pp, void *buf, size_t *size) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLookToRead *p = (CLookToRead *)pp; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t rem = p->size - p->pos; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rem == 0) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p->realStream->Read(p->realStream, buf, size); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rem > *size) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rem = *size; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buf, p->buf + p->pos, rem); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pos += rem; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = rem; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLookToRead *p = (CLookToRead *)pp; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pos = p->size = 0; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p->realStream->Seek(p->realStream, pos, origin); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LookToRead_CreateVTable(CLookToRead *p, int lookahead) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->s.Look = lookahead ? 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookToRead_Look_Lookahead : 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookToRead_Look_Exact; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->s.Skip = LookToRead_Skip; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->s.Read = LookToRead_Read; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->s.Seek = LookToRead_Seek; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LookToRead_Init(CLookToRead *p) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pos = p->size = 0; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SecToLook_Read(void *pp, void *buf, size_t *size) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSecToLook *p = (CSecToLook *)pp; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LookInStream_LookRead(p->realStream, buf, size); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecToLook_CreateVTable(CSecToLook *p) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->s.Read = SecToLook_Read; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SRes SecToRead_Read(void *pp, void *buf, size_t *size) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSecToRead *p = (CSecToRead *)pp; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p->realStream->Read(p->realStream, buf, size); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecToRead_CreateVTable(CSecToRead *p) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->s.Read = SecToRead_Read; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 170