Home | History | Annotate | Download | only in C
      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