diff src/win32/7zip/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,172 @@
     1.4 +// Archive/LzhIn.cpp
     1.5 +
     1.6 +#include "StdAfx.h"
     1.7 +
     1.8 +#include "Common/StringConvert.h"
     1.9 +#include "Common/Buffer.h"
    1.10 +
    1.11 +#include "../../Common/StreamUtils.h"
    1.12 +
    1.13 +#include "LzhIn.h"
    1.14 +
    1.15 +namespace NArchive {
    1.16 +namespace NLzh {
    1.17 + 
    1.18 +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
    1.19 +{
    1.20 +  size_t realProcessedSize = size;
    1.21 +  RINOK(ReadStream(m_Stream, data, &realProcessedSize));
    1.22 +  processedSize = (UInt32)realProcessedSize;
    1.23 +  m_Position += processedSize;
    1.24 +  return S_OK;
    1.25 +}
    1.26 +
    1.27 +HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size)
    1.28 +{
    1.29 +  UInt32 processedSize;
    1.30 +  RINOK(ReadBytes(data, size, processedSize));
    1.31 +  return (processedSize == size) ? S_OK: S_FALSE;
    1.32 +}
    1.33 +
    1.34 +HRESULT CInArchive::Open(IInStream *inStream)
    1.35 +{
    1.36 +  RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
    1.37 +  m_Stream = inStream;
    1.38 +  return S_OK;
    1.39 +}
    1.40 +
    1.41 +static const Byte *ReadUInt32(const Byte *p, UInt32 &v)
    1.42 +{
    1.43 +  v = 0;
    1.44 +  for (int i = 0; i < 4; i++)
    1.45 +    v |= ((UInt32)(*p++) << (i * 8));
    1.46 +  return p;
    1.47 +}
    1.48 +
    1.49 +static const Byte *ReadUInt16(const Byte *p, UInt16 &v)
    1.50 +{
    1.51 +  v = 0;
    1.52 +  for (int i = 0; i < 2; i++)
    1.53 +    v |= ((UInt16)(*p++) << (i * 8));
    1.54 +  return p;
    1.55 +}
    1.56 +
    1.57 +static const Byte *ReadString(const Byte *p, size_t size, AString &s)
    1.58 +{
    1.59 +  s.Empty();
    1.60 +  for (size_t i = 0; i < size; i++)
    1.61 +  {
    1.62 +    char c = p[i];
    1.63 +    if (c == 0)
    1.64 +      break;
    1.65 +    s += c;
    1.66 +  }
    1.67 +  return p + size;
    1.68 +}
    1.69 +
    1.70 +static Byte CalcSum(const Byte *data, size_t size)
    1.71 +{
    1.72 +  Byte sum = 0;
    1.73 +  for (size_t i = 0; i < size; i++)
    1.74 +    sum = (Byte)(sum + data[i]);
    1.75 +  return sum;
    1.76 +}
    1.77 +
    1.78 +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
    1.79 +{
    1.80 +  filled = false;
    1.81 +
    1.82 +  UInt32 processedSize;
    1.83 +  Byte startHeader[2];
    1.84 +  RINOK(ReadBytes(startHeader, 2, processedSize))
    1.85 +  if (processedSize == 0)
    1.86 +    return S_OK;
    1.87 +  if (processedSize == 1)
    1.88 +    return (startHeader[0] == 0) ? S_OK: S_FALSE;
    1.89 +  if (startHeader[0] == 0 && startHeader[1] == 0)
    1.90 +    return S_OK;
    1.91 +
    1.92 +  Byte header[256];
    1.93 +  const UInt32 kBasicPartSize = 22;
    1.94 +  RINOK(ReadBytes(header, kBasicPartSize, processedSize));
    1.95 +  if (processedSize != kBasicPartSize)
    1.96 +    return (startHeader[0] == 0) ? S_OK: S_FALSE;
    1.97 +
    1.98 +  const Byte *p = header;
    1.99 +  memmove(item.Method, p, kMethodIdSize);
   1.100 +  if (!item.IsValidMethod())
   1.101 +    return S_OK;
   1.102 +  p += kMethodIdSize;
   1.103 +  p = ReadUInt32(p, item.PackSize);
   1.104 +  p = ReadUInt32(p, item.Size);
   1.105 +  p = ReadUInt32(p, item.ModifiedTime);
   1.106 +  item.Attributes = *p++;
   1.107 +  item.Level = *p++;
   1.108 +  if (item.Level > 2)
   1.109 +    return S_FALSE;
   1.110 +  UInt32 headerSize;
   1.111 +  if (item.Level < 2)
   1.112 +  {
   1.113 +    headerSize = startHeader[0];
   1.114 +    if (headerSize < kBasicPartSize)
   1.115 +      return S_FALSE;
   1.116 +    UInt32 remain = headerSize - kBasicPartSize;
   1.117 +    RINOK(CheckReadBytes(header + kBasicPartSize, remain));
   1.118 +    if (startHeader[1] != CalcSum(header, headerSize))
   1.119 +      return S_FALSE;
   1.120 +    size_t nameLength = *p++;
   1.121 +    if ((p - header) + nameLength + 2 > headerSize)
   1.122 +      return S_FALSE;
   1.123 +    p = ReadString(p, nameLength, item.Name);
   1.124 +  }
   1.125 +  else
   1.126 +   headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8);
   1.127 +  p = ReadUInt16(p, item.CRC);
   1.128 +  if (item.Level != 0)
   1.129 +  {
   1.130 +    if (item.Level == 2)
   1.131 +    {
   1.132 +      RINOK(CheckReadBytes(header + kBasicPartSize, 2));
   1.133 +    }
   1.134 +    if ((size_t)(p - header) + 3 > headerSize)
   1.135 +      return S_FALSE;
   1.136 +    item.OsId = *p++;
   1.137 +    UInt16 nextSize;
   1.138 +    p = ReadUInt16(p, nextSize);
   1.139 +    while (nextSize != 0)
   1.140 +    {
   1.141 +      if (nextSize < 3)
   1.142 +        return S_FALSE;
   1.143 +      if (item.Level == 1)
   1.144 +      {
   1.145 +        if (item.PackSize < nextSize)
   1.146 +          return S_FALSE;
   1.147 +        item.PackSize -= nextSize;
   1.148 +      }
   1.149 +      CExtension ext;
   1.150 +      RINOK(CheckReadBytes(&ext.Type, 1))
   1.151 +      nextSize -= 3;
   1.152 +      ext.Data.SetCapacity(nextSize);
   1.153 +      RINOK(CheckReadBytes((Byte *)ext.Data, nextSize))
   1.154 +      item.Extensions.Add(ext);
   1.155 +      Byte hdr2[2];
   1.156 +      RINOK(CheckReadBytes(hdr2, 2));
   1.157 +      ReadUInt16(hdr2, nextSize);
   1.158 +    }
   1.159 +  }
   1.160 +  item.DataPosition = m_Position;
   1.161 +  filled = true;
   1.162 +  return S_OK;
   1.163 +}
   1.164 +
   1.165 +HRESULT CInArchive::Skeep(UInt64 numBytes)
   1.166 +{
   1.167 +  UInt64 newPostion;
   1.168 +  RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
   1.169 +  m_Position += numBytes;
   1.170 +  if (m_Position != newPostion)
   1.171 +    return E_FAIL;
   1.172 +  return S_OK;
   1.173 +}
   1.174 +
   1.175 +}}