Mercurial > vba-linux
view 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 source
1 // Archive/LzhIn.cpp3 #include "StdAfx.h"5 #include "Common/StringConvert.h"6 #include "Common/Buffer.h"8 #include "../../Common/StreamUtils.h"10 #include "LzhIn.h"12 namespace NArchive {13 namespace NLzh {15 HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)16 {17 size_t realProcessedSize = size;18 RINOK(ReadStream(m_Stream, data, &realProcessedSize));19 processedSize = (UInt32)realProcessedSize;20 m_Position += processedSize;21 return S_OK;22 }24 HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size)25 {26 UInt32 processedSize;27 RINOK(ReadBytes(data, size, processedSize));28 return (processedSize == size) ? S_OK: S_FALSE;29 }31 HRESULT CInArchive::Open(IInStream *inStream)32 {33 RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));34 m_Stream = inStream;35 return S_OK;36 }38 static const Byte *ReadUInt32(const Byte *p, UInt32 &v)39 {40 v = 0;41 for (int i = 0; i < 4; i++)42 v |= ((UInt32)(*p++) << (i * 8));43 return p;44 }46 static const Byte *ReadUInt16(const Byte *p, UInt16 &v)47 {48 v = 0;49 for (int i = 0; i < 2; i++)50 v |= ((UInt16)(*p++) << (i * 8));51 return p;52 }54 static const Byte *ReadString(const Byte *p, size_t size, AString &s)55 {56 s.Empty();57 for (size_t i = 0; i < size; i++)58 {59 char c = p[i];60 if (c == 0)61 break;62 s += c;63 }64 return p + size;65 }67 static Byte CalcSum(const Byte *data, size_t size)68 {69 Byte sum = 0;70 for (size_t i = 0; i < size; i++)71 sum = (Byte)(sum + data[i]);72 return sum;73 }75 HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)76 {77 filled = false;79 UInt32 processedSize;80 Byte startHeader[2];81 RINOK(ReadBytes(startHeader, 2, processedSize))82 if (processedSize == 0)83 return S_OK;84 if (processedSize == 1)85 return (startHeader[0] == 0) ? S_OK: S_FALSE;86 if (startHeader[0] == 0 && startHeader[1] == 0)87 return S_OK;89 Byte header[256];90 const UInt32 kBasicPartSize = 22;91 RINOK(ReadBytes(header, kBasicPartSize, processedSize));92 if (processedSize != kBasicPartSize)93 return (startHeader[0] == 0) ? S_OK: S_FALSE;95 const Byte *p = header;96 memmove(item.Method, p, kMethodIdSize);97 if (!item.IsValidMethod())98 return S_OK;99 p += kMethodIdSize;100 p = ReadUInt32(p, item.PackSize);101 p = ReadUInt32(p, item.Size);102 p = ReadUInt32(p, item.ModifiedTime);103 item.Attributes = *p++;104 item.Level = *p++;105 if (item.Level > 2)106 return S_FALSE;107 UInt32 headerSize;108 if (item.Level < 2)109 {110 headerSize = startHeader[0];111 if (headerSize < kBasicPartSize)112 return S_FALSE;113 UInt32 remain = headerSize - kBasicPartSize;114 RINOK(CheckReadBytes(header + kBasicPartSize, remain));115 if (startHeader[1] != CalcSum(header, headerSize))116 return S_FALSE;117 size_t nameLength = *p++;118 if ((p - header) + nameLength + 2 > headerSize)119 return S_FALSE;120 p = ReadString(p, nameLength, item.Name);121 }122 else123 headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8);124 p = ReadUInt16(p, item.CRC);125 if (item.Level != 0)126 {127 if (item.Level == 2)128 {129 RINOK(CheckReadBytes(header + kBasicPartSize, 2));130 }131 if ((size_t)(p - header) + 3 > headerSize)132 return S_FALSE;133 item.OsId = *p++;134 UInt16 nextSize;135 p = ReadUInt16(p, nextSize);136 while (nextSize != 0)137 {138 if (nextSize < 3)139 return S_FALSE;140 if (item.Level == 1)141 {142 if (item.PackSize < nextSize)143 return S_FALSE;144 item.PackSize -= nextSize;145 }146 CExtension ext;147 RINOK(CheckReadBytes(&ext.Type, 1))148 nextSize -= 3;149 ext.Data.SetCapacity(nextSize);150 RINOK(CheckReadBytes((Byte *)ext.Data, nextSize))151 item.Extensions.Add(ext);152 Byte hdr2[2];153 RINOK(CheckReadBytes(hdr2, 2));154 ReadUInt16(hdr2, nextSize);155 }156 }157 item.DataPosition = m_Position;158 filled = true;159 return S_OK;160 }162 HRESULT CInArchive::Skeep(UInt64 numBytes)163 {164 UInt64 newPostion;165 RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));166 m_Position += numBytes;167 if (m_Position != newPostion)168 return E_FAIL;169 return S_OK;170 }172 }}