File indexing completed on 2023-03-17 11:05:02
0001
0002
0003
0004 #include "7zFile.h"
0005
0006 #ifndef USE_WINDOWS_FILE
0007
0008 #ifndef UNDER_CE
0009 #include <cerrno>
0010 #endif
0011
0012 #else
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define kChunkSizeMax (1 << 22)
0025
0026 #endif
0027
0028 void File_Construct(CSzFile *p) {
0029 #ifdef USE_WINDOWS_FILE
0030 p->handle = INVALID_HANDLE_VALUE;
0031 #else
0032 p->file = nullptr;
0033 #endif
0034 }
0035
0036 #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
0037 static WRes File_Open(CSzFile *p, const char *name, int writeMode) {
0038 #ifdef USE_WINDOWS_FILE
0039 p->handle = CreateFileA(name,
0040 writeMode ? GENERIC_WRITE : GENERIC_READ,
0041 FILE_SHARE_READ,
0042 NULL,
0043 writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
0044 FILE_ATTRIBUTE_NORMAL,
0045 NULL);
0046 return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
0047 #else
0048 p->file = fopen(name, writeMode ? "wb+" : "rb");
0049 return (p->file != nullptr) ? 0 :
0050 #ifdef UNDER_CE
0051 2;
0052 #else
0053 errno;
0054 #endif
0055 #endif
0056 }
0057
0058 WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
0059 WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
0060 #endif
0061
0062 #ifdef USE_WINDOWS_FILE
0063 static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) {
0064 p->handle = CreateFileW(name,
0065 writeMode ? GENERIC_WRITE : GENERIC_READ,
0066 FILE_SHARE_READ,
0067 NULL,
0068 writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
0069 FILE_ATTRIBUTE_NORMAL,
0070 NULL);
0071 return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
0072 }
0073 WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
0074 WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
0075 #endif
0076
0077 WRes File_Close(CSzFile *p) {
0078 #ifdef USE_WINDOWS_FILE
0079 if (p->handle != INVALID_HANDLE_VALUE) {
0080 if (!CloseHandle(p->handle))
0081 return GetLastError();
0082 p->handle = INVALID_HANDLE_VALUE;
0083 }
0084 #else
0085 if (p->file != nullptr) {
0086 int res = fclose(p->file);
0087 if (res != 0)
0088 return res;
0089 p->file = nullptr;
0090 }
0091 #endif
0092 return 0;
0093 }
0094
0095 WRes File_Read(CSzFile *p, void *data, size_t *size) {
0096 size_t originalSize = *size;
0097 if (originalSize == 0)
0098 return 0;
0099
0100 #ifdef USE_WINDOWS_FILE
0101
0102 *size = 0;
0103 do {
0104 DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
0105 DWORD processed = 0;
0106 BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
0107 data = (void *)((Byte *)data + processed);
0108 originalSize -= processed;
0109 *size += processed;
0110 if (!res)
0111 return GetLastError();
0112 if (processed == 0)
0113 break;
0114 } while (originalSize > 0);
0115 return 0;
0116
0117 #else
0118
0119 *size = fread(data, 1, originalSize, p->file);
0120 if (*size == originalSize)
0121 return 0;
0122 return ferror(p->file);
0123
0124 #endif
0125 }
0126
0127 WRes File_Write(CSzFile *p, const void *data, size_t *size) {
0128 size_t originalSize = *size;
0129 if (originalSize == 0)
0130 return 0;
0131
0132 #ifdef USE_WINDOWS_FILE
0133
0134 *size = 0;
0135 do {
0136 DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
0137 DWORD processed = 0;
0138 BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
0139 data = (void *)((Byte *)data + processed);
0140 originalSize -= processed;
0141 *size += processed;
0142 if (!res)
0143 return GetLastError();
0144 if (processed == 0)
0145 break;
0146 } while (originalSize > 0);
0147 return 0;
0148
0149 #else
0150
0151 *size = fwrite(data, 1, originalSize, p->file);
0152 if (*size == originalSize)
0153 return 0;
0154 return ferror(p->file);
0155
0156 #endif
0157 }
0158
0159 WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) {
0160 #ifdef USE_WINDOWS_FILE
0161
0162 LARGE_INTEGER value;
0163 DWORD moveMethod;
0164 value.LowPart = (DWORD)*pos;
0165 value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16);
0166 switch (origin) {
0167 case SZ_SEEK_SET:
0168 moveMethod = FILE_BEGIN;
0169 break;
0170 case SZ_SEEK_CUR:
0171 moveMethod = FILE_CURRENT;
0172 break;
0173 case SZ_SEEK_END:
0174 moveMethod = FILE_END;
0175 break;
0176 default:
0177 return ERROR_INVALID_PARAMETER;
0178 }
0179 value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
0180 if (value.LowPart == 0xFFFFFFFF) {
0181 WRes res = GetLastError();
0182 if (res != NO_ERROR)
0183 return res;
0184 }
0185 *pos = ((Int64)value.HighPart << 32) | value.LowPart;
0186 return 0;
0187
0188 #else
0189
0190 int moveMethod;
0191 int res;
0192 switch (origin) {
0193 case SZ_SEEK_SET:
0194 moveMethod = SEEK_SET;
0195 break;
0196 case SZ_SEEK_CUR:
0197 moveMethod = SEEK_CUR;
0198 break;
0199 case SZ_SEEK_END:
0200 moveMethod = SEEK_END;
0201 break;
0202 default:
0203 return 1;
0204 }
0205 res = fseek(p->file, (long)*pos, moveMethod);
0206 *pos = ftell(p->file);
0207 return res;
0208
0209 #endif
0210 }
0211
0212 WRes File_GetLength(CSzFile *p, UInt64 *length) {
0213 #ifdef USE_WINDOWS_FILE
0214
0215 DWORD sizeHigh;
0216 DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
0217 if (sizeLow == 0xFFFFFFFF) {
0218 DWORD res = GetLastError();
0219 if (res != NO_ERROR)
0220 return res;
0221 }
0222 *length = (((UInt64)sizeHigh) << 32) + sizeLow;
0223 return 0;
0224
0225 #else
0226
0227 long pos = ftell(p->file);
0228 int res = fseek(p->file, 0, SEEK_END);
0229 *length = ftell(p->file);
0230 fseek(p->file, pos, SEEK_SET);
0231 return res;
0232
0233 #endif
0234 }
0235
0236
0237
0238 static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) {
0239 CFileSeqInStream *p = (CFileSeqInStream *)pp;
0240 return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
0241 }
0242
0243 void FileSeqInStream_CreateVTable(CFileSeqInStream *p) { p->s.Read = FileSeqInStream_Read; }
0244
0245
0246
0247 static SRes FileInStream_Read(void *pp, void *buf, size_t *size) {
0248 CFileInStream *p = (CFileInStream *)pp;
0249 return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
0250 }
0251
0252 static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) {
0253 CFileInStream *p = (CFileInStream *)pp;
0254 return File_Seek(&p->file, pos, origin);
0255 }
0256
0257 void FileInStream_CreateVTable(CFileInStream *p) {
0258 p->s.Read = FileInStream_Read;
0259 p->s.Seek = FileInStream_Seek;
0260 }
0261
0262
0263
0264 static size_t FileOutStream_Write(void *pp, const void *data, size_t size) {
0265 CFileOutStream *p = (CFileOutStream *)pp;
0266 File_Write(&p->file, data, &size);
0267 return size;
0268 }
0269
0270 void FileOutStream_CreateVTable(CFileOutStream *p) { p->s.Write = FileOutStream_Write; }