Skip to content

Commit

Permalink
Added initial portions of dsZipArchive.
Browse files Browse the repository at this point in the history
dsArchive implementation that can read from .zip archives. Directory
records are read and their metadata stored, allowing for operations such as
checking the status of a path or iterating over a directory. The paths may
then be opened independently, even across threads. zip64 extensions are
supported, and files may either use DEFLATE or be uncompressed. Encryption
is not supported.

Streams to read data are not yet implemented.
  • Loading branch information
akb825 committed Jan 13, 2025
1 parent 300d8ff commit 58e4ff2
Show file tree
Hide file tree
Showing 15 changed files with 1,591 additions and 1 deletion.
9 changes: 9 additions & 0 deletions modules/Core/Core/include/DeepSea/Core/Streams/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,15 @@ struct dsFileArchive
dsCloseFileArchiveFileFunction closeFileFunc;
};

/**
* @brief Struct describing a zip archive.
*
* This is an implementation of dsFileArchive for reading .zip files.
*
* @see ZipArchive.h
*/
typedef struct dsZipArchive dsZipArchive;

#ifdef __cplusplus
}
#endif
137 changes: 137 additions & 0 deletions modules/Core/Core/include/DeepSea/Core/Streams/ZipArchive.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright 2025 Aaron Barany
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <DeepSea/Core/Config.h>
#include <DeepSea/Core/Export.h>
#include <DeepSea/Core/Streams/Types.h>

#ifdef __cplusplus
extern "C"
{
#endif

/**
* @file
* @brief Functions for creating and manipulating zip archives.
*
* All paths within a zip archive will be rleative to the root of the archive. A leading ./ may be
* used for any path, including using "." by itself to refer to the root directory of the archive.
*
* @see dsZipArchive
*/

/**
* @brief Opens a zip archive from a file path.
* @remark errno will be set on failure.
* @param allocator The allocator for memory associated with the archive. This must support freeing
* memory.
* @param path The path to the zip archive.
* @param decompressBufferSize The size of the buffer when reading compressed data. Set to 0 to use
* the default.
* @return The zip archive or NULL if it couldn't be opened.
*/
DS_CORE_EXPORT dsZipArchive* dsZipArchive_open(
dsAllocator* allocator, const char* path, size_t decompressBufferSize);

/**
* @brief Opens a zip archive from a resource path.
* @remark errno will be set on failure.
* @param allocator The allocator for memory associated with the archive. This must support freeing
* memory.
* @param type The resource type.
* @param path The path to the zip archive.
* @param decompressBufferSize The size of the buffer when reading compressed data. Set to 0 to use
* the default.
* @return The zip archive or NULL if it couldn't be opened.
*/
DS_CORE_EXPORT dsZipArchive* dsZipArchive_openResource(
dsAllocator* allocator, dsFileResourceType type, const char* path, size_t decompressBufferSize);

/**
* @brief Gets the status on a path within the archive.
* @remark errno will be set on failure.
* @param archive The archive to get the path status from.
* @param path The path within the archive.
* @return The path status.
*/
DS_CORE_EXPORT dsPathStatus dsZipArchive_pathStatus(
const dsZipArchive* archive, const char* path);

/**
* @brief Opens a directory within an archive.
* @remark errno will be set on failure.
* @param archive The archive to open the directory from.
* @param path The path to the directory within the archive.
* @return The directory iterator or NULL if the directory cannot be iterated.
*/
DS_CORE_EXPORT dsDirectoryIterator dsZipArchive_openDirectory(
const dsZipArchive* archive, const char* path);

/**
* @brief Gets the next entry within a directory in an archive.
* @remark errno will be set on failure.
* @param[out] result The storage for the result.
* @param resultSize The maximum size of the result.
* @param archive The archive the directory was opened with.
* @param iterator The iterator for the directory.
* @return The result of getting the next entry. dsPathStatus_Missing will be returned once the last
* entry has been reached.
*/
DS_CORE_EXPORT dsPathStatus dsZipArchive_nextDirectoryEntry(
char* result, size_t resultSize, const dsZipArchive* archive, dsDirectoryIterator iterator);

/**
* @brief Closes a directory within an archive.
* @remark errno will be set on failure.
* @param archive The archive the directory was opened with.
* @param iterator The iterator for the directory to close.
* @return False if the directory couldn't be closed.
*/
DS_CORE_EXPORT bool dsZipArchive_closeDirectory(
const dsZipArchive* archive, dsDirectoryIterator iterator);

/**
* @brief Opens a file within an archive.
* @remark errno will be set on failure.
* @param archive The archive to open the file with.
* @param path The path to the file to open.
* @return The opened stream or NULL if the file couldn't be opened.
*/
DS_CORE_EXPORT dsStream* dsZipArchive_openFile(const dsZipArchive* archive, const char* path);

/**
* @brief Closes a file within an archive.
* @remark errno will be set on failure.
* @param archive The archive the file was opened with.
* @param stream The stream for the file that was oepend.
* @return False if the file couldn't be closed.
*/
DS_CORE_EXPORT bool dsZipArchive_closeFile(const dsZipArchive* archive, dsStream* stream);

/**
* @brief Closes a zip archive.
*
* All files and directories must be closed before calling this function.
*
* @param archive The archive to close.
*/
DS_CORE_EXPORT void dsZipArchive_close(dsZipArchive* archive);

#ifdef __cplusplus
}
#endif
2 changes: 1 addition & 1 deletion modules/Core/Core/src/Streams/FileArchive.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#include <DeepSea/Core/Error.h>

inline dsPathStatus dsFileArchive_pathStatus(const dsFileArchive* archive, const char* path)
dsPathStatus dsFileArchive_pathStatus(const dsFileArchive* archive, const char* path)
{
if (!archive || !archive->getPathStatusFunc || !path || *path == 0)
{
Expand Down
Loading

0 comments on commit 58e4ff2

Please sign in to comment.