/*---------------------------------------------------------------------------* Copyright (C) 2010-2013 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #ifndef __ZIPFILE_H #define __ZIPFILE_H /* --------------------------------------------------------------------------------- This library is provided to assist in parsing standard .zip files. You can create a ZIP file on Windows by right-clicking on selection of files or a folder and selecting "Send To -> Compressed (Zipped) Folder". The library works on both Windows and Cafe, and respects differences in CPU endianness. ZIP files are in little-endian byte order but the target system may be big-endian (Cafe). The main library function is ZIPFILE_CreateDir It takes as input a blob of memory that is the compressed ZIP file, which has been placed into memory in its entirety by some mechanism (built in, loaded, etc). This library does not do the loading. The function parses the file and creates a manifest that looks like a folder tree. The manifest has pointers in it that refer to data in the original input blob. A pointer to the root folder is returned by the function as an output parameter. The library function uses allocate/free functions you provide to allocate a single contiguous blob of memory for the manifest. The manifest contains the ZIPPED_DIR and ZIPPED_FILE structures that refer to each other. The structures are in target system byte order and can be used directly. When you are finished with the manifest you can free the memory associated with it by using a single call to your free function with the pointer to the root directory as an argument. --------------------------------------------------------------------------------- */ #ifdef _MSC_VER #include #else #ifdef EPPC #include #else #error !!! Unknown compilation target #endif #endif #ifdef __cplusplus extern "C" { #endif #ifdef EPPC typedef u8 UINT8; typedef u16 UINT16; typedef u32 UINT32; #endif /* --------------------------------------------------------------------------------- */ /* This manifest structure describes a single file in the ZIP archive. */ struct _ZIPPED_FILE { struct _ZIPPED_DIR * mpParentDir; char const * mpNameOnly; UINT32 mNameOnlyLen; UINT8 const * mpCompData; UINT32 mCompBytes; UINT32 mUncompBytes; UINT32 mUncompCRC; }; typedef struct _ZIPPED_FILE ZIPPED_FILE; /* This manifest structure describes a single directory/subdirectory in the ZIP archive. */ struct _ZIPPED_DIR { struct _ZIPPED_DIR * mpParentDir; char const * mpNameOnly; UINT32 mNameOnlyLen; UINT32 mNumFiles; ZIPPED_FILE * mpFilesArray; struct _ZIPPED_DIR * mpSubDirList; struct _ZIPPED_DIR * mpNextSib; }; typedef struct _ZIPPED_DIR ZIPPED_DIR; /* This function allows calculation of the 'standard' ZIP CRC. This is useful to ensure that the CRC of a decompressed file matches the CRC stored in the ZIP for that file. */ UINT32 ZIPFILE_CalcCRC(UINT8 const *apData, UINT32 aBytes); /* these functions are used by ZIPFILE_CreateDir to allocate and free memory */ /* more than one allocation may be made by ZIPFILE_CreateDir, but only one allocation will remain after the function has completed successfully. The remaining allocation will be the full manifest of the ZIP. The first byte in the allocation corresponds to the first byte of the root folder's ZIPPED_DIR structure */ typedef void * (*ZIPFILE_pf_Alloc)(size_t aBytes); typedef void (*ZIPFILE_pf_Free)(void *addr); /* this is the main function of this library. the function will return 0 if successful, or otherwise it will return an error code (ERRCODE_ZIPFILE_xxx). simplest case use: err = ZIPFILE_Create(pBlob,blobBytes,malloc,free,&pZip); if (!err) { // browse, decompress files free(pZip); } */ int ZIPFILE_CreateDir(UINT8 const *apFileData, UINT32 aFileBytes, ZIPFILE_pf_Alloc afAlloc, ZIPFILE_pf_Free afFree, ZIPPED_DIR **appRetDir); /* this is a helper function that can locate a file that is in a directory or subdirectory */ int ZIPFILE_Find(ZIPPED_DIR *apDir, char const *apFileName, ZIPPED_FILE **apRetFilePtr); /* these are errorcodes that can occur as results of use of the functions above. a zero result from a function means "success" */ #define ZIPFILE_ERRCODE(x) ((int)(0xBADD0000 | (x))) #define ERRCODE_ZIPFILE_INVALID_FILEENTRY ZIPFILE_ERRCODE(1) #define ERRCODE_ZIPFILE_INVALID_CDS ZIPFILE_ERRCODE(2) #define ERRCODE_ZIPFILE_INVALID_CDSTAIL ZIPFILE_ERRCODE(3) #define ERRCODE_ZIPFILE_INVALID_BAD_FILESIZE ZIPFILE_ERRCODE(4) #define ERRCODE_ZIPFILE_INVALID_NO_FILE_ENTRIES ZIPFILE_ERRCODE(5) #define ERRCODE_ZIPFILE_INVALID_UNEXPECTED_EOF ZIPFILE_ERRCODE(6) #define ERRCODE_ZIPFILE_INVALID_NO_CDS ZIPFILE_ERRCODE(7) #define ERRCODE_ZIPFILE_INVALID_NO_CDS_TAIL ZIPFILE_ERRCODE(8) #define ERRCODE_ZIPFILE_INVALID_JUNK_AT_EOF ZIPFILE_ERRCODE(9) #define ERRCODE_ZIPFILE_INVALID_BAD_FILE_COUNT ZIPFILE_ERRCODE(10) #define ERRCODE_ZIPFILE_EMPTY ZIPFILE_ERRCODE(11) #define ERRCODE_ZIPFILE_OUTOFMEMORY ZIPFILE_ERRCODE(12) #define ERRCODE_ZIPFILE_ARG ZIPFILE_ERRCODE(13) #define ERRCODE_ZIPFILE_INTERNAL ZIPFILE_ERRCODE(14) #define ERRCODE_ZIPFILE_PATHNOTFOUND ZIPFILE_ERRCODE(15) #define ERRCODE_ZIPFILE_FILENOTFOUND ZIPFILE_ERRCODE(16) /* --------------------------------------------------------------------------------- */ #ifdef __cplusplus } #endif /* --------------------------------------------------------------------------------- */ #endif // __ZIPFILE_H