📄 gfile.cpp
字号:
/* Copyright (C) 2006, Mike Gashler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. see http://www.gnu.org/copyleft/lesser.html*/#include "GFile.h"#include "GMacros.h"#include "GDirList.h"#ifdef WIN32# include <windows.h># include <shlobj.h> // to get users' application data dir# include <sys/utime.h> // utime# include <direct.h># include <io.h>#else# include <unistd.h># include <utime.h> // utime, which sets file times#endif // WIN32#include <stdio.h>#include <sys/types.h>#include <stdlib.h> // getenvbool GFile::DoesFileExist(const char *szFilename){ return(access(szFilename, 0) == 0);}bool GFile::DoesDirExist(const char *szDir){ char szBuff[256]; char* pCurDir = getcwd(szBuff, 255); int nVal = chdir(szDir); chdir(pCurDir); return(nVal == 0);}bool GFile::MakeDir(char* szDir){ bool bOK = false; int n; for(n = 0; ; n++) { if(szDir[n] == '/' || szDir[n] == '\\' || szDir[n] == '\0') { char cTmp = szDir[n]; szDir[n] = '\0';#ifdef WIN32 bOK = (mkdir(szDir) == 0);#else // WIN32 bOK = (mkdir(szDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0); // read/write/search permissions for owner and group, and with read/search permissions for others#endif // !WIN32 szDir[n] = cTmp; if(cTmp == '\0') break; } } return bOK;}// Find the last slash and return what's past thatconst char* GFile::ClipPath(const char* szBuff){ int n = 0; int i = 0; while(szBuff[i] != 0) { if(szBuff[i] == '\\' || szBuff[i] == '/') n = i + 1; i++; } return(szBuff + n);}// Find the last slash and set it to '\0'char* GFile::ClipFilename(char* szBuff){ int n = -1; int i = 0; while(szBuff[i] != 0) { if(szBuff[i] == '\\' || szBuff[i] == '/') n = i; i++; } if(n > -1) szBuff[n + 1] = '\0'; return szBuff;}bool GFile::CpyFile(const char* szSrcPath, const char* szDestPath){ FILE* pSrc = fopen(szSrcPath, "rb"); if(!pSrc) return false;// create the subdirectory GTEMPBUF(char, szSubdirectoryString, strlen(szDestPath)+ 1); strcpy(szSubdirectoryString, szDestPath); ClipFilename(szSubdirectoryString); MakeDir(szSubdirectoryString); FILE* pDest = fopen(szDestPath, "wb"); if(!pDest) { fclose(pSrc); return false; } char szBuf[1024]; int nFileSize = filelength(fileno(pSrc)); int nChunkSize; while(nFileSize > 0) { nChunkSize = MIN(nFileSize, 1024); fread(szBuf, nChunkSize, 1, pSrc); fwrite(szBuf, nChunkSize, 1, pDest); nFileSize -= nChunkSize; } fclose(pSrc); fclose(pDest); return true;}bool GFile::GetGoodLocalStorageDirectory(char *toHere){ char *szReturnValue = NULL; toHere[0] = '\0';#ifdef WIN32 TCHAR szPath[MAX_PATH]; // *** If you use VisualStudio 6.0 and you get an error on the // next line then you need to get the Feb 2003 update of the // Platform SDK. (This is the last version that supports VS6). if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, szPath))) { printf("\nWindows System App Directory: %s", szPath); strcpy(toHere, szPath); return true; }#endif // now Linux/Mac OS#ifndef __linux__ // Mac OS printf("Mac OS is not set up for directory structure, but using the Linux one's...\n"); /* TODOR #include <CoreFoundation/CoreFoundation.h> #include <ApplicationServices/ApplicationServices.h> CFStringRef shortUserName; CFNumberRef userUID; CFBooleanRef userIsActive; CFBooleanRef loginCompleted; int MyCGGetSessionInfo { CFDictionaryRef sessionInfoDict; sessionInfoDict = CGSessionCopyCurrentDictionary(); if (sessionInfoDict == NULL) { printf("Unable to get session dictionary."); return(1); } shortUserName = CFDictionaryGetValue(sessionInfoDict, kCGSessionUserNameKey); userUID = CFDictionaryGetValue(sessionInfoDict, kCGSessionUserIDKey); userIsActive = CFDictionaryGetValue(sessionInfoDict, kCGSessionOnConsoleKey); loginCompleted = CFDictionaryGetValue(sessionInfoDict, kCGSessionLoginDoneKey); } */#endif szReturnValue = getenv("HOME"); if(!szReturnValue) szReturnValue = getenv("HOMEPATH"); if(!szReturnValue) szReturnValue = getenv("USERPROFILE"); strcpy(toHere, szReturnValue); return szReturnValue != NULL; // if we were successful this will have been set to something...}/*static*/ char* GFile::LoadFileToBuffer(const char* szFilename, int* pnSize){ // Load the script FileHolder fh(fopen(szFilename, "rb")); FILE* pFile = fh.Get(); if(!pFile) return NULL; int nFileSize = filelength(fileno(pFile)); *pnSize = nFileSize; ArrayHolder<char*> hBuffer(new char[nFileSize + 1]); GAssert(hBuffer.Get(), "out of memory"); int nBytesRead = fread(hBuffer.Get(), sizeof(char), nFileSize, pFile); int err = ferror(pFile); if(err != 0 || nBytesRead != nFileSize) { GAssert(false, "Error reading file"); return NULL; } hBuffer.Get()[nFileSize] = '\0'; // null terminate the string that represents the file, now copied to the memory in hBuffer [?] [rdp] return hBuffer.Drop();}/*static*/ bool GFile::SaveBufferToFile(unsigned char* pBuf, int nSize, const char* szFilename){ FileHolder fh(fopen(szFilename, "wb")); FILE* pFile = fh.Get(); if(!pFile) return false; if(fwrite(pBuf, nSize, 1, pFile) != 1) return false; return true;}void GFile::CondensePath(char* szPath){ int n;#ifdef WIN32 for(n = 0; szPath[n] != '\0'; n++) { if(szPath[n] == '\\') szPath[n] = '/'; }#endif // WIN32 int nPrevSlash = -1; int nPrevPrevSlash = -1; for(n = 0; szPath[n] != '\0'; n++) { if(szPath[n] == '/') { nPrevPrevSlash = nPrevSlash; nPrevSlash = n; if(strncmp(szPath + n, "/./", 3) == 0) { int nDelSize = 2; int i; for(i = n + 1; ; i++) { szPath[i] = szPath[i + nDelSize]; if(szPath[i] == '\0') break; } n--; // so we'll catch the current slash the next time around the loop -- handle it next time! } else if(nPrevPrevSlash >= 0 && strncmp(szPath + n, "/../", 4) == 0) { int nDelSize = n - nPrevPrevSlash + 3; int i; for(i = nPrevPrevSlash; ; i++) { szPath[i] = szPath[i + nDelSize]; if(szPath[i] == '\0') break; } nPrevSlash = -1; nPrevPrevSlash = -1; n = -1; } } }}// statictime_t GFile::GetModifiedTime(const char* szFilename){ struct stat buffer; /*int status = */stat(szFilename, &buffer); // todo: check return value return buffer.st_mtime; // number of seconds since 0000 UTC 1970... :-)}// staticvoid GFile::SetModifiedTime(const char* szFilename, time_t t){ struct stat bufferIn; /*int status = */stat(szFilename, &bufferIn); struct utimbuf bufferOut; bufferOut.actime = bufferIn.st_atime; bufferOut.modtime = t; utime(szFilename, &bufferOut);}// staticbool GFile::ShredFile(const char* szFilename){#ifdef WIN32 char szTmp[4096]; int i; for(i = 0; i < 4096; i++) szTmp[i] = rand() % 256; FILE* pFile = fopen(szFilename, "r+"); if(!pFile) return false; FileHolder hFile(pFile); int nFileSize = filelength(fileno(pFile)); while(nFileSize > 0) { fwrite(szTmp, 1, 4096, pFile); nFileSize -= 4096; } fflush(pFile); hFile.Close(); return DeleteFile(szFilename) ? true : false;#else // WIN32 GTEMPBUF(char, szTmp, strlen(szFilename + 32)); strcpy(szTmp, "shred -fun1 "); strcat(szTmp, szFilename); system(szTmp); return true;#endif // !WIN32}// staticbool GFile::ShredFolder(const char* szPath){ char* szOldDir = new char[300]; Holder<char*> hOldDir(szOldDir); getcwd(szOldDir, 300); // Recurse subdirs { if(chdir(szPath) != 0) return false; GDirList dl(false, false, true, false); while(true) { const char* szDir = dl.GetNext(); if(!szDir) break; ShredFolder(szDir); } } // Delete files bool bOK = true; { GDirList dl(false, true, false, false); while(true) { const char* szFile = dl.GetNext(); if(!szFile) break; if(!GFile::ShredFile(szFile)) bOK = false; } } // Remove the empty folder chdir(szOldDir);#ifdef WIN32 RemoveDirectory(szPath);#else // WIN32 rmdir(szPath);#endif // !WIN32 return bOK;}// staticvoid GFile::ParsePath(const char* szPath, struct PathData* pData){#ifdef WIN32 if(szPath[0] != '\0' && szPath[1] == ':') pData->dirStart = 2; else pData->dirStart = 0;#else pData->dirStart = 0;#endif // !WIN32 int n; int lastSlash = -1; int lastPeriod = -1; for(n = pData->dirStart; szPath[n] != '\0'; n++) { if(szPath[n] == '/'#ifdef WIN32 || szPath[n] == '\\'#endif // WIN32 ) lastSlash = n; else if(szPath[n] == '.') lastPeriod = n; } pData->fileStart = lastSlash + 1; if(lastPeriod < lastSlash) pData->extStart = n; else pData->extStart = lastPeriod; pData->len = n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -