/*
 * miniz.c
 *
 *  Created on: 04/ago/2017
 *      Author: chessaa
 */



//#include "bsk_miniz.h"

//#define mz_zip_info_t bsk_zip_info_t

#include "miniz_header.h"

#include <string.h>

/* parasoft off
 *   Third part file
 */

typedef unsigned char mz_uint8;
typedef signed short mz_int16;
typedef unsigned short mz_uint16;
typedef unsigned int mz_uint32;
typedef unsigned int mz_uint;
typedef long long mz_int64;
typedef unsigned long long mz_uint64;
typedef int mz_bool;

#define MZ_CRC32_INIT (0)

unsigned long mz_b2l(const unsigned char* b)
{
  unsigned long l;
  memcpy(&l, b, sizeof l);
  return l;
}

unsigned short mz_b2s(const unsigned char* b)
{
  unsigned short l;
  memcpy(&l, b, sizeof l);
  return l;
}

void mz_s2b(unsigned char* b, unsigned short s)
{
  memcpy(b, &s, sizeof s);
}

void mz_l2b(unsigned char* b, unsigned long s)
{
  memcpy(b, &s, sizeof s);
}

//TODO: use max_size
int mz_check_zip_header(struct mz_zip_info_t* zi, const void* const data, unsigned int /*dlen*/)
{
  static char buffer[128];
  struct mz_zip_info_t zi_buff;

  if (!zi)
    zi=&zi_buff;

  memset(zi, 0,sizeof *zi);
  zi->data_start=data;

  const char* image=(char*)data;
  const struct zip_file_header_t* zh=(const struct zip_file_header_t*)data;
  if (!(zh->header_signature[0]=='P' && zh->header_signature[1]=='K' && zh->header_signature[2]==3 && zh->header_signature[3]==4))
    return -1;


  unsigned long csize=mz_b2l(zh->csize);
  unsigned long usize=mz_b2l(zh->usize);

  unsigned short fname_len=mz_b2s(zh->fname_len);
  unsigned short extra_len=mz_b2s(zh->extra_len);

  unsigned short flags=mz_b2s(zh->flags);

  zi->valid=1;

  zi->compressed=(flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? 1 : 0;
  zi->compressed|=csize!=usize ? 2 : 0;

  zi->compressed_size=csize;
  zi->uncompressed_size=usize;
  zi->crc32=mz_b2l(zh->crc32);

  if (!fname_len)
  {
    buffer[0]=0;
    zi->filename=0;
  }
  else
  {
    unsigned int len=fname_len;
    if (len>(sizeof(buffer)-1))
      len=sizeof(buffer)-1;
    unsigned int i;
    char* s=(char*)&image[sizeof(struct zip_file_header_t)];
    for(i=0; i<len; ++i)
      buffer[i]=s[i];
    buffer[i]=0;
    zi->filename=buffer;
  }

  zi->data_offset=sizeof(struct zip_file_header_t)+fname_len+extra_len;
  zi->data_start=&image[zi->data_offset];

  return zi->compressed ? 0 : 1;
}

mz_ulong mz_crc32_ext(mz_ulong crc, const void *ptr_, unsigned int buf_len)
{
  static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
    0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
  const unsigned char* ptr=(const unsigned char*)ptr_;
  mz_uint32 crcu32 = (mz_uint32)crc;
  if (!ptr) return MZ_CRC32_INIT;
  crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
  return ~crcu32;
}

mz_ulong mz_crc32(const void *ptr_, unsigned int buf_len)
{
  return mz_crc32_ext(MZ_CRC32_INIT, ptr_, buf_len);
}
