7Z源码分析——7z.h

#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
extern const Byte k7zSignature[k7zSignatureSize];

文件的开头处定义了2个宏,k7zStartHeaderSize 是7z文件头的大小(详情可见7z文件格式及其源码的分析(三));k7zSignatureSize是7z文件标志的大小;k7zSignature是7z文件标志(是一个常量,7zArcIn.c中定义了const Byte k7zSignature[k7zSignatureSize] = {‘7’, ‘z’, 0xBC, 0xAF, 0x27, 0x1C};)。

typedef struct
{
  const Byte *Data;
  size_t Size;
} CSzData;

结构体CSzData的第一个变量是一个指向常量的指针(Data指向地址的内容不可改变,但是Data指向的地址是可以改变的),第二个变量是size_t类型的,表示Data的大小。

/* CSzCoderInfo & CSzFolder support only default methods */

typedef struct
{
  size_t PropsOffset;
  UInt32 MethodID;
  Byte NumStreams;
  Byte PropsSize;
} CSzCoderInfo;

typedef struct
{
  UInt32 InIndex;
  UInt32 OutIndex;
} CSzBond;

#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4

typedef struct
{
  UInt32 NumCoders;
  UInt32 NumBonds;
  UInt32 NumPackStreams;
  UInt32 UnpackStream;
  UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
  CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
  CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;

先介绍三个宏的意义,SZ_NUM_CODERS_IN_FOLDER_MAX表示支持的压缩算法种类的最大个数(从源码和7z软件都可以看出,只支持LZMA2、LZMA、PPMD、BZIP2四种压缩);SZ_NUM_BONDS_IN_FOLDER_MAX表示绑定对的最大个数;SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX表示打包数据流的最大个数。

CSzCoderInfo描述了一个coder的信息(coder的解释见7z文件格式及其源码的分析(四)),PropsOffset是属性的偏移,MethodID是压缩算法ID(ID的定义见7zDec.c),NumStreams数据流的个数,PropsSize是属性大小。
CSzBond描述了绑定对的信息,InIndex是输入索引,OutIndex是输出索引。
CSzFolder描述了文件夹的信息,NumCoders是coder的个数,NumBonds是绑定对的个数,NumPackStreams是打包数据流的个数,UnpackStream是解包流,PackStreams存放的是打包流,Bonds存放的是绑定对的信息,Coders存放的是coder的信息。

typedef struct
{
  UInt32 Low;
  UInt32 High;
} CNtfsFileTime;

typedef struct
{
  Byte *Defs; /* MSB 0 bit numbering */
  UInt32 *Vals;
} CSzBitUi32s;

typedef struct
{
  Byte *Defs; /* MSB 0 bit numbering */
  // UInt64 *Vals;
  CNtfsFileTime *Vals;
} CSzBitUi64s;

CNtfsFileTime表示一个64位的值(类似于结构体FILETIME的定义)。
CSzBitUi32s表示无符号32位数值。
CSzBitUi64s表示无符号64位数值。

typedef struct
{
  UInt32 NumPackStreams;
  UInt32 NumFolders;

  UInt64 *PackPositions;          // NumPackStreams + 1
  CSzBitUi32s FolderCRCs;         // NumFolders

  size_t *FoCodersOffsets;        // NumFolders + 1
  UInt32 *FoStartPackStreamIndex; // NumFolders + 1
  UInt32 *FoToCoderUnpackSizes;   // NumFolders + 1
  Byte *FoToMainUnpackSizeIndex;  // NumFolders
  UInt64 *CoderUnpackSizes;       // for all coders in all folders

  Byte *CodersData;
} CSzAr;
typedef struct
{
  CSzAr db;

  UInt64 startPosAfterHeader;
  UInt64 dataPos;

  UInt32 NumFiles;

  UInt64 *UnpackPositions;  // NumFiles + 1
  // Byte *IsEmptyFiles;
  Byte *IsDirs;
  CSzBitUi32s CRCs;

  CSzBitUi32s Attribs;
  // CSzBitUi32s Parents;
  CSzBitUi64s MTime;
  CSzBitUi64s CTime;

  UInt32 *FolderToFile;   // NumFolders + 1
  UInt32 *FileToFolder;   // NumFiles

  size_t *FileNameOffsets; /* in 2-byte steps */
  Byte *FileNames;  /* UTF-16-LE */
} CSzArEx;

对于CSzAr和CSzArEx每个变量的意义,只能从变量名进行猜测(从作者的注释可以看到有些变量应该存放的值),对于CSzAr和CSzArEx中Ar是什么的简称,我没有猜测出来,从源码看,它们存放的应该是压缩包的信息。

#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)

#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)

#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))

#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])

上面四个宏函数,SzBitArray_Check检查数组比特位是否为0;SzBitWithVals_Check检查数据比特位是否为0;SzArEx_IsDir判断是否是文件夹;SzArEx_GetFileSize获取文件大小。

该头文件中还有一些函数的声明,它们的实现在7zArcIn.c中,后期介绍这个文件的时候,再详细说明。

猜你喜欢

转载自blog.csdn.net/zlanbl085321/article/details/80667976