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

源码下载地址:https://www.7-zip.org/download.html
这里写图片描述
下载后解压,然后使用Visual Studio 2008 SP1(一定要打SP1补丁,不然后面编译会很麻烦,各种报错,然后查看解决办法,也许最终还是回到打SP1补丁……) 打开%7z_source%\CPP\7zip\Bundles\Format7zF\Format7z.dsw,会有如下提示,选择标记的那个:
这里写图片描述
然后快捷键Alt+F7打开工程属性窗口,修改一下输出路径(也可以不修改),F7编译,报错fatal error LNK1107: invalid or corrupt file: cannot read at 0x26D,修改如下两个文件的属性配置:
这里写图片描述
去掉Command Line 中的-omf(两个文件都是如此) ,然后rebuild(build还会报上面的错误,不懂的可以查查rebuild和build的区别)。
这里写图片描述

以上都不是关键,只是为了方便调试罢了。下面开始分析源码,我打算先从%7z_source%\C里面的文件开始(因为这里面是其他类的基础),下面介绍7zTypes.h里面的内容。

#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif

这段对宏EXTERN_C_BEGIN的定义,就不多加解释了,关于extern “C”的作用,参见extern “C”的作用详解
C和C++混合编译

#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17

这组宏是错误码,SZ_OK是执行成功,其他见名知意(具体为什么取这些值,是作者喜好)。

typedef int SRes;
#ifdef _WIN32
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else
typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif

以上自定义了一种数据类型SRes,还有根据不同编译配置的数据类型WRes及宏函数MY_SRes_HRESULT_FROM_WRes(x)(我查看过,HRESULT_FROM_WIN32(x)定义在winerror.h中,#else分支的实现和HRESULT_FROM_WIN32(x)实际走的分支是一样的,估计作者是想32位和非32位的宏函数MY_SRes_HRESULT_FROM_WRes(x)实现保持一致吧,而且7zTypes.h中的许多内容摘自lzma918中Types.h)。7zTypes.h中还有其他类似的自定义类型和宏函数,就不一一介绍了。

/* The following interfaces use first parameter as pointer to structure */

typedef struct IByteIn IByteIn;
struct IByteIn
{
  Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
};
#define IByteIn_Read(p) (p)->Read(p)


typedef struct IByteOut IByteOut;
struct IByteOut
{
  void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)

从作者的注释中可以看出,这两个函数读写一个字节(函数指针,具体实例化在后期的调用中)。

typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
  SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
       (output(*size) < input(*size)) is allowed */
};
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)

读数据流,read()的后两个参数buf 和size既是输入参数又是输出参数,buf存放读出的数据,size作为输入,是期望读到的大小,作为输出,是实际读到的大小(函数指针,具体实例化在后期的调用中)。

typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{
  size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
    /* Returns: result - the number of actually written bytes.
       (result < size) means error */
};
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)

写数据流(类似上面的read函数,具体实例化在后期的调用中)。

typedef enum
{
  SZ_SEEK_SET = 0,
  SZ_SEEK_CUR = 1,
  SZ_SEEK_END = 2
} ESzSeek;


typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{
  SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
  SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size)   (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)

typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
  SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
       (output(*size) > input(*size)) is not allowed
       (output(*size) < input(*size)) is allowed */
  SRes (*Skip)(const ILookInStream *p, size_t offset);
    /* offset must be <= output(*size) of Look */

  SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
    /* reads directly (without buffer). It's same as ISeqInStream::Read */
  SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
};

#define ILookInStream_Look(p, buf, size)   (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset)      (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size)   (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)

类似于文件的操作,只是此处对象是数据流而已。

typedef struct ICompressProgress ICompressProgress;

struct ICompressProgress
{
  SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
    /* Returns: result. (result != SZ_OK) means break.
       Value (UInt64)(Int64)-1 for size means unknown value. */
};
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)

函数指针,用来处理压缩进度。

其他还有一些结构体的定义和函数声明,就不再介绍(详情可看7zTypes.h)。

猜你喜欢

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