VSIArchiveReader* VSIArchiveFilesystemHandler::OpenArchiveFile(const char* archiveFilename, const char* fileInArchiveName) { VSIArchiveReader* poReader = CreateReader(archiveFilename); if (poReader == NULL) { return NULL; } if (fileInArchiveName == NULL || strlen(fileInArchiveName) == 0) { if (poReader->GotoFirstFile() == FALSE) { delete(poReader); return NULL; } /* Skip optionnal leading subdir */ CPLString osFileName = poReader->GetFileName(); const char* fileName = osFileName.c_str(); if (fileName[strlen(fileName)-1] == '/' || fileName[strlen(fileName)-1] == '\\') { if (poReader->GotoNextFile() == FALSE) { delete(poReader); return NULL; } } if (poReader->GotoNextFile()) { CPLString msg; msg.Printf("Support only 1 file in archive file %s when no explicit in-archive filename is specified", archiveFilename); const VSIArchiveContent* content = GetContentOfArchive(archiveFilename, poReader); if (content) { int i; msg += "\nYou could try one of the following :\n"; for(i=0;i<content->nEntries;i++) { msg += CPLString().Printf(" %s/%s/%s\n", GetPrefix(), archiveFilename, content->entries[i].fileName); } } CPLError(CE_Failure, CPLE_NotSupported, "%s", msg.c_str()); delete(poReader); return NULL; } } else { const VSIArchiveEntry* archiveEntry = NULL; if (FindFileInArchive(archiveFilename, fileInArchiveName, &archiveEntry) == FALSE || archiveEntry->bIsDir) { delete(poReader); return NULL; } if (!poReader->GotoFileOffset(archiveEntry->file_pos)) { delete poReader; return NULL; } } return poReader; }