
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/* iowin32.c -- IO base function header for compress/uncompress .zip
   files using zlib + zip or unzip API
   This IO API version uses the Win32 API (for Microsoft Windows)

   Version 1.01e, February 12th, 2005

   Copyright (C) 1998-2005 Gilles Vollant
*/

#include <stdlib.h>

#include "zlib.h"
#include "axis2_ioapi.h"
#include "axis2_iowin32.h"

#ifndef INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
#endif

#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif

voidpf ZCALLBACK win32_open_file_func OF(
     (voidpf opaque,
      const char *filename,
      int mode));

uLong ZCALLBACK win32_read_file_func OF(
     (voidpf opaque,
      voidpf stream,
      void *buf,
      uLong size));

uLong ZCALLBACK win32_write_file_func OF(
     (voidpf opaque,
      voidpf stream,
      const void *buf,
      uLong size));

long ZCALLBACK win32_tell_file_func OF(
     (voidpf opaque,
      voidpf stream));

long ZCALLBACK win32_seek_file_func OF(
     (voidpf opaque,
      voidpf stream,
      uLong offset,
      int origin));

int ZCALLBACK win32_close_file_func OF(
     (voidpf opaque,
      voidpf stream));

int ZCALLBACK win32_error_file_func OF(
     (voidpf opaque,
      voidpf stream));

typedef struct
{
    HANDLE hf;
    int error;
}
WIN32FILE_IOWIN;

voidpf ZCALLBACK
win32_open_file_func(
    voidpf opaque,
    const char *filename,
    int mode)
{
    /*const char *mode_fopen = NULL;*/
    DWORD dwDesiredAccess,
     dwCreationDisposition,
     dwShareMode,
     dwFlagsAndAttributes;
    HANDLE hFile = 0;
    voidpf ret = NULL;

    dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = dwCreationDisposition = 0;
    /* dwCreationDisposition = 0, to avoid C4701 */

    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
    {
        dwDesiredAccess = GENERIC_READ;
        dwCreationDisposition = OPEN_EXISTING;
        dwShareMode = FILE_SHARE_READ;
    }
    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
    {
        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
        dwCreationDisposition = OPEN_EXISTING;
    }
    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
    {
        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
        dwCreationDisposition = CREATE_ALWAYS;
    }

    if ((filename) && (dwDesiredAccess != 0))
        hFile =
            CreateFile((LPCTSTR) filename, dwDesiredAccess, dwShareMode, NULL,
                       dwCreationDisposition, dwFlagsAndAttributes, NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        hFile = NULL;

    if (hFile)
    {
        WIN32FILE_IOWIN w32fiow;
        w32fiow.hf = hFile;
        w32fiow.error = 0;
        ret = malloc(sizeof(WIN32FILE_IOWIN));
        if (ret == NULL)
            CloseHandle(hFile);
        else
            *((WIN32FILE_IOWIN *) ret) = w32fiow;
    }
    return ret;
}

uLong ZCALLBACK
win32_read_file_func(
    voidpf opaque,
    voidpf stream,
    void *buf,
    uLong size)
{
    uLong ret = 0;
    HANDLE hFile = NULL;
    if (stream)
        hFile = ((WIN32FILE_IOWIN *) stream)->hf;
    if (hFile)
        if (!ReadFile(hFile, buf, size, &ret, NULL))
        {
            DWORD dwErr = GetLastError();
            if (dwErr == ERROR_HANDLE_EOF)
                dwErr = 0;
            ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr;
        }

    return ret;
}

uLong ZCALLBACK
win32_write_file_func(
    voidpf opaque,
    voidpf stream,
    const void *buf,
    uLong size)
{
    uLong ret = 0;
    HANDLE hFile = NULL;
    if (stream)
        hFile = ((WIN32FILE_IOWIN *) stream)->hf;

    if (hFile)
        if (!WriteFile(hFile, buf, size, &ret, NULL))
        {
            DWORD dwErr = GetLastError();
            if (dwErr == ERROR_HANDLE_EOF)
                dwErr = 0;
            ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr;
        }

    return ret;
}

long ZCALLBACK
win32_tell_file_func(
    voidpf opaque,
    voidpf stream)
{
    long ret = -1;
    HANDLE hFile = NULL;
    if (stream)
        hFile = ((WIN32FILE_IOWIN *) stream)->hf;
    if (hFile)
    {
        DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
        if (dwSet == INVALID_SET_FILE_POINTER)
        {
            DWORD dwErr = GetLastError();
            ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr;
            ret = -1;
        }
        else
            ret = (long) dwSet;
    }
    return ret;
}

long ZCALLBACK
win32_seek_file_func(
    voidpf opaque,
    voidpf stream,
    uLong offset,
    int origin)
{
    DWORD dwMoveMethod = 0xFFFFFFFF;
    HANDLE hFile = NULL;

    long ret = -1;
    if (stream)
        hFile = ((WIN32FILE_IOWIN *) stream)->hf;
    switch (origin)
    {
    case ZLIB_FILEFUNC_SEEK_CUR:
        dwMoveMethod = FILE_CURRENT;
        break;
    case ZLIB_FILEFUNC_SEEK_END:
        dwMoveMethod = FILE_END;
        break;
    case ZLIB_FILEFUNC_SEEK_SET:
        dwMoveMethod = FILE_BEGIN;
        break;
    default:
        return -1;
    }

    if (hFile)
    {
        DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
        if (dwSet == INVALID_SET_FILE_POINTER)
        {
            DWORD dwErr = GetLastError();
            ((WIN32FILE_IOWIN *) stream)->error = (int) dwErr;
            ret = -1;
        }
        else
            ret = 0;
    }
    return ret;
}

int ZCALLBACK
win32_close_file_func(
    voidpf opaque,
    voidpf stream)
{
    int ret = -1;

    if (stream)
    {
        HANDLE hFile;
        hFile = ((WIN32FILE_IOWIN *) stream)->hf;
        if (hFile)
        {
            CloseHandle(hFile);
            ret = 0;
        }
        free(stream);
    }
    return ret;
}

int ZCALLBACK
win32_error_file_func(
    voidpf opaque,
    voidpf stream)
{
    int ret = -1;
    if (stream)
    {
        ret = ((WIN32FILE_IOWIN *) stream)->error;
    }
    return ret;
}

void
fill_win32_filefunc(
    zlib_filefunc_def *pzlib_filefunc_def)
{
    pzlib_filefunc_def->zopen_file = win32_open_file_func;
    pzlib_filefunc_def->zread_file = win32_read_file_func;
    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
    pzlib_filefunc_def->zclose_file = win32_close_file_func;
    pzlib_filefunc_def->zerror_file = win32_error_file_func;
    pzlib_filefunc_def->opaque = NULL;
}
