/*
  zip_extra_field_api.c -- public extra fields API functions
  Copyright (C) 2012 Dieter Baron and Thomas Klausner

  This file is part of libzip, a library to manipulate ZIP archives.
  The authors can be contacted at <libzip@nih.at>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
  3. The names of the authors may not be used to endorse or promote
     products derived from this software without specific prior
     written permission.
 
  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/



#include "zipint.h"



ZIP_EXTERN int
zip_file_extra_field_delete(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags)
{
    struct zip_dirent *de;
    
    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return -1;

    de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
    return 0;
}



ZIP_EXTERN int
zip_file_extra_field_delete_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags)
{
    struct zip_dirent *de;
    
    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return -1;

    de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
    return 0;
}



ZIP_EXTERN const zip_uint8_t *
zip_file_extra_field_get(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags)
{
    static const zip_uint8_t empty[1];

    struct zip_dirent *de;
    struct zip_extra_field *ef;
    int i;

    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return NULL;

    if ((flags & ZIP_EF_BOTH) == 0)
	flags = ZIP_EF_BOTH;

    if (flags & ZIP_FL_LOCAL)
	if (_zip_read_local_ef(za, idx) < 0)
	    return NULL;

    i = 0;
    for (ef=de->extra_fields; ef; ef=ef->next) {
	if (ef->flags & flags & ZIP_EF_BOTH) {
	    if (i < ef_idx) {
		i++;
		continue;
	    }

	    if (idp)
		*idp = ef->id;
	    if (lenp)
		*lenp = ef->size;
	    if (ef->size > 0)
		return ef->data;
	    else
		return empty;
	}
    }

    _zip_error_set(&za->error, ZIP_ER_NOENT, 0);
    return NULL;

}



ZIP_EXTERN const zip_uint8_t *
zip_file_extra_field_get_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags)
{
    struct zip_dirent *de;

    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return NULL;

    if ((flags & ZIP_EF_BOTH) == 0)
	flags = ZIP_EF_BOTH;

    if (flags & ZIP_FL_LOCAL)
	if (_zip_read_local_ef(za, idx) < 0)
	    return NULL;

    return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
}



ZIP_EXTERN zip_int16_t
zip_file_extra_fields_count(struct zip *za, zip_uint64_t idx, zip_flags_t flags)
{
    struct zip_dirent *de;
    struct zip_extra_field *ef;
    zip_uint16_t n;

    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return -1;

    if ((flags & ZIP_EF_BOTH) == 0)
	flags = ZIP_EF_BOTH;

    if (flags & ZIP_FL_LOCAL)
	if (_zip_read_local_ef(za, idx) < 0)
	    return -1;

    n = 0;
    for (ef=de->extra_fields; ef; ef=ef->next)
	if (ef->flags & flags & ZIP_EF_BOTH)
	    n++;

    return (zip_int16_t)n;
}



ZIP_EXTERN zip_int16_t
zip_file_extra_fields_count_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags)
{
    struct zip_dirent *de;
    struct zip_extra_field *ef;
    zip_uint16_t n;

    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return -1;

    if ((flags & ZIP_EF_BOTH) == 0)
	flags = ZIP_EF_BOTH;

    if (flags & ZIP_FL_LOCAL)
	if (_zip_read_local_ef(za, idx) < 0)
	    return -1;

    n = 0;
    for (ef=de->extra_fields; ef; ef=ef->next)
	if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
	    n++;

    return (zip_int16_t)n;
}



ZIP_EXTERN int
zip_file_extra_field_set(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags)
{
    struct zip_dirent *de;
    zip_uint16_t ls, cs;
    struct zip_extra_field *ef, *ef_prev, *ef_new;
    int i, found;

    if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
	return -1;

    if (ef_id == ZIP_EF_ZIP64 || ef_id == ZIP_EF_UTF_8_NAME || ef_id == ZIP_EF_UTF_8_COMMENT) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (flags & ZIP_EF_LOCAL)
	ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
    else
	ls = 0;
    if (flags & ZIP_EF_CENTRAL)
	cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
    else
	cs = 0;

    if (((zip_uint32_t)(ls > cs ? ls : cs)) + len + 4 > ZIP_UINT16_MAX) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    ef = de->extra_fields;
    ef_prev = NULL;
    i = 0;
    found = 0;

    for (; ef; ef=ef->next) {
	if (ef->id == ef_id && (ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
	    if (i == ef_idx) {
		found = 1;
		break;
	    }
	    i++;
	}
	ef_prev = ef;
    }

    if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return -1;
    }

    if (found) {
	ef_new->next = ef->next;
	ef->next = NULL;
	_zip_ef_free(ef);
	if (ef_prev)
	    ef_prev->next = ef_new;
	else
	    de->extra_fields = ef_new;
    }
    else if (ef) {
	ef_new->next = ef->next;
	ef->next = ef_new;
    }
    else
	de->extra_fields = ef_new;
    
    return 0;
}
