/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_ZIP_ARCHIVE_H_
#define ART_RUNTIME_ZIP_ARCHIVE_H_

#include <stdint.h>
#include <zlib.h>

#include "base/logging.h"
#include "base/stringpiece.h"
#include "base/unix_file/random_access_file.h"
#include "globals.h"
#include "mem_map.h"
#include "os.h"
#include "safe_map.h"
#include "UniquePtr.h"

namespace art {

class ZipArchive;
class MemMap;

class ZipEntry {
 public:
  bool ExtractToFile(File& file);
  bool ExtractToMemory(uint8_t* begin, size_t size);
  MemMap* ExtractToMemMap(const char* entry_filename);

  uint32_t GetUncompressedLength();
  uint32_t GetCrc32();

 private:
  ZipEntry(const ZipArchive* zip_archive, const byte* ptr) : zip_archive_(zip_archive), ptr_(ptr) {}

  // Zip compression methods
  enum {
    kCompressStored     = 0,        // no compression
    kCompressDeflated   = 8,        // standard deflate
  };

  // kCompressStored, kCompressDeflated, ...
  uint16_t GetCompressionMethod();

  uint32_t GetCompressedLength();

  // returns -1 on error
  off_t GetDataOffset();

  const ZipArchive* zip_archive_;

  // pointer to zip entry within central directory
  const byte* ptr_;

  friend class ZipArchive;
  DISALLOW_COPY_AND_ASSIGN(ZipEntry);
};

class ZipArchive {
 public:
  // Zip file constants.
  static const uint32_t kEOCDSignature  = 0x06054b50;
  static const int32_t kEOCDLen         = 22;
  static const int32_t kEOCDNumEntries  =  8;  // offset to #of entries in file
  static const int32_t kEOCDSize        = 12;  // size of the central directory
  static const int32_t kEOCDFileOffset  = 16;  // offset to central directory

  static const int32_t kMaxCommentLen = 65535;  // longest possible in uint16_t
  static const int32_t kMaxEOCDSearch = (kMaxCommentLen + kEOCDLen);

  static const uint32_t kLFHSignature = 0x04034b50;
  static const int32_t kLFHLen        = 30;  // excluding variable-len fields
  static const int32_t kLFHNameLen    = 26;  // offset to filename length
  static const int32_t kLFHExtraLen   = 28;  // offset to extra length

  static const uint32_t kCDESignature   = 0x02014b50;
  static const int32_t kCDELen          = 46;  // excluding variable-len fields
  static const int32_t kCDEMethod       = 10;  // offset to compression method
  static const int32_t kCDEModWhen      = 12;  // offset to modification timestamp
  static const int32_t kCDECRC          = 16;  // offset to entry CRC
  static const int32_t kCDECompLen      = 20;  // offset to compressed length
  static const int32_t kCDEUncompLen    = 24;  // offset to uncompressed length
  static const int32_t kCDENameLen      = 28;  // offset to filename length
  static const int32_t kCDEExtraLen     = 30;  // offset to extra length
  static const int32_t kCDECommentLen   = 32;  // offset to comment length
  static const int32_t kCDELocalOffset  = 42;  // offset to local hdr

  // return new ZipArchive instance on success, NULL on error.
  static ZipArchive* Open(const std::string& filename);
  static ZipArchive* OpenFromFd(int fd);

  ZipEntry* Find(const char* name) const;

  ~ZipArchive() {
    Close();
  }

 private:
  explicit ZipArchive(int fd) : fd_(fd), num_entries_(0), dir_offset_(0) {}

  bool MapCentralDirectory();
  bool Parse();
  void Close();

  int fd_;
  uint16_t num_entries_;
  off_t dir_offset_;
  UniquePtr<MemMap> dir_map_;
  typedef SafeMap<StringPiece, const byte*> DirEntries;
  DirEntries dir_entries_;

  friend class ZipEntry;

  DISALLOW_COPY_AND_ASSIGN(ZipArchive);
};

}  // namespace art

#endif  // ART_RUNTIME_ZIP_ARCHIVE_H_
