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