// Archive/LzhItem.h #ifndef __ARCHIVE_LZH_ITEM_H #define __ARCHIVE_LZH_ITEM_H #include "Common/Types.h" #include "Common/String.h" #include "Common/Buffer.h" #include "LzhHeader.h" namespace NArchive { namespace NLzh { struct CExtension { Byte Type; CByteBuffer Data; AString GetString() const { AString s; for (size_t i = 0; i < Data.GetCapacity(); i++) { char c = (char)Data[i]; if (c == 0) break; s += c; } return s; } }; struct CItem { public: AString Name; Byte Method[kMethodIdSize]; UInt32 PackSize; UInt32 Size; UInt32 ModifiedTime; Byte Attributes; Byte Level; UInt16 CRC; Byte OsId; CObjectVector Extensions; bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } bool IsDirectory() const {return (IsLhMethod() && Method[3] == 'd'); } bool IsCopyMethod() const { return (IsLhMethod() && Method[3] == '0') || (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); } bool IsLh1GroupMethod() const { if (!IsLhMethod()) return false; switch(Method[3]) { case '1': return true; } return false; } bool IsLh4GroupMethod() const { if (!IsLhMethod()) return false; switch(Method[3]) { case '4': case '5': case '6': case '7': return true; } return false; } int GetNumDictBits() const { if (!IsLhMethod()) return 0; switch(Method[3]) { case '1': return 12; case '2': return 13; case '3': return 13; case '4': return 12; case '5': return 13; case '6': return 15; case '7': return 16; } return 0; } int FindExt(Byte type) const { for (int i = 0; i < Extensions.Size(); i++) if (Extensions[i].Type == type) return i; return -1; } bool GetUnixTime(UInt32 &value) const { int index = FindExt(kExtIdUnixTime); if (index < 0) return false; const Byte *data = (const Byte *)(Extensions[index].Data); value = data[0] | ((UInt32)data[1] << 8) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 24); return true; } AString GetDirName() const { int index = FindExt(kExtIdDirName); if (index < 0) return AString(); return Extensions[index].GetString(); } AString GetFileName() const { int index = FindExt(kExtIdFileName); if (index < 0) return Name; return Extensions[index].GetString(); } AString GetName() const { AString dirName = GetDirName(); dirName.Replace((char)0xFF, '\\'); if (!dirName.IsEmpty()) { char c = dirName[dirName.Length() - 1]; if (c != '\\' && c != '/') dirName += '\\'; } return dirName + GetFileName(); } }; class CItemEx: public CItem { public: UInt64 DataPosition; }; }} #endif