1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) 2010-2013 Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 
13 #ifndef __ZIPFILE_H
14 #define __ZIPFILE_H
15 
16 /* ---------------------------------------------------------------------------------
17 
18 This library is provided to assist in parsing standard .zip files.
19 
20 You can create a ZIP file in Windows by right-clicking a selection of files
21 or a folder and selecting "Send To -> Compressed (Zipped) Folder".
22 
23 The library works on both Windows and Cafe, and respects differences in CPU
24 endianness.  ZIP files are in little-endian byte order but the target system
25 may be big-endian (Cafe).
26 
27 The main library function is
28 
29 ZIPFILE_CreateDir
30 
31 It takes as input a blob of memory that is the compressed ZIP file, which has
32 been placed into memory in its entirety by some mechanism (built in, loaded, etc.).
33 This library does not do the loading.
34 
35 The function parses the file and creates a manifest that looks like a folder tree.
36 The manifest has pointers in it that refer to data in the original input blob.
37 A pointer to the root folder is returned by the function as an output parameter.
38 
39 The library function uses allocate/free functions you provide to allocate a single
40 contiguous blob of memory for the manifest.  The manifest contains the ZIPPED_DIR and
41 ZIPPED_FILE structures that refer to each other. The structures are in target system
42 byte order and can be used directly.
43 
44 When you are finished with the manifest you can free the memory associated with it
45 by using a single call to your free function with the pointer to the root directory
46 as an argument.
47 
48 --------------------------------------------------------------------------------- */
49 
50 #ifdef _MSC_VER
51 #include <windows.h>
52 #else
53 #ifdef EPPC
54 #include <cafe.h>
55 #else
56 #error !!! Unknown compilation target
57 #endif
58 #endif
59 
60 #ifdef __cplusplus
61 extern "C" {
62 #endif
63 
64 #ifdef EPPC
65 typedef u8 UINT8;
66 typedef u16 UINT16;
67 typedef u32 UINT32;
68 #endif
69 
70 /* --------------------------------------------------------------------------------- */
71 
72 
73 /* This manifest structure describes a single file in the ZIP archive. */
74 struct _ZIPPED_FILE
75 {
76     struct _ZIPPED_DIR *    mpParentDir;
77     char const *            mpNameOnly;
78     UINT32                  mNameOnlyLen;
79     UINT8 const *           mpCompData;
80     UINT32                  mCompBytes;
81     UINT32                  mUncompBytes;
82     UINT32                  mUncompCRC;
83 };
84 typedef struct _ZIPPED_FILE ZIPPED_FILE;
85 
86 /* This manifest structure describes a single directory/subdirectory in the ZIP archive. */
87 struct _ZIPPED_DIR
88 {
89     struct _ZIPPED_DIR *    mpParentDir;
90     char const *            mpNameOnly;
91     UINT32                  mNameOnlyLen;
92     UINT32                  mNumFiles;
93     ZIPPED_FILE *           mpFilesArray;
94     struct _ZIPPED_DIR *    mpSubDirList;
95     struct _ZIPPED_DIR *    mpNextSib;
96 };
97 typedef struct _ZIPPED_DIR ZIPPED_DIR;
98 
99 /* This function allows calculation of the 'standard' ZIP CRC.  This is useful to ensure
100    that the CRC of a decompressed file matches the CRC stored in the ZIP for that file. */
101 UINT32  ZIPFILE_CalcCRC(UINT8 const *apData, UINT32 aBytes);
102 
103 
104 /* these functions are used by ZIPFILE_CreateDir to allocate and free memory */
105 /* more than one allocation may be made by ZIPFILE_CreateDir, but only one allocation
106    will remain after the function has completed successfully.  The remaining allocation
107    will be the full manifest of the ZIP. The first byte in the allocation corresponds to
108    the first byte of the root folder's ZIPPED_DIR structure */
109 typedef void * (*ZIPFILE_pf_Alloc)(size_t aBytes);
110 typedef void   (*ZIPFILE_pf_Free)(void *addr);
111 
112 /* this is the main function of this library.
113    the function will return 0 if successful, or otherwise it will return
114    an error code (ERRCODE_ZIPFILE_xxx).
115 
116    simplest case use:
117 
118    err = ZIPFILE_Create(pBlob,blobBytes,malloc,free,&pZip);
119    if (!err)
120    {
121         // browse, decompress files
122         free(pZip);
123    }
124 */
125 int ZIPFILE_CreateDir(UINT8 const *apFileData, UINT32 aFileBytes, ZIPFILE_pf_Alloc afAlloc, ZIPFILE_pf_Free afFree, ZIPPED_DIR **appRetDir);
126 
127 
128 /* this is a helper function that can locate a file that is in a directory or subdirectory */
129 int ZIPFILE_Find(ZIPPED_DIR *apDir, char const *apFileName, ZIPPED_FILE **apRetFilePtr);
130 
131 
132 /* these are errorcodes that can occur as results of use of the functions above.
133    a zero result from a function means "success" */
134 #define ZIPFILE_ERRCODE(x)                          ((int)(0xBADD0000 | (x)))
135 #define ERRCODE_ZIPFILE_INVALID_FILEENTRY           ZIPFILE_ERRCODE(1)
136 #define ERRCODE_ZIPFILE_INVALID_CDS                 ZIPFILE_ERRCODE(2)
137 #define ERRCODE_ZIPFILE_INVALID_CDSTAIL             ZIPFILE_ERRCODE(3)
138 #define ERRCODE_ZIPFILE_INVALID_BAD_FILESIZE        ZIPFILE_ERRCODE(4)
139 #define ERRCODE_ZIPFILE_INVALID_NO_FILE_ENTRIES     ZIPFILE_ERRCODE(5)
140 #define ERRCODE_ZIPFILE_INVALID_UNEXPECTED_EOF      ZIPFILE_ERRCODE(6)
141 #define ERRCODE_ZIPFILE_INVALID_NO_CDS              ZIPFILE_ERRCODE(7)
142 #define ERRCODE_ZIPFILE_INVALID_NO_CDS_TAIL         ZIPFILE_ERRCODE(8)
143 #define ERRCODE_ZIPFILE_INVALID_JUNK_AT_EOF         ZIPFILE_ERRCODE(9)
144 #define ERRCODE_ZIPFILE_INVALID_BAD_FILE_COUNT      ZIPFILE_ERRCODE(10)
145 #define ERRCODE_ZIPFILE_EMPTY                       ZIPFILE_ERRCODE(11)
146 #define ERRCODE_ZIPFILE_OUTOFMEMORY                 ZIPFILE_ERRCODE(12)
147 #define ERRCODE_ZIPFILE_ARG                         ZIPFILE_ERRCODE(13)
148 #define ERRCODE_ZIPFILE_INTERNAL                    ZIPFILE_ERRCODE(14)
149 #define ERRCODE_ZIPFILE_PATHNOTFOUND                ZIPFILE_ERRCODE(15)
150 #define ERRCODE_ZIPFILE_FILENOTFOUND                ZIPFILE_ERRCODE(16)
151 
152 /* --------------------------------------------------------------------------------- */
153 
154 #ifdef __cplusplus
155 }
156 #endif
157 
158 /* --------------------------------------------------------------------------------- */
159 
160 #endif // __ZIPFILE_H
161 
162