]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
2 2008-11-22 : Igor Pavlov : Public domain */
6 #ifndef USE_WINDOWS_FILE
12 #ifdef USE_WINDOWS_FILE
15 ReadFile and WriteFile functions in Windows have BUG:
16 If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
17 from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
18 (Insufficient system resources exist to complete the requested service).
19 Probably in some version of Windows there are problems with other sizes:
20 for 32 MB (maybe also for 16 MB).
21 And message can be "Network connection was lost"
24 #define kChunkSizeMax (1 << 22)
28 void File_Construct(CSzFile
*p
)
30 #ifdef USE_WINDOWS_FILE
31 p
->handle
= INVALID_HANDLE_VALUE
;
37 static WRes
File_Open(CSzFile
*p
, const char *name
, int writeMode
)
39 #ifdef USE_WINDOWS_FILE
40 p
->handle
= CreateFileA(name
,
41 writeMode
? GENERIC_WRITE
: GENERIC_READ
,
42 FILE_SHARE_READ
, NULL
,
43 writeMode
? CREATE_ALWAYS
: OPEN_EXISTING
,
44 FILE_ATTRIBUTE_NORMAL
, NULL
);
45 return (p
->handle
!= INVALID_HANDLE_VALUE
) ? 0 : GetLastError();
47 p
->file
= fopen(name
, writeMode
? "wb+" : "rb");
48 return (p
->file
!= 0) ? 0 : errno
;
52 WRes
InFile_Open(CSzFile
*p
, const char *name
) { return File_Open(p
, name
, 0); }
53 WRes
OutFile_Open(CSzFile
*p
, const char *name
) { return File_Open(p
, name
, 1); }
55 WRes
File_Close(CSzFile
*p
)
57 #ifdef USE_WINDOWS_FILE
58 if (p
->handle
!= INVALID_HANDLE_VALUE
)
60 if (!CloseHandle(p
->handle
))
61 return GetLastError();
62 p
->handle
= INVALID_HANDLE_VALUE
;
67 int res
= fclose(p
->file
);
76 WRes
File_Read(CSzFile
*p
, void *data
, size_t *size
)
78 size_t originalSize
= *size
;
79 if (originalSize
== 0)
82 #ifdef USE_WINDOWS_FILE
87 DWORD curSize
= (originalSize
> kChunkSizeMax
) ? kChunkSizeMax
: (DWORD
)originalSize
;
89 BOOL res
= ReadFile(p
->handle
, data
, curSize
, &processed
, NULL
);
90 data
= (void *)((Byte
*)data
+ processed
);
91 originalSize
-= processed
;
94 return GetLastError();
98 while (originalSize
> 0);
103 *size
= fread(data
, 1, originalSize
, p
->file
);
104 if (*size
== originalSize
)
106 return ferror(p
->file
);
111 WRes
File_Write(CSzFile
*p
, const void *data
, size_t *size
)
113 size_t originalSize
= *size
;
114 if (originalSize
== 0)
117 #ifdef USE_WINDOWS_FILE
122 DWORD curSize
= (originalSize
> kChunkSizeMax
) ? kChunkSizeMax
: (DWORD
)originalSize
;
124 BOOL res
= WriteFile(p
->handle
, data
, curSize
, &processed
, NULL
);
125 data
= (void *)((Byte
*)data
+ processed
);
126 originalSize
-= processed
;
129 return GetLastError();
133 while (originalSize
> 0);
138 *size
= fwrite(data
, 1, originalSize
, p
->file
);
139 if (*size
== originalSize
)
141 return ferror(p
->file
);
146 WRes
File_Seek(CSzFile
*p
, Int64
*pos
, ESzSeek origin
)
148 #ifdef USE_WINDOWS_FILE
152 value
.LowPart
= (DWORD
)*pos
;
153 value
.HighPart
= (LONG
)((UInt64
)*pos
>> 16 >> 16); /* for case when UInt64 is 32-bit only */
156 case SZ_SEEK_SET
: moveMethod
= FILE_BEGIN
; break;
157 case SZ_SEEK_CUR
: moveMethod
= FILE_CURRENT
; break;
158 case SZ_SEEK_END
: moveMethod
= FILE_END
; break;
159 default: return ERROR_INVALID_PARAMETER
;
161 value
.LowPart
= SetFilePointer(p
->handle
, value
.LowPart
, &value
.HighPart
, moveMethod
);
162 if (value
.LowPart
== 0xFFFFFFFF)
164 WRes res
= GetLastError();
168 *pos
= ((Int64
)value
.HighPart
<< 32) | value
.LowPart
;
177 case SZ_SEEK_SET
: moveMethod
= SEEK_SET
; break;
178 case SZ_SEEK_CUR
: moveMethod
= SEEK_CUR
; break;
179 case SZ_SEEK_END
: moveMethod
= SEEK_END
; break;
182 res
= fseek(p
->file
, (long)*pos
, moveMethod
);
183 *pos
= ftell(p
->file
);
189 WRes
File_GetLength(CSzFile
*p
, UInt64
*length
)
191 #ifdef USE_WINDOWS_FILE
194 DWORD sizeLow
= GetFileSize(p
->handle
, &sizeHigh
);
195 if (sizeLow
== 0xFFFFFFFF)
197 DWORD res
= GetLastError();
201 *length
= (((UInt64
)sizeHigh
) << 32) + sizeLow
;
206 long pos
= ftell(p
->file
);
207 int res
= fseek(p
->file
, 0, SEEK_END
);
208 *length
= ftell(p
->file
);
209 fseek(p
->file
, pos
, SEEK_SET
);
216 /* ---------- FileSeqInStream ---------- */
218 static SRes
FileSeqInStream_Read(void *pp
, void *buf
, size_t *size
)
220 CFileSeqInStream
*p
= (CFileSeqInStream
*)pp
;
221 return File_Read(&p
->file
, buf
, size
) == 0 ? SZ_OK
: SZ_ERROR_READ
;
224 void FileSeqInStream_CreateVTable(CFileSeqInStream
*p
)
226 p
->s
.Read
= FileSeqInStream_Read
;
230 /* ---------- FileInStream ---------- */
232 static SRes
FileInStream_Read(void *pp
, void *buf
, size_t *size
)
234 CFileInStream
*p
= (CFileInStream
*)pp
;
235 return (File_Read(&p
->file
, buf
, size
) == 0) ? SZ_OK
: SZ_ERROR_READ
;
238 static SRes
FileInStream_Seek(void *pp
, Int64
*pos
, ESzSeek origin
)
240 CFileInStream
*p
= (CFileInStream
*)pp
;
241 return File_Seek(&p
->file
, pos
, origin
);
244 void FileInStream_CreateVTable(CFileInStream
*p
)
246 p
->s
.Read
= FileInStream_Read
;
247 p
->s
.Seek
= FileInStream_Seek
;
251 /* ---------- FileOutStream ---------- */
253 static size_t FileOutStream_Write(void *pp
, const void *data
, size_t size
)
255 CFileOutStream
*p
= (CFileOutStream
*)pp
;
256 File_Write(&p
->file
, data
, &size
);
260 void FileOutStream_CreateVTable(CFileOutStream
*p
)
262 p
->s
.Write
= FileOutStream_Write
;