#include "stdafx.h" #include "FileFilter.h" #include "McRegionLevelStorageSource.h" #include "File.h" #ifdef __PS3__ #include #endif const wchar_t File::pathSeparator = L'\\'; const wstring File::pathRoot = L""; // Path root after pathSeparator has been removed //Creates a new File instance from a parent abstract pathname and a child pathname string. File::File( const File &parent, const wstring& child ) { m_abstractPathName = parent.getPath() + pathSeparator + child; } //Creates a new File instance by converting the given pathname string into an abstract pathname. File::File( const wstring& pathname ) //: parent( NULL ) { // #ifndef _CONTENT_PACKAGE // char buf[256]; // wcstombs(buf, pathname.c_str(), 256); // printf("File::File - %s\n",buf); // #endif if( pathname.empty() ) m_abstractPathName = wstring( L"" ); else m_abstractPathName = pathname; /* vector path = stringSplit( pathname, pathSeparator ); if( path.back().compare( pathRoot ) != 0 ) m_abstractPathName = path.back(); else m_abstractPathName = L""; path.pop_back(); if( path.size() > 0 ) { // If the last member of the vector is the root then just stop if( path.back().compare( pathRoot ) != 0 ) this->parent = new File( &path ); else this->parent = NULL; } */ } File::File( const wstring& parent, const wstring& child ) //: m_abstractPathName( child ) { m_abstractPathName = pathRoot + pathSeparator + parent + pathSeparator + child; //this->parent = new File( parent ); } //Creates a new File instance by converting the given path vector into an abstract pathname. /* File::File( vector *path ) : parent( NULL ) { m_abstractPathName = path->back(); path->pop_back(); if( path->size() > 0 ) { // If the last member of the vector is the root then just stop if( path->back().compare( pathRoot ) != 0 ) this->parent = new File( path ); else this->parent = NULL; } } */ //Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, //then the directory must be empty in order to be deleted. //Returns: //true if and only if the file or directory is successfully deleted; false otherwise bool File::_delete() { #ifdef _UNICODE BOOL result = DeleteFile( getPath().c_str() ); #else BOOL result = DeleteFile( wstringtofilename(getPath()) ); #endif if( result == 0 ) { DWORD error = GetLastError(); #ifndef _CONTENT_PACKAGE printf( "File::_delete - Error code %d (%#0.8X)\n", error, error ); #endif return false; } else return true; } //Creates the directory named by this abstract pathname. //Returns: //true if and only if the directory was created; false otherwise bool File::mkdir() const { #ifdef _UNICODE return CreateDirectory( getPath().c_str(), NULL) != 0; #else return CreateDirectory( wstringtofilename(getPath()), NULL) != 0; #endif } //Creates the directory named by this abstract pathname, including any //necessary but nonexistent parent directories. Note that if this //operation fails it may have succeeded in creating some of the necessary //parent directories. // //@return true if and only if the directory was created, // along with all necessary parent directories; false // otherwise // //@throws SecurityException // If a security manager exists and its {@link // java.lang.SecurityManager#checkRead(java.lang.String)} // method does not permit verification of the existence of the // named directory and all necessary parent directories; or if // the {@link // java.lang.SecurityManager#checkWrite(java.lang.String)} // method does not permit the named directory and all necessary // parent directories to be created // bool File::mkdirs() const { vector path = stringSplit( m_abstractPathName, pathSeparator ); wstring pathToHere = L""; AUTO_VAR(itEnd, path.end()); for( AUTO_VAR(it, path.begin()); it != itEnd; it++ ) { // If this member of the vector is the root then just skip to the next if( pathRoot.compare( *it ) == 0 ) { pathToHere = *it; continue; } pathToHere = pathToHere + pathSeparator + *it; // if not exists #ifdef _UNICODE if( GetFileAttributes( pathToHere.c_str() ) == -1 ) { DWORD result = CreateDirectory( pathToHere.c_str(), NULL); if( result == 0 ) { // Failed to create return false; } } #else if( GetFileAttributes( wstringtofilename(pathToHere) ) == -1 ) { DWORD result = CreateDirectory( wstringtofilename(pathToHere), NULL); if( result == 0 ) { // Failed to create return false; } } #endif } // We should now exist assert( exists() ); return true; } /* File *File::getParent() const { return (File *) parent; } */ //Tests whether the file or directory denoted by this abstract pathname exists. //Returns: //true if and only if the file or directory denoted by this abstract pathname exists; false otherwise bool File::exists() const { // TODO 4J Stu - Possible we could get an error result from something other than the file not existing? #ifdef _UNICODE return GetFileAttributes( getPath().c_str() ) != -1; #else return GetFileAttributes( wstringtofilename(getPath()) ) != -1; #endif } //Tests whether the file denoted by this abstract pathname is a normal file. A file is normal if it is not a directory and, //in addition, satisfies other system-dependent criteria. Any non-directory file created by a Java application is guaranteed to be a normal file. //Returns: //true if and only if the file denoted by this abstract pathname exists and is a normal file; false otherwise bool File::isFile() const { return exists() && !isDirectory(); } //Renames the file denoted by this abstract pathname. //Whether or not this method can move a file from one filesystem to another is platform-dependent. //The return value should always be checked to make sure that the rename operation was successful. // //Parameters: //dest - The new abstract pathname for the named file //Returns: //true if and only if the renaming succeeded; false otherwise bool File::renameTo(File dest) { // 4J Stu - The wstringtofilename function returns a pointer to the same location in memory every time it is // called, therefore we were getting sourcePath and destPath having the same value. The solution here is to // make a copy of the sourcePath by storing it in a std::string string sourcePath = wstringtofilename(getPath()); const char *destPath = wstringtofilename(dest.getPath()); BOOL result = MoveFile(sourcePath.c_str(), destPath); if( result == 0 ) { DWORD error = GetLastError(); #ifndef _CONTENT_PACKAGE printf( "File::renameTo - Error code %d (%#0.8X)\n", error, error ); #endif return false; } else return true; } //Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname. //If this abstract pathname does not denote a directory, then this method returns null. Otherwise an array of File objects is returned, //one for each file or directory in the directory. Pathnames denoting the directory itself and the directory's parent directory //are not included in the result. Each resulting abstract pathname is constructed from this abstract pathname using //the File(File, String) constructor. Therefore if this pathname is absolute then each resulting pathname is absolute; //if this pathname is relative then each resulting pathname will be relative to the same directory. // //There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, //in particular, guaranteed to appear in alphabetical order. // //Returns: //An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. //The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, //or if an I/O error occurs. vector *File::listFiles() const { vector *vOutput = new vector(); // TODO 4J Stu - Also need to check for I/O errors? if( !isDirectory() ) return vOutput; #if defined(__PS3__) const char *lpFileName=wstringtofilename(getPath()); char filePath[256]; std::string mountedPath = StorageManager.GetMountedPath(lpFileName); if(mountedPath.length() > 0) { strcpy(filePath, mountedPath.c_str()); } else if(lpFileName[0] == '/') // already fully qualified path strcpy(filePath, lpFileName ); else sprintf(filePath,"%s/%s",getUsrDirPath(), lpFileName ); int fd; CellFsErrno err = cellFsOpendir(filePath , &fd); CellFsDirectoryEntry de; uint32_t count = 0; err = cellFsGetDirectoryEntries(fd, &de, sizeof(CellFsDirectoryEntry), &count); if(count != 0) { do { if(de.attribute.st_mode & CELL_FS_S_IFREG) vOutput->push_back( new File( *this, filenametowstring( de.entry_name.d_name ) ) ); err = cellFsGetDirectoryEntries(fd, &de, sizeof(CellFsDirectoryEntry), &count); } while( count ); } err = cellFsClose(fd); #else WIN32_FIND_DATA wfd; #ifdef _UNICODE WCHAR path[MAX_PATH]; swprintf( path, L"%ls\\*", getPath().c_str() ); HANDLE hFind = FindFirstFile( path, &wfd); if(hFind != INVALID_HANDLE_VALUE) { int count = 0; do { //if( !(wfd.dwFileAttributes & dwAttr) ) vOutput->push_back( new File( *this, wfd.cFileName ) ); } while( FindNextFile( hFind, &wfd) ); FindClose( hFind); } #else char path[MAX_PATH]; sprintf( path, "%s\\*", wstringtofilename( getPath() ) ); HANDLE hFind = FindFirstFile( path, &wfd); if(hFind != INVALID_HANDLE_VALUE) { //int count = 0; do { //if( !(wfd.dwFileAttributes & dwAttr) ) vOutput->push_back( new File( *this, filenametowstring( wfd.cFileName ) ) ); } while( FindNextFile( hFind, &wfd) ); FindClose( hFind); } #endif #endif return vOutput; } //Returns an array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname that //satisfy the specified filter. The behavior of this method is the same as that of the listFiles() method, except that the pathnames //in the returned array must satisfy the filter. If the given filter is null then all pathnames are accepted. Otherwise, a pathname //satisfies the filter if and only if the value true results when the FileFilter.accept(java.io.File) method of the filter is invoked //on the pathname. //Parameters: //filter - A file filter //Returns: //An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. //The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs. vector *File::listFiles(FileFilter *filter) const { // TODO 4J Stu - Also need to check for I/O errors? if( !isDirectory() ) return NULL; vector *vOutput = new vector(); #ifdef __PS3__ const char *lpFileName=wstringtofilename(getPath()); char filePath[256]; std::string mountedPath = StorageManager.GetMountedPath(lpFileName); if(mountedPath.length() > 0) { strcpy(filePath, mountedPath.c_str()); } else if(lpFileName[0] == '/') // already fully qualified path strcpy(filePath, lpFileName ); else sprintf(filePath,"%s/%s",getUsrDirPath(), lpFileName ); int fd; CellFsErrno err = cellFsOpendir(filePath, &fd); CellFsDirectoryEntry de; uint32_t count = 0; err = cellFsGetDirectoryEntries(fd, &de, sizeof(CellFsDirectoryEntry), &count); if(count != 0) { do { File thisFile = File( *this, filenametowstring( de.entry_name.d_name ) ); if( filter->accept( &thisFile ) ) { File storageFile = thisFile; if(de.attribute.st_mode & CELL_FS_S_IFREG) vOutput->push_back( &storageFile ); } err = cellFsGetDirectoryEntries(fd, &de, sizeof(CellFsDirectoryEntry), &count); } while( count ); } err = cellFsClose(fd); #else #ifdef _UNICODE WCHAR path[MAX_PATH]; WIN32_FIND_DATA wfd; DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY; swprintf( path, L"%ls\\*", getPath().c_str() ); HANDLE hFind = FindFirstFile( path, &wfd); if(hFind != INVALID_HANDLE_VALUE) { int count = 0; do { File thisFile = File( *this, wfd.cFileName ); if( filter->accept( &thisFile ) ) { File storageFile = thisFile; vOutput->push_back( &storageFile ); } } while( FindNextFile( hFind, &wfd) ); FindClose( hFind); } #else char path[MAX_PATH]; WIN32_FIND_DATA wfd; //DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY; sprintf( path, "%s\\*", wstringtofilename( getPath() ) ); HANDLE hFind = FindFirstFile( path, &wfd); if(hFind != INVALID_HANDLE_VALUE) { //int count = 0; do { File thisFile = File( *this, filenametowstring( wfd.cFileName ) ); if( filter->accept( &thisFile ) ) { File storageFile = thisFile; vOutput->push_back( &storageFile ); } } while( FindNextFile( hFind, &wfd) ); FindClose( hFind); } #endif #endif return vOutput; } //Tests whether the file denoted by this abstract pathname is a directory. //Returns: //true if and only if the file denoted by this abstract pathname exists and is a directory; false otherwise bool File::isDirectory() const { #ifdef _UNICODE return exists() && ( GetFileAttributes( getPath().c_str() ) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; #else return exists() && ( GetFileAttributes( wstringtofilename(getPath()) ) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; #endif } //Returns the length of the file denoted by this abstract pathname. The return value is unspecified if this pathname denotes a directory. //Returns: //The length, in bytes, of the file denoted by this abstract pathname, or 0L if the file does not exist __int64 File::length() { #if defined(__PS3__) //extern const char* getPS3HomePath(); CellFsErrno err=0; const char *lpFileName=wstringtofilename(getPath()); char filePath[256]; std::string mountedPath = StorageManager.GetMountedPath(lpFileName); if(mountedPath.length() > 0) { strcpy(filePath, mountedPath.c_str()); } else if(lpFileName[0] == '/') // already fully qualified path strcpy(filePath, lpFileName ); else sprintf(filePath,"%s/%s",getUsrDirPath(), lpFileName ); #ifndef _CONTENT_PACKAGE //printf("+++File::length - %s\n",filePath); #endif // check if the file exists first CellFsStat statData; err=cellFsStat(filePath, &statData); if( err != CELL_FS_SUCCEEDED) { //printf("+++File::length FAILED with %d\n",err); return 0; } if(statData.st_mode == CELL_FS_S_IFDIR) { //printf("+++File::length FAILED with %d\n",err); return 0; } //printf("+++File::length - %ll\n",statData.st_size); return statData.st_size; #else WIN32_FILE_ATTRIBUTE_DATA fileInfoBuffer; #ifdef _UNICODE BOOL result = GetFileAttributesEx( getPath().c_str(), // file or directory name GetFileExInfoStandard, // attribute &fileInfoBuffer // attribute information ); #else BOOL result = GetFileAttributesEx( wstringtofilename(getPath()), // file or directory name GetFileExInfoStandard, // attribute &fileInfoBuffer // attribute information ); #endif if( result != 0 && !( (fileInfoBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) ) { // Success LARGE_INTEGER liFileSize; liFileSize.HighPart = fileInfoBuffer.nFileSizeHigh; liFileSize.LowPart = fileInfoBuffer.nFileSizeLow; return liFileSize.QuadPart; } else { //Fail or a Directory return 0l; } #endif } //Returns the time that the file denoted by this abstract pathname was last modified. //Returns: //A long value representing the time the file was last modified, measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970), //or 0L if the file does not exist or if an I/O error occurs __int64 File::lastModified() { WIN32_FILE_ATTRIBUTE_DATA fileInfoBuffer; #ifdef _UNICODE BOOL result = GetFileAttributesEx( getPath().c_str(), // file or directory name GetFileExInfoStandard, // attribute &fileInfoBuffer // attribute information ); #else BOOL result = GetFileAttributesEx( wstringtofilename(getPath()), // file or directory name GetFileExInfoStandard, // attribute &fileInfoBuffer // attribute information ); #endif if( result != 0 && !( (fileInfoBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) ) { // Success LARGE_INTEGER liLastModified; liLastModified.HighPart = fileInfoBuffer.ftLastWriteTime.dwHighDateTime; liLastModified.LowPart = fileInfoBuffer.ftLastWriteTime.dwLowDateTime; return liLastModified.QuadPart; } else { //Fail or a Directory return 0l; } } const wstring File::getPath() const { /* wstring path; if ( parent != NULL) path = parent->getPath(); else path = wstring(pathRoot); path.push_back( pathSeparator ); path.append(m_abstractPathName); */ return m_abstractPathName; } wstring File::getName() const { unsigned int sep = (unsigned int )(m_abstractPathName.find_last_of( this->pathSeparator )); return m_abstractPathName.substr( sep + 1, m_abstractPathName.length() ); } bool File::eq_test(const File &x, const File &y) { return x.getPath().compare( y.getPath() ) == 0; } // 4J TODO JEV, a better hash function may be nessesary. int File::hash_fnct(const File &k) { int hashCode = 0; //if (k->parent != NULL) // hashCode = hash_fnct(k->getParent()); wchar_t *ref = (wchar_t *) k.m_abstractPathName.c_str(); for (unsigned int i = 0; i < k.m_abstractPathName.length(); i++) { hashCode += ((hashCode * 33) + ref[i]) % 149; } return (int) hashCode; }