3 Test application for 7z Decoder
4 LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02)
13 #include "7zExtract.h"
15 typedef struct _CFileInStream
23 #define kBufferSize (1 << 12)
24 Byte g_Buffer
[kBufferSize
];
26 SZ_RESULT
SzFileReadImp(void *object
, void **buffer
, size_t maxRequiredSize
, size_t *processedSize
)
28 CFileInStream
*s
= (CFileInStream
*)object
;
29 size_t processedSizeLoc
;
30 if (maxRequiredSize
> kBufferSize
)
31 maxRequiredSize
= kBufferSize
;
32 processedSizeLoc
= fread(g_Buffer
, 1, maxRequiredSize
, s
->File
);
34 if (processedSize
!= 0)
35 *processedSize
= processedSizeLoc
;
41 SZ_RESULT
SzFileReadImp(void *object
, void *buffer
, size_t size
, size_t *processedSize
)
43 CFileInStream
*s
= (CFileInStream
*)object
;
44 size_t processedSizeLoc
= fread(buffer
, 1, size
, s
->File
);
45 if (processedSize
!= 0)
46 *processedSize
= processedSizeLoc
;
52 SZ_RESULT
SzFileSeekImp(void *object
, CFileSize pos
)
54 CFileInStream
*s
= (CFileInStream
*)object
;
55 int res
= fseek(s
->File
, (long)pos
, SEEK_SET
);
61 void PrintError(char *sz
)
63 printf("\nERROR: %s\n", sz
);
66 int main(int numargs
, char *args
[])
68 CFileInStream archiveStream
;
69 CArchiveDatabaseEx db
;
72 ISzAlloc allocTempImp
;
74 printf("\n7z ANSI-C Decoder 4.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n");
78 "\nUsage: 7zDec <command> <archive_name>\n\n"
80 " e: Extract files from archive\n"
81 " l: List contents of archive\n"
82 " t: Test integrity of archive\n");
87 PrintError("incorrect command");
91 archiveStream
.File
= fopen(args
[2], "rb");
92 if (archiveStream
.File
== 0)
94 PrintError("can not open input file");
98 archiveStream
.InStream
.Read
= SzFileReadImp
;
99 archiveStream
.InStream
.Seek
= SzFileSeekImp
;
101 allocImp
.Alloc
= SzAlloc
;
102 allocImp
.Free
= SzFree
;
104 allocTempImp
.Alloc
= SzAllocTemp
;
105 allocTempImp
.Free
= SzFreeTemp
;
109 res
= SzArchiveOpen(&archiveStream
.InStream
, &db
, &allocImp
, &allocTempImp
);
112 char *command
= args
[1];
115 int extractCommand
= 0;
116 if (strcmp(command
, "l") == 0)
118 if (strcmp(command
, "t") == 0)
120 else if (strcmp(command
, "e") == 0)
126 for (i
= 0; i
< db
.Database
.NumFiles
; i
++)
128 CFileItem
*f
= db
.Database
.Files
+ i
;
129 printf("%10d %s\n", (int)f
->Size
, f
->Name
);
132 else if (testCommand
|| extractCommand
)
136 // if you need cache, use these 3 variables.
137 // if you use external function, you can make these variable as static.
138 UInt32 blockIndex
= 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
139 Byte
*outBuffer
= 0; // it must be 0 before first call for each new archive.
140 size_t outBufferSize
= 0; // it can have any value before first call (if outBuffer = 0)
143 for (i
= 0; i
< db
.Database
.NumFiles
; i
++)
146 size_t outSizeProcessed
;
147 CFileItem
*f
= db
.Database
.Files
+ i
;
149 printf("Directory ");
154 printf(" %s", f
->Name
);
160 res
= SzExtract(&archiveStream
.InStream
, &db
, i
,
161 &blockIndex
, &outBuffer
, &outBufferSize
,
162 &offset
, &outSizeProcessed
,
163 &allocImp
, &allocTempImp
);
169 UInt32 processedSize
;
170 char *fileName
= f
->Name
;
171 size_t nameLen
= strlen(f
->Name
);
172 for (; nameLen
> 0; nameLen
--)
173 if (f
->Name
[nameLen
- 1] == '/')
175 fileName
= f
->Name
+ nameLen
;
179 outputHandle
= fopen(fileName
, "wb+");
180 if (outputHandle
== 0)
182 PrintError("can not open output file");
186 processedSize
= fwrite(outBuffer
+ offset
, 1, outSizeProcessed
, outputHandle
);
187 if (processedSize
!= outSizeProcessed
)
189 PrintError("can not write output file");
193 if (fclose(outputHandle
))
195 PrintError("can not close output file");
202 allocImp
.Free(outBuffer
);
206 PrintError("incorrect command");
210 SzArDbExFree(&db
, allocImp
.Free
);
212 fclose(archiveStream
.File
);
215 printf("\nEverything is Ok\n");
218 if (res
== SZE_OUTOFMEMORY
)
219 PrintError("can not allocate memory");
221 printf("\nERROR #%d\n", res
);