Example #1
0
ZIPProvider::ZIPHandle * ZIPProvider::getZIPHandle(
													const std::string & archiveFileName,
													bool createFile) {
	ZIPHandle * handle = nullptr;

	// Check if archive is already opened.
	auto it = openHandles.find(archiveFileName);
	if (it != openHandles.end()) {
		return it->second;
	}

	int flags = ZIP_CHECKCONS;

	// Check if archive exists.
	if (!FileUtils::isFile(FileName(archiveFileName))) {
		if (!createFile) {
			return nullptr;
		} else {
			flags |= ZIP_CREATE;
		}
	}

	// Open archive.
	int error;
	zip * zipHandle = zip_open(archiveFileName.c_str(), flags, &error);

	if (zipHandle == nullptr) {
		char errorString[256];
		zip_error_to_str(errorString, 256, error, errno);
		WARN(errorString+std::string(" File: ")+archiveFileName);
		return nullptr;
	}
	FileName archiveRoot;
	archiveRoot.setFSName("zip");
	archiveRoot.setDir( archiveFileName+'$' );
	handle = new ZIPHandle(archiveRoot,zipHandle);
	openHandles[archiveFileName] = handle;
	return handle;
}
Example #2
0
AbstractFSProvider::status_t ZIPProvider::ZIPHandle::dir(
															const std::string & localDirectory,
															std::list<FileName> & result,
															const uint8_t flags) {
	int num = zip_get_num_files(handle);
	if (num == -1) {
		WARN(zip_strerror(handle));
		return FAILURE;
	}
	struct zip_stat sb;
	zip_stat_init(&sb);

	// Iterate over indices.
	for (int i = 0; i < num; ++i) {
		if (zip_stat_index(handle, i, 0, &sb) == -1) {
			WARN(zip_strerror(handle));
			return FAILURE;
		}

		FileName entryFileName(sb.name);

		// Determine if the entry is a file or a directory.
		if (entryFileName.getFile().empty()) {
			if(!(flags & FileUtils::DIR_DIRECTORIES)) {
				continue;
			}

			if (!(flags & FileUtils::DIR_RECURSIVE)) {
				std::string entryDirectory = entryFileName.getDir();

				if(entryDirectory == localDirectory) {
					continue;
				}

				if(entryDirectory.back() == '/') {
					entryDirectory.resize(entryDirectory.size() - 1);
				}
				const auto slashPos = entryDirectory.find_last_of('/');
				if(slashPos != std::string::npos) {
					entryDirectory = entryDirectory.substr(0, slashPos + 1);
				} else {
					entryDirectory.clear();
				}
				// Compare the parent directory of the directory with the requested localDirectory.
				if(entryDirectory != localDirectory) {
					continue;
				}
			}
		} else {
			if(!(flags & FileUtils::DIR_FILES)) {
				continue;
			}

			// Compare the directory of the file with the requested localDirectory.
			if (!(flags & FileUtils::DIR_RECURSIVE) && entryFileName.getDir() != localDirectory) {
				continue;
			}
		}

		// Check for hidden files beginning with '.' (files only).
		if (entryFileName.getFile().front() == '.' && !(flags & FileUtils::DIR_HIDDEN_FILES)) {
			continue;
		}

		FileName f;
		f.setFSName(archiveRoot.getFSName());
		f.setDir(archiveRoot.getDir() + entryFileName.getDir());
		f.setFile(entryFileName.getFile());
		result.push_back(f);
	}
	return OK;
}