00001 #include "flGlobal.h"
00002 #if FL_FILE != 0
00003 #include <pspkernel.h>
00004 #include <string.h>
00005 #include <stdio.h>
00006
00007 #if FL_INCLUDE_ALL_C == 0
00008 #include "flFileSys.h"
00009 #include "flMemory.h"
00010
00011 #if FL_DEBUG != 0
00012 #include "flDebug.h"
00013 #endif
00014 #endif
00015
00016 File* fileOpen(char* inPath, u8 inMode) {
00017 if(!inPath || !inPath[0] || (inMode > 15)) {
00018 #if FL_DEBUG_WARNING != 0
00019 debugWarning("Trying to open file with invalid parameters (inPath: \"%s\", inMode: %i).", inPath, inMode);
00020 #endif
00021 return NULL;
00022 }
00023
00024 File* tempOut = memAlloc(sizeof(File));
00025 if(!tempOut) {
00026 #if FL_DEBUG_WARNING != 0
00027 debugWarning("Couldn't create file struct while opening \"%s\".", inPath);
00028 #endif
00029 return NULL;
00030 }
00031 tempOut->fileMode = inMode;
00032 tempOut->fileState = FILE_STATE_NORMAL;
00033 tempOut->filePath = memAlloc(strlen(inPath) + 1);
00034 if(!tempOut->filePath) {
00035 #if FL_DEBUG_WARNING != 0
00036 debugWarning("Couldn't copy file string while opening \"%s\", probably out of memory.", inPath);
00037 #endif
00038 memFree(tempOut);
00039 return NULL;
00040 }
00041 strcpy(tempOut->filePath, inPath);
00042 tempOut->filePointer = 0;
00043
00044 if(!strncmp(inPath, "mem:/", 5)) {
00045 tempOut->fileType = FILE_TYPE_MEMORY;
00046 int i;
00047 unsigned int tempDataPtr = 0;
00048 for(i = 5; (inPath[i] >= ASCII_0) && (inPath[i] <= ASCII_9); i++) {
00049 tempDataPtr *= 10;
00050 tempDataPtr += (inPath[i] - ASCII_0);
00051 }
00052 tempOut->fileData = (u8*)tempDataPtr;
00053 tempDataPtr = 0;
00054 for(i = 5; (inPath[i] >= ASCII_0) && (inPath[i] <= ASCII_9); i++) {
00055 tempDataPtr *= 10;
00056 tempDataPtr += (inPath[i] - ASCII_0);
00057 }
00058 tempOut->fileSize = tempDataPtr;
00059 return tempOut;
00060 }
00061
00062 char tempMode[4];
00063 memClear(tempMode, 4);
00064
00065 if(inMode & 2)
00066 tempMode[0] = 'w';
00067 else if(!(inMode & 3))
00068 tempMode[0] = 'a';
00069 else
00070 tempMode[0] = 'r';
00071
00072 if(inMode & 4) {
00073 tempMode[1] = 'b';
00074 if(inMode & 8)
00075 tempMode[2] = '+';
00076 } else if(inMode & 8) {
00077 tempMode[1] = '+';
00078 }
00079
00080 if(fileExists(inPath)) {
00081 SceIoStat tempStats;
00082 if(sceIoGetstat(inPath, &tempStats) != 0) {
00083 #if FL_DEBUG_WARNING != 0
00084 debugWarning("Couldn't get file stats for \"%s\".", inPath);
00085 #endif
00086 memFree(tempOut->filePath);
00087 memFree(tempOut);
00088 return NULL;
00089 }
00090 tempOut->fileSize = tempStats.st_size;
00091 } else {
00092 tempOut->fileSize = 0;
00093 }
00094
00095 tempOut->fileData = (u8*)fopen(inPath, tempMode);
00096 if(!tempOut->fileData) {
00097 #if FL_DEBUG_WARNING != 0
00098 debugWarning("Couldn't open file \"%s\".", inPath);
00099 #endif
00100 memFree(tempOut->filePath);
00101 memFree(tempOut);
00102 return NULL;
00103 }
00104 tempOut->fileType = FILE_TYPE_FILE;
00105
00106 return tempOut;
00107 }
00108
00109 void fileClose(File* inFile) {
00110 if(!inFile) {
00111 #if FL_DEBUG_WARNING != 0
00112 debugWarning("Trying to close NULL file.");
00113 #endif
00114 return;
00115 }
00116 if(inFile->fileType == FILE_TYPE_FILE)
00117 fclose((FILE*)inFile->fileData);
00118 memFree(inFile->filePath);
00119 memFree(inFile);
00120 return;
00121 }
00122
00123 bool fileCheckState(File* inFile) {
00124 if(!inFile) {
00125 #if FL_DEBUG_WARNING != 0
00126 debugWarning("Trying to check the state of a NULL file.");
00127 #endif
00128 return false;
00129 }
00130 if(inFile->fileType == FILE_TYPE_FILE) {
00131 if(feof((FILE*)inFile->fileData))
00132 inFile->fileState |= FILE_STATE_EOF;
00133 else
00134 inFile->fileState &= ~FILE_STATE_EOF;
00135 if(ferror((FILE*)inFile->fileData))
00136 inFile->fileState |= FILE_STATE_ERROR;
00137 else
00138 inFile->fileState &= ~FILE_STATE_ERROR;
00139 } else if(inFile->fileType == FILE_TYPE_MEMORY) {
00140 if(inFile->filePointer >= (inFile->fileSize - 1))
00141 inFile->fileState |= FILE_STATE_EOF;
00142 else
00143 inFile->fileState &= ~FILE_STATE_EOF;
00144 if(inFile->filePointer < 0)
00145 inFile->fileState |= FILE_STATE_ERROR;
00146 else
00147 inFile->fileState &= ~FILE_STATE_ERROR;
00148 }
00149 if(inFile->fileState != FILE_STATE_NORMAL)
00150 return false;
00151 return true;
00152 }
00153
00154 void fileSeek(File* inFile, long inSeek, int inMode) {
00155 if(!inFile || ((inMode != FILE_SEEK_SET) && (inMode != FILE_SEEK_CUR) && (inMode != FILE_SEEK_END))) {
00156 #if FL_DEBUG_WARNING != 0
00157 debugWarning("Trying to fseek a NULL file, or fseeking using a bad seek mode.");
00158 #endif
00159 return;
00160 }
00161
00162 if(inFile->fileType == FILE_TYPE_FILE) {
00163 fseek((FILE*)inFile->fileData, inSeek, inMode);
00164 } else if(inFile->fileType == FILE_TYPE_MEMORY) {
00165 if(inMode == FILE_SEEK_SET)
00166 inFile->filePointer = inSeek;
00167 else if(inMode == FILE_SEEK_CUR)
00168 inFile->filePointer += inSeek;
00169 else
00170 inFile->filePointer = (inFile->fileSize + inSeek);
00171 }
00172 }
00173
00174 int fileRead(void* inDest, int inSize, File* inFile) {
00175 if(!fileCheckState(inFile))
00176 return -1;
00177 if(inFile->fileType == FILE_TYPE_FILE) {
00178 inSize = fread(inDest, 1, inSize, (FILE*)inFile->fileData);
00179 } else if(inFile->fileType == FILE_TYPE_MEMORY) {
00180 if((inFile->filePointer + inSize) > inFile->fileSize)
00181 inSize = (inFile->fileSize - (inFile->filePointer + inSize));
00182 memCopy(inDest, &inFile->fileData[inFile->filePointer], inSize);
00183 } else {
00184 #if FL_DEBUG_ERROR != 0
00185 debugError("Trying to read from corrupted file context.");
00186 #endif
00187 return -1;
00188 }
00189 inFile->filePointer += inSize;
00190 return inSize;
00191 }
00192
00193 int fileWrite(void* inSrc, int inSize, File* inFile) {
00194 if(!fileCheckState(inFile))
00195 return -1;
00196 if(inFile->fileType == FILE_TYPE_FILE) {
00197 inSize = fwrite(inSrc, 1, inSize, (FILE*)inFile->fileData);
00198 if((inFile->filePointer + inSize) > inFile->fileSize)
00199 inFile->fileSize = (inFile->filePointer + inSize);
00200 } else if(inFile->fileType == FILE_TYPE_MEMORY) {
00201 if((inFile->filePointer + inSize) > inFile->fileSize)
00202 inSize = (inFile->fileSize - (inFile->filePointer + inSize));
00203 memCopy(&inFile->fileData[inFile->filePointer], inSrc, inSize);
00204 } else {
00205 #if FL_DEBUG_ERROR != 0
00206 debugError("Trying to read from corrupted file context.");
00207 #endif
00208 return -1;
00209 }
00210 inFile->filePointer += inSize;
00211 return inSize;
00212 }
00213
00214 int filePuts(char* inString, File* inFile) {
00215 if(!inString || !inString[0]) {
00216 #if FL_DEBUG_WARNING != 0
00217 debugWarning("Trying print a NULL string to file.");
00218 #endif
00219 return -1;
00220 }
00221 return fileWrite(inString, strlen(inString), inFile);
00222 }
00223
00224 char* fileGets(char* inString, int inCount, File* inFile) {
00225 int i;
00226 for(i = 0; i < (inCount - 1); i++) {
00227 if(fileRead(&inString[i], 1, inFile) != 1)
00228 return NULL;
00229 if(inString[i] == 0)
00230 return inString;
00231 if(inString[i] == '\n') {
00232 i++;
00233 break;
00234 }
00235 }
00236 inString[i] = 0;
00237 return inString;
00238 }
00239
00240 bool fileEOF(File* inFile) {
00241 fileCheckState(inFile);
00242 return (inFile->fileState & FILE_STATE_EOF);
00243 }
00244
00245 bool fileError(File* inFile) {
00246 fileCheckState(inFile);
00247 return (inFile->fileState & FILE_STATE_ERROR);
00248 }
00249
00250 char fileTypeGet(char* inPath) {
00251 if(!inPath || !inPath[0]) {
00252 #if FL_DEBUG_WARNING != 0
00253 debugWarning("Trying to get the type of a file with NULL path.");
00254 #endif
00255 return -1;
00256 }
00257
00258 SceIoStat tempStats;
00259
00260 if(inPath[strlen(inPath) - 1] == '/') {
00261 inPath[strlen(inPath) - 1] = 0;
00262 sceIoGetstat(inPath, &tempStats);
00263 inPath[strlen(inPath) - 1] = '/';
00264 if(tempStats.st_mode & FIO_S_IFDIR)
00265 return 0;
00266 return -1;
00267 }
00268 if(!strcmp(&inPath[strlen(inPath) - 3], "/..") || !strcmp(inPath, ".."))
00269 return 2;
00270 if(!strcmp(&inPath[strlen(inPath) - 2], "/.") || !strcmp(inPath, "."))
00271 return 3;
00272
00273 sceIoGetstat(inPath, &tempStats);
00274
00275 if(tempStats.st_mode & FIO_S_IFDIR) {
00276 return 0;
00277 } else {
00278 if(fileExists(inPath))
00279 return 1;
00280 return -1;
00281 }
00282 }
00283
00284 bool fileExists(char* inPath) {
00285 if(!inPath || !inPath[0])
00286 return false;
00287
00288 if(!strncmp(inPath, "mem:/", 5)) {
00289 #if FL_DEBUG_WARNING != 0
00290 debugWarning("Trying to check if memory address exists \"%s\".", inPath);
00291 #endif
00292 return true;
00293 }
00294
00295 FILE* tempFile = fopen(inPath, "rb");
00296 if(tempFile) {
00297 fclose(tempFile);
00298 return true;
00299 }
00300 return false;
00301 }
00302
00303 char* fileNameFromPath(char* inPath) {
00304 if(!inPath || !inPath[0]) {
00305 #if FL_DEBUG_WARNING != 0
00306 debugWarning("Trying to get filename from a NULL string.");
00307 #endif
00308 return NULL;
00309 }
00310 char* tempStrPtr = inPath;
00311 int tempStrLen = 0;
00312 while(tempStrPtr[0]) {
00313 tempStrLen++;
00314 if((tempStrPtr[0] == '/') || (tempStrPtr[0] == '\\'))
00315 tempStrLen = 0;
00316 tempStrPtr++;
00317 }
00318
00319 if(!tempStrLen)
00320 return NULL;
00321 tempStrLen++;
00322 char* tempOut = (char*)memAlloc(tempStrLen);
00323 memCopy(tempOut, &inPath[strlen(inPath) - (tempStrLen - 1)], tempStrLen);
00324
00325 return tempOut;
00326 }
00327
00328 char* fileExtension(char* inPath) {
00329 if(!inPath || !inPath[0]) {
00330 #if FL_DEBUG_WARNING != 0
00331 debugWarning("Trying to get file extension from a NULL string.");
00332 #endif
00333 return NULL;
00334 }
00335 int tempLen = 0;
00336 char* tempStrPtr = &inPath[strlen(inPath) - 1];
00337 while(tempStrPtr[0] != '.') {
00338 tempLen++;
00339 tempStrPtr--;
00340 }
00341 if(!tempLen)
00342 return NULL;
00343 char* tempOut = (char*)memAlloc(tempLen + 1);
00344 if(!tempOut) {
00345 #if FL_DEBUG_WARNING != 0
00346 debugWarning("Cannot allocate file extension string.\nProbably out of memory.");
00347 #endif
00348 return NULL;
00349 }
00350 int i;
00351 for(i = 1; i <= tempLen; i++) {
00352 if((tempStrPtr[i] == '\r') ||(tempStrPtr[i] == '\n') || (tempStrPtr[i] == ' '))
00353 tempOut[i - 1] = 0;
00354 else
00355 tempOut[i - 1] = tempStrPtr[i];
00356 }
00357 tempOut[tempLen] = 0;
00358 return tempOut;
00359 }
00360
00361 char* filePathValidate(char* inPath) {
00362 if(!inPath || !inPath[0])
00363 return NULL;
00364 u32 i;
00365 for(i = 0; i < strlen(inPath); i++) {
00366 if((inPath[i] == '\n') || (inPath[i] == '\r'))
00367 inPath[i] = 0;
00368 }
00369 return inPath;
00370 }
00371
00372 bool fileMkdir(char* inDir) {
00373 if(!inDir || !inDir[0]) {
00374 #if FL_DEBUG_WARNING != 0
00375 debugWarning("Cannot create a folder with a NULL name.");
00376 #endif
00377 return false;
00378 }
00379 sceIoMkdir(inDir, 0777);
00380 return true;
00381 }
00382
00383 bool fileDelete(char* inPath) {
00384 if(!inPath || !inPath[0]) {
00385 #if FL_DEBUG_WARNING != 0
00386 debugWarning("Cannot delete a file with NULL path.");
00387 #endif
00388 return false;
00389 }
00390
00391 if(!strncmp(inPath, "mem:/", 5)) {
00392 int i;
00393 unsigned int tempDataPtr = 0;
00394 for(i = 5; (inPath[i] >= ASCII_0) && (inPath[i] <= ASCII_9); i++) {
00395 tempDataPtr *= 10;
00396 tempDataPtr += (inPath[i] - ASCII_0);
00397 }
00398 memFree((void*)tempDataPtr);
00399 return true;
00400 }
00401
00402 int tempfileTypeGet = fileTypeGet(inPath);
00403 if(tempfileTypeGet) {
00404 if(tempfileTypeGet == 1)
00405 sceIoRemove(inPath);
00406 return true;
00407 }
00408
00409 #if FL_DEBUG_WARNING != 0
00410 debugWarning("Recursive deletion and folder deletion are not yet supported.");
00411 #endif
00412 return false;
00413 }
00414
00415 bool fileCopy(char* inSrc, char* inDest) {
00416 if(!inSrc || !inDest || !inSrc[0] || !inDest[0]) {
00417 #if FL_DEBUG_WARNING != 0
00418 debugWarning("Trying to copy to/from a null file path.");
00419 #endif
00420 return false;
00421 }
00422
00423 SceUID tempSrc = sceIoOpen(inSrc, PSP_O_RDONLY, 0777);
00424 if(tempSrc <= 0) {
00425 #if FL_DEBUG_WARNING != 0
00426 debugWarning("Can't open source file \"%s\" for copying.", inSrc);
00427 #endif
00428 return false;
00429 }
00430
00431 SceUID tempDest = sceIoOpen(inDest, PSP_O_WRONLY | PSP_O_CREAT, 0777);
00432 if(tempDest <= 0) {
00433 sceIoClose(tempSrc);
00434 #if FL_DEBUG_WARNING != 0
00435 debugWarning("Can't open destination file \"%s\" for copying.", inDest);
00436 #endif
00437 return false;
00438 }
00439
00440 char* tempData = memQalloc(FILE_COPY_BLOCKSIZE);
00441 int tempRead = sceIoRead(tempSrc, tempData, FILE_COPY_BLOCKSIZE);
00442 int tempWritten;
00443
00444 while(tempRead > 0) {
00445 tempWritten = sceIoWrite(tempDest, tempData, tempRead);
00446 if(tempWritten != tempRead) {
00447 sceIoClose(tempDest);
00448 sceIoClose(tempSrc);
00449 sceIoRemove(inDest);
00450 #if FL_DEBUG_WARNING != 0
00451 debugWarning("Error writing while copying file \"%s\" to \"%s\".", inSrc, inDest);
00452 #endif
00453 return false;
00454 }
00455 tempRead = sceIoRead(tempSrc, tempData, FILE_COPY_BLOCKSIZE);
00456 }
00457
00458 sceIoClose(tempDest);
00459 sceIoClose(tempSrc);
00460
00461 return true;
00462 }
00463
00464 #endif