zip_archive.h revision db4d54081f09abcbe97ffdf615874f2809a9e777
1b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom/*
2b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * Copyright (C) 2008 The Android Open Source Project
3b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom *
4b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * you may not use this file except in compliance with the License.
6b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * You may obtain a copy of the License at
7b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom *
8b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom *
10b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * See the License for the specific language governing permissions and
14b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * limitations under the License.
15b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom */
16b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
17b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#ifndef ART_SRC_ZIP_ARCHIVE_H_
18b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#define ART_SRC_ZIP_ARCHIVE_H_
19b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
20b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <map>
21b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <stdint.h>
22b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/mman.h>
23b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <zlib.h>
24b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
25db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom#include "file.h"
26b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include "globals.h"
27b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include "logging.h"
28db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom#include "mem_map.h"
29b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include "scoped_ptr.h"
30b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include "stringpiece.h"
317e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "unordered_map.h"
32b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
33b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromnamespace art {
34b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
35b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass ZipArchive;
36b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass MemMap;
37b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
38b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass ZipEntry {
39b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
40b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom public:
41b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  // Uncompress an entry, in its entirety, to an open file descriptor.
42db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  bool Extract(File& file);
43b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
44b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  uint32_t GetCrc32();
45b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
46b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom private:
47b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
48db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  ZipEntry(ZipArchive* zip_archive, const byte* ptr) : zip_archive_(zip_archive), ptr_(ptr) {};
49b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
50b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  // Zip compression methods
51b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  enum {
52b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    kCompressStored     = 0,        // no compression
53b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    kCompressDeflated   = 8,        // standard deflate
54b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  };
55b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
56b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  // kCompressStored, kCompressDeflated, ...
57b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  uint16_t GetCompressionMethod();
58b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
59b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  uint32_t GetCompressedLength();
60b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
61b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  uint32_t GetUncompressedLength();
62b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
63b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  // returns -1 on error
64b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  off_t GetDataOffset();
65b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
66b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  ZipArchive* zip_archive_;
67b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
68b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  // pointer to zip entry within central directory
69db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  const byte* ptr_;
70b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
71b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  friend class ZipArchive;
72b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom};
73b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
74b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass ZipArchive {
75b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom public:
76b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
77b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  // Zip file constants.
78b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const uint32_t kEOCDSignature  = 0x06054b50;
79b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kEOCDLen         = 22;
80b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kEOCDNumEntries  =  8;  // offset to #of entries in file
81b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kEOCDSize        = 12;  // size of the central directory
82b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kEOCDFileOffset  = 16;  // offset to central directory
83b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
84b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kMaxCommentLen = 65535;  // longest possible in uint16_t
85b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kMaxEOCDSearch = (kMaxCommentLen + kEOCDLen);
86b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
87b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const uint32_t kLFHSignature = 0x04034b50;
88b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kLFHLen        = 30;  // excluding variable-len fields
89b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kLFHNameLen    = 26;  // offset to filename length
90b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kLFHExtraLen   = 28;  // offset to extra length
91b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
92b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const uint32_t kCDESignature   = 0x02014b50;
93b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDELen          = 46;  // excluding variable-len fields
94b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDEMethod       = 10;  // offset to compression method
95b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDEModWhen      = 12;  // offset to modification timestamp
96b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDECRC          = 16;  // offset to entry CRC
97b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDECompLen      = 20;  // offset to compressed length
98b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDEUncompLen    = 24;  // offset to uncompressed length
99b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDENameLen      = 28;  // offset to filename length
100b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDEExtraLen     = 30;  // offset to extra length
101b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDECommentLen   = 32;  // offset to comment length
102b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static const int32_t kCDELocalOffset  = 42;  // offset to local hdr
103b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
104b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  static ZipArchive* Open(const std::string& filename);
105b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  ZipEntry* Find(const char * name);
106b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
107b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  ~ZipArchive() {
108b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom    Close();
109b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  }
110b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
111b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom private:
112b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  ZipArchive(int fd) : fd_(fd), num_entries_(0), dir_offset_(0) {}
113b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
114b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  bool MapCentralDirectory();
115b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  bool Parse();
116b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  void Close();
117b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
118b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  int fd_;
119b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  uint16_t num_entries_;
120b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  off_t dir_offset_;
121b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  scoped_ptr<MemMap> dir_map_;
122db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom  typedef std::tr1::unordered_map<StringPiece, const byte*> DirEntries;
1237e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  DirEntries dir_entries_;
124b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
125b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom  friend class ZipEntry;
126b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom};
127b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
128b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom}  // namespace art
129b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom
130b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#endif  // ART_SRC_ZIP_ARCHIVE_H_
131