int ZipArchive::deleteEntry(const ZipEntry& entry) const { if (!isOpen()) { return LIBZIPPP_ERROR_NOT_OPEN; } if (entry.zipFile!=this) { return LIBZIPPP_ERROR_INVALID_ENTRY; } if (mode==READ_ONLY) { return LIBZIPPP_ERROR_NOT_ALLOWED; } //deletion not allowed if (entry.isFile()) { int result = zip_delete(zipHandle, entry.getIndex()); if (result==0) { return 1; } return LIBZIPPP_ERROR_UNKNOWN; //unable to delete the entry } else { int counter = 0; vector<ZipEntry> allEntries = getEntries(); vector<ZipEntry>::const_iterator eit; for(eit=allEntries.begin() ; eit!=allEntries.end() ; ++eit) { ZipEntry ze = *eit; int startPosition = ze.getName().find(entry.getName()); if (startPosition==0) { int result = zip_delete(zipHandle, ze.getIndex()); if (result==0) { ++counter; } else { return LIBZIPPP_ERROR_UNKNOWN; } //unable to remove the current entry } } return counter; } }
bool ZipArchive::setEntryComment(const ZipEntry& entry, const string& comment) const { if (!isOpen()) { return false; } if (entry.zipFile!=this) { return false; } bool result = zip_file_set_comment(zipHandle, entry.getIndex(), comment.c_str(), comment.size(), ZIP_FL_ENC_GUESS); return result==0; }
string ZipArchive::getEntryComment(const ZipEntry& entry, State state) const { if (!isOpen()) { return string(); } if (entry.zipFile!=this) { return string(); } int flag = ZIP_FL_ENC_GUESS; if (state==ORIGINAL) { flag = flag | ZIP_FL_UNCHANGED; } unsigned int clen; const char* com = zip_file_get_comment(zipHandle, entry.getIndex(), &clen, flag); string comment = com==NULL ? string() : string(com, clen); return comment; }
int ZipArchive::readEntry(const ZipEntry& zipEntry, std::ofstream& ofOutput, State state, libzippp_uint64 chunksize) const { if (!ofOutput.is_open()) { return LIBZIPPP_ERROR_INVALID_PARAMETER; } if (!isOpen()) { return LIBZIPPP_ERROR_NOT_OPEN; } if (zipEntry.zipFile!=this) { return LIBZIPPP_ERROR_INVALID_ENTRY; } int iRes = LIBZIPPP_OK; int flag = state==ORIGINAL ? ZIP_FL_UNCHANGED : 0; struct zip_file* zipFile = zip_fopen_index(zipHandle, zipEntry.getIndex(), flag); if (zipFile) { libzippp_uint64 maxSize = zipEntry.getSize(); if (!chunksize) { chunksize = DEFAULT_CHUNK_SIZE; } // use the default chunk size (512K) if not specified by the user if (maxSize<chunksize) { char* data = new char[maxSize]; if (data!=NULL) { libzippp_int64 result = zip_fread(zipFile, data, maxSize); if (result>0) { if (result != static_cast<libzippp_int64>(maxSize)) { iRes = LIBZIPPP_ERROR_OWRITE_INDEX_FAILURE; } else { ofOutput.write(data, maxSize); if (!ofOutput) { iRes = LIBZIPPP_ERROR_OWRITE_FAILURE; } } } else { iRes = LIBZIPPP_ERROR_FREAD_FAILURE; } delete[] data; } else { iRes = LIBZIPPP_ERROR_MEMORY_ALLOCATION; } } else { libzippp_uint64 uWrittenBytes = 0; libzippp_int64 result = 0; char* data = new char[chunksize]; if (data!=NULL) { int nbChunks = maxSize/chunksize; for (int uiChunk=0 ; uiChunk<nbChunks ; ++uiChunk) { result = zip_fread(zipFile, data, chunksize); if (result>0) { if (result!=static_cast<libzippp_int64>(chunksize)) { iRes = LIBZIPPP_ERROR_OWRITE_INDEX_FAILURE; break; } else { ofOutput.write(data, chunksize); if (!ofOutput) { iRes = LIBZIPPP_ERROR_OWRITE_FAILURE; break; } uWrittenBytes += result; } } else { iRes = LIBZIPPP_ERROR_FREAD_FAILURE; break; } } delete[] data; } else { iRes = LIBZIPPP_ERROR_MEMORY_ALLOCATION; } int leftOver = maxSize%chunksize; if (iRes==0 && leftOver>0) { char* data = new char[leftOver]; if (data!=NULL) { result = zip_fread(zipFile, data, leftOver); if (result>0) { if (result!=static_cast<libzippp_int64>(leftOver)) { iRes = LIBZIPPP_ERROR_OWRITE_INDEX_FAILURE; } else { ofOutput.write(data, leftOver); if (!ofOutput) { iRes = LIBZIPPP_ERROR_OWRITE_FAILURE; } else { uWrittenBytes += result; if (uWrittenBytes!=maxSize) { iRes = LIBZIPPP_ERROR_UNKNOWN; // shouldn't occur but let's be careful } } } } else { iRes = LIBZIPPP_ERROR_FREAD_FAILURE; } } else { iRes = LIBZIPPP_ERROR_MEMORY_ALLOCATION; } delete[] data; } } zip_fclose(zipFile); } else { iRes = LIBZIPPP_ERROR_FOPEN_FAILURE; } return iRes; }
int ZipArchive::renameEntry(const ZipEntry& entry, const string& newName) const { if (!isOpen()) { return LIBZIPPP_ERROR_NOT_OPEN; } if (entry.zipFile!=this) { return LIBZIPPP_ERROR_INVALID_ENTRY; } if (mode==READ_ONLY) { return LIBZIPPP_ERROR_NOT_ALLOWED; } //renaming not allowed if (newName.length()==0) { return LIBZIPPP_ERROR_INVALID_PARAMETER; } if (newName==entry.getName()) { return LIBZIPPP_ERROR_INVALID_PARAMETER; } if (entry.isFile()) { if (ENTRY_IS_DIRECTORY(newName)) { return LIBZIPPP_ERROR_INVALID_PARAMETER; } //invalid new name int lastSlash = newName.rfind(ENTRY_PATH_SEPARATOR); if (lastSlash!=1) { bool dadded = addEntry(newName.substr(0, lastSlash+1)); if (!dadded) { return LIBZIPPP_ERROR_UNKNOWN; } //the hierarchy hasn't been created } int result = zip_file_rename(zipHandle, entry.getIndex(), newName.c_str(), ZIP_FL_ENC_GUESS); if (result==0) { return 1; } return LIBZIPPP_ERROR_UNKNOWN; //renaming was not possible (entry already exists ?) } else { if (!ENTRY_IS_DIRECTORY(newName)) { return LIBZIPPP_ERROR_INVALID_PARAMETER; } //invalid new name int parentSlash = newName.rfind(ENTRY_PATH_SEPARATOR, newName.length()-2); if (parentSlash!=-1) { //updates the dir hierarchy string parent = newName.substr(0, parentSlash+1); bool dadded = addEntry(parent); if (!dadded) { return LIBZIPPP_ERROR_UNKNOWN; } } int counter = 0; string originalName = entry.getName(); vector<ZipEntry> allEntries = getEntries(); vector<ZipEntry>::const_iterator eit; for(eit=allEntries.begin() ; eit!=allEntries.end() ; ++eit) { ZipEntry ze = *eit; string currentName = ze.getName(); int startPosition = currentName.find(originalName); if (startPosition==0) { if (currentName == originalName) { int result = zip_file_rename(zipHandle, entry.getIndex(), newName.c_str(), ZIP_FL_ENC_GUESS); if (result==0) { ++counter; } else { return LIBZIPPP_ERROR_UNKNOWN; } //unable to rename the folder } else { string targetName = currentName.replace(0, originalName.length(), newName); int result = zip_file_rename(zipHandle, ze.getIndex(), targetName.c_str(), ZIP_FL_ENC_GUESS); if (result==0) { ++counter; } else { return LIBZIPPP_ERROR_UNKNOWN; } //unable to rename a sub-entry } } else { //file not affected by the renaming } } /* * Special case for moving a directory a/x to a/x/y to avoid to lose * the a/x path in the archive. */ bool newNameIsInsideCurrent = (newName.find(entry.getName())==0); if (newNameIsInsideCurrent) { bool dadded = addEntry(newName); if (!dadded) { return LIBZIPPP_ERROR_UNKNOWN; } } return counter; } }