/*
 * 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_SRC_ZIP_ARCHIVE_H_
#define ART_SRC_ZIP_ARCHIVE_H_

#include <stdint.h>
#include <sys/mman.h>
#include <zlib.h>

#include <map>

#include "UniquePtr.h"
#include "file.h"
#include "globals.h"
#include "logging.h"
#include "mem_map.h"
#include "stringpiece.h"
#include "unordered_map.h"

namespace art {

class ZipArchive;
class MemMap;

class ZipEntry {

 public:
  // Uncompress an entry, in its entirety, to an open file descriptor.
  bool Extract(File& file);

  uint32_t GetCrc32();

 private:

  ZipEntry(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();

  uint32_t GetUncompressedLength();

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

  ZipArchive* zip_archive_;

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

  friend class ZipArchive;
};

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

  static ZipArchive* Open(const std::string& filename);
  ZipEntry* Find(const char * name);

  ~ZipArchive() {
    Close();
  }

 private:
  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 std::tr1::unordered_map<StringPiece, const byte*, StringPieceHash> DirEntries;
  DirEntries dir_entries_;

  friend class ZipEntry;
};

}  // namespace art

#endif  // ART_SRC_ZIP_ARCHIVE_H_
