2 * This file is part of NumptyPhysics
3 * Copyright (C) 2008 Tim Edmonds
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
27 //zip file structs and uncompress_int below lifted from navit project (GPL).
37 unsigned int zipuncmp
;
38 unsigned short zipfnln
;
39 unsigned short zipxtraln
;
41 } __attribute__ ((packed
));
56 unsigned short zipcfnl
;
57 unsigned short zipcxtl
;
58 unsigned short zipccml
;
59 unsigned short zipdsk
;
60 unsigned short zipint
;
64 } __attribute__ ((packed
));
68 unsigned short zipedsk
;
69 unsigned short zipecen
;
70 unsigned short zipenum
;
71 unsigned short zipecenn
;
73 unsigned int zipeofst
;
76 } __attribute__ ((packed
));
78 int uncompress_int(unsigned char *dest
, int *destLen
,
79 const unsigned char *source
, int sourceLen
)
84 stream
.next_in
= (Bytef
*)source
;
85 stream
.avail_in
= (uInt
)sourceLen
;
86 stream
.next_out
= dest
;
87 stream
.avail_out
= (uInt
)*destLen
;
89 stream
.zalloc
= (alloc_func
)0;
90 stream
.zfree
= (free_func
)0;
92 err
= inflateInit2(&stream
, -MAX_WBITS
);
93 if (err
!= Z_OK
) return err
;
95 err
= inflate(&stream
, Z_FINISH
);
96 if (err
!= Z_STREAM_END
) {
98 if (err
== Z_NEED_DICT
|| (err
== Z_BUF_ERROR
&& stream
.avail_in
== 0))
102 *destLen
= stream
.total_out
;
104 err
= inflateEnd(&stream
);
110 ZipFile::ZipFile(const std::string
& fn
)
113 m_fd
=open(fn
.c_str(), O_RDONLY
);
116 m_dataLen
= stat
.st_size
;
118 m_data
= (unsigned char*)mmap(NULL
,m_dataLen
,PROT_READ
,MAP_PRIVATE
, m_fd
, 0);
119 if ( !m_data
) throw "mmap failed";
120 if ( *(int*)&m_data
[0] != 0x04034b50 ) throw "bad zip magic";
121 m_eoc
= (zip_eoc
*)&m_data
[m_dataLen
-sizeof(zip_eoc
)];
122 m_firstcd
= (zip_cd
*)&m_data
[m_eoc
->zipeofst
];
123 if ( m_eoc
&& m_firstcd
) {
124 m_entries
= m_eoc
->zipenum
;
134 if ( m_data
) munmap( m_data
, m_dataLen
);
135 if ( m_fd
) close( m_fd
);
139 std::string
ZipFile::entryName( int n
)
141 if ( n
< 0 || n
>= m_entries
) return std::string();
142 zip_cd
* cd
= m_firstcd
;
143 for ( int count
=0; cd
< (zip_cd
*)m_eoc
&& count
< n
; count
++ ) {
144 cd
= (zip_cd
*)(((char*)cd
) + sizeof(zip_cd
) + cd
->zipcfnl
+ cd
->zipcxtl
+ cd
->zipccml
);
146 zip_lfh
* lfh
= (zip_lfh
*)&m_data
[cd
->zipofst
];
149 return std::string(lfh
->zipname
,lfh
->zipfnln
);
151 return std::string();
154 unsigned char* ZipFile::extract( int n
, int *l
)
156 if ( n
< 0 || n
>= m_entries
) return NULL
;
157 zip_cd
* cd
= m_firstcd
;
158 for ( int count
=0; cd
< (zip_cd
*)m_eoc
&& count
< n
; count
++ ) {
159 cd
= (zip_cd
*)(((char*)cd
) + sizeof(zip_cd
) + cd
->zipcfnl
+ cd
->zipcxtl
+ cd
->zipccml
);
161 zip_lfh
* lfh
= (zip_lfh
*)&m_data
[cd
->zipofst
];
165 unsigned char* zdat
= (unsigned char*)lfh
+ sizeof(*lfh
) + lfh
->zipfnln
+ lfh
->zipxtraln
;
166 switch (lfh
->zipmthd
) {
171 m_temp
= new unsigned char[*l
];
172 if ( uncompress_int(m_temp
, l
, zdat
, lfh
->zipsize
) == Z_OK
) {