/*
  zip_source_crc.c -- pass-through source that calculates CRC32 and size
  Copyright (C) 2009 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 <stdlib.h>
#include <string.h>

#include "zipint.h"

struct crc {
    int eof;
    int validate;
    int e[2];
    zip_uint64_t size;
    zip_uint32_t crc;
};

static zip_int64_t crc_read(struct zip_source *, void *, void *
			    , zip_uint64_t, enum zip_source_cmd);



struct zip_source *
zip_source_crc(struct zip *za, struct zip_source *src, int validate)
{
    struct crc *ctx;

    if (src == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    ctx->validate = validate;

    return zip_source_layered(za, src, crc_read, ctx);
}



static zip_int64_t
crc_read(struct zip_source *src, void *_ctx, void *data,
	 zip_uint64_t len, enum zip_source_cmd cmd)
{
    struct crc *ctx;
    zip_int64_t n;

    ctx = (struct crc *)_ctx;

    switch (cmd) {
    case ZIP_SOURCE_OPEN:
	ctx->eof = 0;
	ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
	ctx->size = 0;

	return 0;

    case ZIP_SOURCE_READ:
	if (ctx->eof || len == 0)
	    return 0;

	if ((n=zip_source_read(src, data, len)) < 0)
	    return ZIP_SOURCE_ERR_LOWER;

	if (n == 0) {
	    ctx->eof = 1;
	    if (ctx->validate) {
		struct zip_stat st;

		if (zip_source_stat(src, &st) < 0)
		    return ZIP_SOURCE_ERR_LOWER;

		if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
		    ctx->e[0] = ZIP_ER_CRC;
		    ctx->e[1] = 0;
		    
		    return -1;
		}
		if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
		    ctx->e[0] = ZIP_ER_INCONS;
		    ctx->e[1] = 0;
		    
		    return -1;
		}
	    }
	}
	else {
	    ctx->size += (zip_uint64_t)n;
	    ctx->crc = (zip_uint32_t)crc32(ctx->crc, data, (uInt)n); /* XXX: check for overflow, use multiple crc calls if needed */
	}
	return n;

    case ZIP_SOURCE_CLOSE:
	return 0;

    case ZIP_SOURCE_STAT:
	{
	    struct zip_stat *st;

	    st = (struct zip_stat *)data;

	    if (ctx->eof) {
		/* XXX: Set comp_size, comp_method, encryption_method?
		        After all, this only works for uncompressed data. */
		st->size = ctx->size;
		st->crc = ctx->crc;
		st->comp_size = ctx->size;
		st->comp_method = ZIP_CM_STORE;
		st->encryption_method = ZIP_EM_NONE;
		st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;;
	    }
	}
	return 0;
	
    case ZIP_SOURCE_ERROR:
	memcpy(data, ctx->e, sizeof(ctx->e));
	return 0;

    case ZIP_SOURCE_FREE:
	free(ctx);
	return 0;

    default:
	return -1;
    }
    
}
