CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/GeneratorInterface/ReggeGribovPartonMCInterface/src/7zFile.cc

Go to the documentation of this file.
00001 /* 7zFile.c -- File IO
00002 2009-11-24 : Igor Pavlov : Public domain */
00003 
00004 #include "7zFile.h"
00005 
00006 #ifndef USE_WINDOWS_FILE
00007 
00008 #ifndef UNDER_CE
00009 #include <errno.h>
00010 #endif
00011 
00012 #else
00013 
00014 /*
00015    ReadFile and WriteFile functions in Windows have BUG:
00016    If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
00017    from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
00018    (Insufficient system resources exist to complete the requested service).
00019    Probably in some version of Windows there are problems with other sizes:
00020    for 32 MB (maybe also for 16 MB).
00021    And message can be "Network connection was lost"
00022 */
00023 
00024 #define kChunkSizeMax (1 << 22)
00025 
00026 #endif
00027 
00028 void File_Construct(CSzFile *p)
00029 {
00030   #ifdef USE_WINDOWS_FILE
00031   p->handle = INVALID_HANDLE_VALUE;
00032   #else
00033   p->file = NULL;
00034   #endif
00035 }
00036 
00037 #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
00038 static WRes File_Open(CSzFile *p, const char *name, int writeMode)
00039 {
00040   #ifdef USE_WINDOWS_FILE
00041   p->handle = CreateFileA(name,
00042       writeMode ? GENERIC_WRITE : GENERIC_READ,
00043       FILE_SHARE_READ, NULL,
00044       writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
00045       FILE_ATTRIBUTE_NORMAL, NULL);
00046   return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
00047   #else
00048   p->file = fopen(name, writeMode ? "wb+" : "rb");
00049   return (p->file != 0) ? 0 :
00050     #ifdef UNDER_CE
00051     2; /* ENOENT */
00052     #else
00053     errno;
00054     #endif
00055   #endif
00056 }
00057 
00058 WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
00059 WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
00060 #endif
00061 
00062 #ifdef USE_WINDOWS_FILE
00063 static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
00064 {
00065   p->handle = CreateFileW(name,
00066       writeMode ? GENERIC_WRITE : GENERIC_READ,
00067       FILE_SHARE_READ, NULL,
00068       writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
00069       FILE_ATTRIBUTE_NORMAL, NULL);
00070   return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
00071 }
00072 WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
00073 WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
00074 #endif
00075 
00076 WRes File_Close(CSzFile *p)
00077 {
00078   #ifdef USE_WINDOWS_FILE
00079   if (p->handle != INVALID_HANDLE_VALUE)
00080   {
00081     if (!CloseHandle(p->handle))
00082       return GetLastError();
00083     p->handle = INVALID_HANDLE_VALUE;
00084   }
00085   #else
00086   if (p->file != NULL)
00087   {
00088     int res = fclose(p->file);
00089     if (res != 0)
00090       return res;
00091     p->file = NULL;
00092   }
00093   #endif
00094   return 0;
00095 }
00096 
00097 WRes File_Read(CSzFile *p, void *data, size_t *size)
00098 {
00099   size_t originalSize = *size;
00100   if (originalSize == 0)
00101     return 0;
00102 
00103   #ifdef USE_WINDOWS_FILE
00104 
00105   *size = 0;
00106   do
00107   {
00108     DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
00109     DWORD processed = 0;
00110     BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
00111     data = (void *)((Byte *)data + processed);
00112     originalSize -= processed;
00113     *size += processed;
00114     if (!res)
00115       return GetLastError();
00116     if (processed == 0)
00117       break;
00118   }
00119   while (originalSize > 0);
00120   return 0;
00121 
00122   #else
00123   
00124   *size = fread(data, 1, originalSize, p->file);
00125   if (*size == originalSize)
00126     return 0;
00127   return ferror(p->file);
00128   
00129   #endif
00130 }
00131 
00132 WRes File_Write(CSzFile *p, const void *data, size_t *size)
00133 {
00134   size_t originalSize = *size;
00135   if (originalSize == 0)
00136     return 0;
00137   
00138   #ifdef USE_WINDOWS_FILE
00139 
00140   *size = 0;
00141   do
00142   {
00143     DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
00144     DWORD processed = 0;
00145     BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
00146     data = (void *)((Byte *)data + processed);
00147     originalSize -= processed;
00148     *size += processed;
00149     if (!res)
00150       return GetLastError();
00151     if (processed == 0)
00152       break;
00153   }
00154   while (originalSize > 0);
00155   return 0;
00156 
00157   #else
00158 
00159   *size = fwrite(data, 1, originalSize, p->file);
00160   if (*size == originalSize)
00161     return 0;
00162   return ferror(p->file);
00163   
00164   #endif
00165 }
00166 
00167 WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
00168 {
00169   #ifdef USE_WINDOWS_FILE
00170 
00171   LARGE_INTEGER value;
00172   DWORD moveMethod;
00173   value.LowPart = (DWORD)*pos;
00174   value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
00175   switch (origin)
00176   {
00177     case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
00178     case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
00179     case SZ_SEEK_END: moveMethod = FILE_END; break;
00180     default: return ERROR_INVALID_PARAMETER;
00181   }
00182   value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
00183   if (value.LowPart == 0xFFFFFFFF)
00184   {
00185     WRes res = GetLastError();
00186     if (res != NO_ERROR)
00187       return res;
00188   }
00189   *pos = ((Int64)value.HighPart << 32) | value.LowPart;
00190   return 0;
00191 
00192   #else
00193   
00194   int moveMethod;
00195   int res;
00196   switch (origin)
00197   {
00198     case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
00199     case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
00200     case SZ_SEEK_END: moveMethod = SEEK_END; break;
00201     default: return 1;
00202   }
00203   res = fseek(p->file, (long)*pos, moveMethod);
00204   *pos = ftell(p->file);
00205   return res;
00206   
00207   #endif
00208 }
00209 
00210 WRes File_GetLength(CSzFile *p, UInt64 *length)
00211 {
00212   #ifdef USE_WINDOWS_FILE
00213   
00214   DWORD sizeHigh;
00215   DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
00216   if (sizeLow == 0xFFFFFFFF)
00217   {
00218     DWORD res = GetLastError();
00219     if (res != NO_ERROR)
00220       return res;
00221   }
00222   *length = (((UInt64)sizeHigh) << 32) + sizeLow;
00223   return 0;
00224   
00225   #else
00226   
00227   long pos = ftell(p->file);
00228   int res = fseek(p->file, 0, SEEK_END);
00229   *length = ftell(p->file);
00230   fseek(p->file, pos, SEEK_SET);
00231   return res;
00232   
00233   #endif
00234 }
00235 
00236 
00237 /* ---------- FileSeqInStream ---------- */
00238 
00239 static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
00240 {
00241   CFileSeqInStream *p = (CFileSeqInStream *)pp;
00242   return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
00243 }
00244 
00245 void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
00246 {
00247   p->s.Read = FileSeqInStream_Read;
00248 }
00249 
00250 
00251 /* ---------- FileInStream ---------- */
00252 
00253 static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
00254 {
00255   CFileInStream *p = (CFileInStream *)pp;
00256   return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
00257 }
00258 
00259 static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
00260 {
00261   CFileInStream *p = (CFileInStream *)pp;
00262   return File_Seek(&p->file, pos, origin);
00263 }
00264 
00265 void FileInStream_CreateVTable(CFileInStream *p)
00266 {
00267   p->s.Read = FileInStream_Read;
00268   p->s.Seek = FileInStream_Seek;
00269 }
00270 
00271 
00272 /* ---------- FileOutStream ---------- */
00273 
00274 static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
00275 {
00276   CFileOutStream *p = (CFileOutStream *)pp;
00277   File_Write(&p->file, data, &size);
00278   return size;
00279 }
00280 
00281 void FileOutStream_CreateVTable(CFileOutStream *p)
00282 {
00283   p->s.Write = FileOutStream_Write;
00284 }