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;
        }
    }
}
// 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);

}