blob: 65fbdb873e6828fb9e02554776fa97c11a9ae1f4 [file] [log] [blame]
Brian Carlstromb0460ea2011-07-29 10:08:05 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_SRC_ZIP_ARCHIVE_H_
18#define ART_SRC_ZIP_ARCHIVE_H_
19
Brian Carlstromb0460ea2011-07-29 10:08:05 -070020#include <stdint.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070021#include <zlib.h>
22
Elliott Hughes76160052012-12-12 16:31:20 -080023#include "base/unix_file/random_access_file.h"
Brian Carlstromb0460ea2011-07-29 10:08:05 -070024#include "globals.h"
25#include "logging.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070026#include "mem_map.h"
Elliott Hughes76160052012-12-12 16:31:20 -080027#include "os.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070028#include "safe_map.h"
Brian Carlstromb0460ea2011-07-29 10:08:05 -070029#include "stringpiece.h"
Elliott Hughese5448b52012-01-18 16:44:06 -080030#include "UniquePtr.h"
Brian Carlstromb0460ea2011-07-29 10:08:05 -070031
32namespace art {
33
34class ZipArchive;
35class MemMap;
36
37class ZipEntry {
Brian Carlstromb0460ea2011-07-29 10:08:05 -070038 public:
Brian Carlstrom89521892011-12-07 22:05:07 -080039 bool ExtractToFile(File& file);
40 bool ExtractToMemory(MemMap& mem_map);
Brian Carlstromb0460ea2011-07-29 10:08:05 -070041
Brian Carlstrom89521892011-12-07 22:05:07 -080042 uint32_t GetUncompressedLength();
Brian Carlstromb0460ea2011-07-29 10:08:05 -070043 uint32_t GetCrc32();
44
45 private:
Brian Carlstroma6cc8932012-01-04 14:44:07 -080046 ZipEntry(const ZipArchive* zip_archive, const byte* ptr) : zip_archive_(zip_archive), ptr_(ptr) {}
Brian Carlstromb0460ea2011-07-29 10:08:05 -070047
48 // Zip compression methods
49 enum {
50 kCompressStored = 0, // no compression
51 kCompressDeflated = 8, // standard deflate
52 };
53
54 // kCompressStored, kCompressDeflated, ...
55 uint16_t GetCompressionMethod();
56
57 uint32_t GetCompressedLength();
58
Brian Carlstromb0460ea2011-07-29 10:08:05 -070059 // returns -1 on error
60 off_t GetDataOffset();
61
Brian Carlstroma6cc8932012-01-04 14:44:07 -080062 const ZipArchive* zip_archive_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -070063
64 // pointer to zip entry within central directory
Brian Carlstromdb4d5402011-08-09 12:18:28 -070065 const byte* ptr_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -070066
67 friend class ZipArchive;
Elliott Hughesa21039c2012-06-21 12:09:25 -070068 DISALLOW_COPY_AND_ASSIGN(ZipEntry);
Brian Carlstromb0460ea2011-07-29 10:08:05 -070069};
70
Brian Carlstromb0460ea2011-07-29 10:08:05 -070071class ZipArchive {
72 public:
Brian Carlstromb0460ea2011-07-29 10:08:05 -070073 // Zip file constants.
74 static const uint32_t kEOCDSignature = 0x06054b50;
75 static const int32_t kEOCDLen = 22;
76 static const int32_t kEOCDNumEntries = 8; // offset to #of entries in file
77 static const int32_t kEOCDSize = 12; // size of the central directory
78 static const int32_t kEOCDFileOffset = 16; // offset to central directory
79
80 static const int32_t kMaxCommentLen = 65535; // longest possible in uint16_t
81 static const int32_t kMaxEOCDSearch = (kMaxCommentLen + kEOCDLen);
82
83 static const uint32_t kLFHSignature = 0x04034b50;
84 static const int32_t kLFHLen = 30; // excluding variable-len fields
85 static const int32_t kLFHNameLen = 26; // offset to filename length
86 static const int32_t kLFHExtraLen = 28; // offset to extra length
87
88 static const uint32_t kCDESignature = 0x02014b50;
89 static const int32_t kCDELen = 46; // excluding variable-len fields
90 static const int32_t kCDEMethod = 10; // offset to compression method
91 static const int32_t kCDEModWhen = 12; // offset to modification timestamp
92 static const int32_t kCDECRC = 16; // offset to entry CRC
93 static const int32_t kCDECompLen = 20; // offset to compressed length
94 static const int32_t kCDEUncompLen = 24; // offset to uncompressed length
95 static const int32_t kCDENameLen = 28; // offset to filename length
96 static const int32_t kCDEExtraLen = 30; // offset to extra length
97 static const int32_t kCDECommentLen = 32; // offset to comment length
98 static const int32_t kCDELocalOffset = 42; // offset to local hdr
99
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700100 // return new ZipArchive instance on success, NULL on error.
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700101 static ZipArchive* Open(const std::string& filename);
Brian Carlstroma6cc8932012-01-04 14:44:07 -0800102 static ZipArchive* OpenFromFd(int fd);
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700103
Brian Carlstroma6cc8932012-01-04 14:44:07 -0800104 ZipEntry* Find(const char* name) const;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700105
106 ~ZipArchive() {
107 Close();
108 }
109
110 private:
Elliott Hughesa51a3dd2011-10-17 15:19:26 -0700111 explicit ZipArchive(int fd) : fd_(fd), num_entries_(0), dir_offset_(0) {}
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700112
113 bool MapCentralDirectory();
114 bool Parse();
115 void Close();
116
117 int fd_;
118 uint16_t num_entries_;
119 off_t dir_offset_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700120 UniquePtr<MemMap> dir_map_;
Elliott Hughesa0e18062012-04-13 15:59:59 -0700121 typedef SafeMap<StringPiece, const byte*> DirEntries;
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700122 DirEntries dir_entries_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700123
124 friend class ZipEntry;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700125
126 DISALLOW_COPY_AND_ASSIGN(ZipArchive);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700127};
128
129} // namespace art
130
131#endif // ART_SRC_ZIP_ARCHIVE_H_