/*
  zip_string.c -- string handling (with encoding)
  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 <stdlib.h>
#include <string.h>

#include "zipint.h"



zip_uint32_t
_zip_string_crc32(const struct zip_string *s)
{
    zip_uint32_t crc;
    
    crc = (zip_uint32_t)crc32(0L, Z_NULL, 0);

    if (s != NULL)    
	crc = (zip_uint32_t)crc32(crc, s->raw, s->length);

    return crc;
}



int
_zip_string_equal(const struct zip_string *a, const struct zip_string *b)
{
    if (a == NULL || b == NULL)
	return a == b;

    if (a->length != b->length)
	return 0;

    /* XXX: encoding */

    return (memcmp(a->raw, b->raw, a->length) == 0);
}



void
_zip_string_free(struct zip_string *s)
{
    if (s == NULL)
	return;

    free(s->raw);
    free(s->converted);
    free(s);
}



const zip_uint8_t *
_zip_string_get(struct zip_string *string, zip_uint32_t *lenp, zip_flags_t flags, struct zip_error *error)
{
    static const zip_uint8_t empty[1] = "";

    if (string == NULL) {
	if (lenp)
	    *lenp = 0;
	return empty;
    }

    if ((flags & ZIP_FL_ENC_RAW) == 0) {
	/* start guessing */
	if (string->encoding == ZIP_ENCODING_UNKNOWN)
	    _zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN);

	if (((flags & ZIP_FL_ENC_STRICT)
	     && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN)
	    || (string->encoding == ZIP_ENCODING_CP437)) {
	    if (string->converted == NULL) {
		if ((string->converted=_zip_cp437_to_utf8(string->raw, string->length,
							  &string->converted_length, error)) == NULL)
		    return NULL;
	    }
	    if (lenp)
		*lenp = string->converted_length;
	    return string->converted;
	}
    }
    
    if (lenp)
	*lenp = string->length;
    return string->raw;
}



zip_uint16_t
_zip_string_length(const struct zip_string *s)
{
    if (s == NULL)
	return 0;

    return s->length;
}



struct zip_string *
_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, struct zip_error *error)
{
    struct zip_string *s;
    enum zip_encoding_type expected_encoding;
    
    if (length == 0)
	return NULL;

    switch (flags & ZIP_FL_ENCODING_ALL) {
    case ZIP_FL_ENC_GUESS:
	expected_encoding = ZIP_ENCODING_UNKNOWN;
	break;
    case ZIP_FL_ENC_UTF_8:
	expected_encoding = ZIP_ENCODING_UTF8_KNOWN;
	break;
    case ZIP_FL_ENC_CP437:
	expected_encoding = ZIP_ENCODING_CP437;
	break;
    default:
	_zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }
	
    if ((s=malloc(sizeof(*s))) == NULL) {
	_zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    if ((s->raw=malloc(length+1)) == NULL) {
	free(s);
	return NULL;
    }

    memcpy(s->raw, raw, length);
    s->raw[length] = '\0';
    s->length = length;
    s->encoding = ZIP_ENCODING_UNKNOWN;
    s->converted = NULL;
    s->converted_length = 0;

    if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
	if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) {
	    _zip_string_free(s);
	    _zip_error_set(error, ZIP_ER_INVAL, 0);
	    return NULL;
	}
    }
    
    return s;
}



void
_zip_string_write(const struct zip_string *s, FILE *f)
{
    if (s == NULL)
	return;
    
    fwrite(s->raw, s->length, 1, f);
}
