/*
 * 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 <string>

#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, std::string* error_msg);
  bool ExtractToMemory(uint8_t* begin, size_t size, std::string* error_msg);
  MemMap* ExtractToMemMap(const char* entry_filename, std::string* error_msg);

  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
  off64_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 kEOCDDiskNumber      =  4;              // number of the current disk
  static const int32_t kEOCDDiskNumberForCD =  6;              // disk number with the Central Directory
  static const int32_t kEOCDNumEntries      =  8;              // offset to #of entries in file
  static const int32_t kEOCDTotalNumEntries = 10;              // offset to total #of entries in spanned archives
  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 kEOCDCommentSize     = 20;              // offset to the length of the file comment

  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 kLFHGPBFlags   = 6;   // offset to GPB flags
  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 kCDEGPBFlags     = 8;   // offset to GPB flags
  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

  // General Purpose Bit Flag
  static const int32_t kGPFEncryptedFlag   = (1 << 0);
  static const int32_t kGPFUnsupportedMask = (kGPFEncryptedFlag);

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

  ZipEntry* Find(const char* name) const;

  ~ZipArchive() {
    Close();
  }

 private:
  explicit ZipArchive(int fd, const char* filename)
      : fd_(fd), num_entries_(0), dir_offset_(0), filename_(filename) {}

  bool MapCentralDirectory(std::string* error_msg);
  bool Parse(std::string* error_msg);
  void Close();
  std::string ErrorStringPrintf(const char* fmt, ...)
          __attribute__((__format__(__printf__, 2, 3))) COLD_ATTR;

  int fd_;
  uint16_t num_entries_;
  off64_t dir_offset_;
  UniquePtr<MemMap> dir_map_;
  typedef SafeMap<StringPiece, const byte*> DirEntries;
  DirEntries dir_entries_;
  // Containing file for error reporting.
  const std::string filename_;

  friend class ZipEntry;

  DISALLOW_COPY_AND_ASSIGN(ZipArchive);
};

}  // namespace art

#endif  // ART_RUNTIME_ZIP_ARCHIVE_H_
