CPUTFileSystem::CPUTandroidifstream::CPUTandroidifstream(const cString &fileName, std::ios_base::openmode mode) : iCPUTifstream(fileName, mode) { mpAsset = NULL; mpAssetDir = NULL; mbEOF = true; // Extract the file and dir int length = fileName.length(); int index = fileName.find_last_of("\\/"); cString file = fileName.substr(index + 1, (length - 1 - index)); cString dir = fileName.substr(0, index); // On Android, all files are in the APK and are compressed. // We do not have access to the standard file system, so // all files need streaming from memory through the android asset manager AAssetManager* assetManager = CPUTWindowAndroid::GetAppState()->activity->assetManager; mpAssetDir = AAssetManager_openDir(assetManager, dir.c_str()); if (!mpAssetDir) DEBUG_PRINT("Failed to load asset Dir"); const char* assetFileName = NULL; while ((assetFileName = AAssetDir_getNextFileName(mpAssetDir)) != NULL) { if (strcmp(file.c_str(), assetFileName) == 0) { // For some reason we need to pass in the fully pathed filename here, rather than the relative filename // that we have just been given. This feels like a bug in Android! mpAsset = AAssetManager_open(assetManager, fileName.c_str()/*assetFileName*/, AASSET_MODE_STREAMING); if (mpAsset) mbEOF = false; return; } } }
//---------------------------------------------------------------- void RemoveWhitespace(cString &szString) { // Remove leading whitespace size_t nFirstIndex = szString.find_first_not_of(_L(' ')); if(nFirstIndex != cString::npos) { szString = szString.substr(nFirstIndex); } // Remove trailing newlines size_t nLastIndex = szString.find_last_not_of(_L('\n')); while(nLastIndex != szString.length()-1) { szString.erase(nLastIndex+1,1); nLastIndex = szString.find_last_not_of(_L('\n')); }; // Tabs nLastIndex = szString.find_last_not_of(_L('\t')); while(nLastIndex != szString.length()-1) { szString.erase(nLastIndex+1,1); nLastIndex = szString.find_last_not_of(_L('\t')); }; // Spaces nLastIndex = szString.find_last_not_of(_L(' ')); while(nLastIndex != szString.length()-1) { szString.erase(nLastIndex+1,1); nLastIndex = szString.find_last_not_of(_L(' ')); }; }
// // This function parses configuration options from a text string. Removes any previous // options stored in the configuration list. // void CommandParser::ParseConfigurationOptions(cString arguments, cString delimiter) { CleanConfigurationOptions(); std::vector<cString> argumentList; size_t pos; size_t nextPos = arguments.find_first_of(delimiter, 0); // // Break out parameters from command line // while (nextPos != std::string::npos) { pos = nextPos + 1; nextPos = arguments.find_first_of(delimiter, pos); argumentList.push_back(arguments.substr(pos, nextPos - pos)); } // // Remove leading spaces from arguments. // for (std::vector<cString>::iterator it = argumentList.begin(); it != argumentList.end(); it++) { std::string::size_type pos = it->find_first_not_of(' '); if (pos != std::string::npos) { it->erase(0, pos); } } // // Remove trailing spaces from arguments // for (std::vector<cString>::iterator it = argumentList.begin(); it != argumentList.end(); it++) { std::string::size_type pos = it->find_last_not_of(' '); if (pos != std::string::npos) { it->erase(pos + 1); } } // // Split the values from the parameter name // cString arg; for (std::vector<cString>::iterator it = argumentList.begin(); it != argumentList.end(); it++) { arg = *it; pos = arg.find_first_of(_L(":"), 0); if (pos != cString::npos) { m_ArgumentMap.insert(std::make_pair(arg.substr(0, pos), arg.substr(pos + 1, std::string::npos))); } else { m_ArgumentMap.insert(std::make_pair(arg.substr(0, pos), _L(""))); } } return; }
cString CPUTAssetLibrary::GetMaterialEffectPath(const cString &name,bool nameIsFullPathAndFilename) { // Resolve name to absolute path before searching cString absolutePathAndFilename; if (name[0] == '%') { absolutePathAndFilename = mSystemDirectoryName + _L("Material/") + name.substr(1) + _L(".mtl"); // TODO: Instead of having the Material/directory hardcoded here it could be set like the normal material directory. But then there would need to be a bunch new variables like SetSystemMaterialDirectory CPUTFileSystem::ResolveAbsolutePathAndFilename(absolutePathAndFilename, &absolutePathAndFilename); } else if( !nameIsFullPathAndFilename ) { CPUTFileSystem::ResolveAbsolutePathAndFilename( mMaterialDirectoryName + name + _L(".mtl"), &absolutePathAndFilename); } else { absolutePathAndFilename = name; } return absolutePathAndFilename; }
// Read the entire contents of a file and return a pointer/size to it //----------------------------------------------------------------------------- CPUTResult CPUTFileSystem::ReadFileContents(const cString &fileName, UINT *pSizeInBytes, void **ppData, bool bAddTerminator, bool bLoadAsBinary) { #ifdef CPUT_OS_ANDROID // Extract the file and dir int length = fileName.length(); int index = fileName.find_last_of("\\/"); cString file = fileName.substr(index + 1, (length - 1 - index)); cString dir = fileName.substr(0, index); DEBUG_PRINT("ReadFileContents(%s) : dir [%s], file [%s]", fileName.c_str(), dir.c_str(), file.c_str()); // On Android, all files are in the APK and are compressed. // We do not have access to the standard file system, so // all files need streaming from memory through the android asset manager AAssetManager* assetManager = CPUTWindowAndroid::GetAppState()->activity->assetManager; AAssetDir* assetDir = AAssetManager_openDir(assetManager, dir.c_str()); if (!assetDir) DEBUG_PRINT("Failed to load asset Dir"); const char* assetFileName = NULL; while ((assetFileName = AAssetDir_getNextFileName(assetDir)) != NULL) { if (strcmp(file.c_str(), assetFileName) == 0) { // For some reason we need to pass in the fully pathed filename here, rather than the relative filename // that we have just been given. This feels like a bug in Android! AAsset* asset = AAssetManager_open(assetManager, fileName.c_str()/*assetFileName*/, AASSET_MODE_STREAMING); if (!asset) { DEBUG_PRINT("Asset failed to load for file %s", fileName.c_str()); return CPUT_ERROR; } *pSizeInBytes = AAsset_getLength(asset); // allocate buffer if (bAddTerminator) *ppData = (void*) new char[*pSizeInBytes + 1]; else *ppData = (void*) new char[*pSizeInBytes]; if (!*ppData) { DEBUG_PRINT("Out of memory loading %s", fileName.c_str()); return CPUT_ERROR; } // read it all in int numBytesRead = AAsset_read(asset, *ppData, *pSizeInBytes); if (bAddTerminator) { ((char *)(*ppData))[numBytesRead++] = '\0'; *pSizeInBytes++; } ASSERT( numBytesRead == *pSizeInBytes, _L("File read byte count mismatch.") ); AAsset_close(asset); AAssetDir_close(assetDir); return CPUT_SUCCESS; } } AAssetDir_close(assetDir); #else FILE *pFile = NULL; if (bLoadAsBinary) { #if defined (UNICODE) || defined(_UNICODE) _wfopen_s(&pFile, fileName.c_str(), _L("r")); #else pFile = fopen(fileName.c_str(), "r"); #endif } else { #if defined (UNICODE) || defined(_UNICODE) _wfopen_s(&pFile, fileName.c_str(), _L("r")); #else pFile = fopen(fileName.c_str(), "r"); #endif } if(pFile) { // get file size fseek(pFile, 0, SEEK_END); *pSizeInBytes = ftell(pFile); fseek (pFile, 0, SEEK_SET); // allocate buffer *ppData = (void*) new char[*pSizeInBytes]; ASSERT( *ppData, _L("Out of memory") ); // read it all in UINT numBytesRead = (UINT) fread(*ppData, sizeof(char), *pSizeInBytes, pFile); if (bAddTerminator) { ((char *)(*ppData))[numBytesRead++] = '\0'; *pSizeInBytes++; } ASSERT( numBytesRead == *pSizeInBytes, _L("File read byte count mismatch.") ); // close and return fclose(pFile); return CPUT_SUCCESS; } #endif // some kind of file error, translate the error code and return it return CPUT_ERROR; // return TranslateFileError(err); }