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