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; }
int VSIArchiveFilesystemHandler::Stat( const char *pszFilename, VSIStatBufL *pStatBuf, int nFlags ) { int ret = -1; CPLString osFileInArchive; memset(pStatBuf, 0, sizeof(VSIStatBufL)); char* archiveFilename = SplitFilename(pszFilename, osFileInArchive, TRUE); if (archiveFilename == NULL) return -1; if (strlen(osFileInArchive) != 0) { if (ENABLE_DEBUG) CPLDebug("VSIArchive", "Looking for %s %s\n", archiveFilename, osFileInArchive.c_str()); const VSIArchiveEntry* archiveEntry = NULL; if (FindFileInArchive(archiveFilename, osFileInArchive, &archiveEntry)) { /* Patching st_size with uncompressed file size */ pStatBuf->st_size = (long)archiveEntry->uncompressed_size; pStatBuf->st_mtime = (time_t)archiveEntry->nModifiedTime; if (archiveEntry->bIsDir) pStatBuf->st_mode = S_IFDIR; else pStatBuf->st_mode = S_IFREG; ret = 0; } } else { VSIArchiveReader* poReader = CreateReader(archiveFilename); CPLFree(archiveFilename); archiveFilename = NULL; if (poReader != NULL && poReader->GotoFirstFile()) { /* 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 -1; } } if (poReader->GotoNextFile()) { /* Several files in archive --> treat as dir */ pStatBuf->st_size = 0; pStatBuf->st_mode = S_IFDIR; } else { /* Patching st_size with uncompressed file size */ pStatBuf->st_size = (long)poReader->GetFileSize(); pStatBuf->st_mtime = (time_t)poReader->GetModifiedTime(); pStatBuf->st_mode = S_IFREG; } ret = 0; } delete(poReader); } CPLFree(archiveFilename); return ret; }