/*
 * Copyright (c) 2001-2003 Shiman Associates Inc. All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include <string.h>
#include "riff.h"

int32
riff_cmp_fourcc(FourCC id, char* test_string)
{
    if ( test_string == 0 )
        return mas_error(MERR_NULLPTR);
    
    if ( strlen( test_string ) != 4 )
        return mas_error(MERR_INVALID);

    if ( *(uint32*)test_string == id )
        return 0;

    return 1;
}

int32
riff_read_chunk_header( FILE *fp, struct riff_chunk_header* header )
{
    int32 error = 0;

    error = fread(header, 1, sizeof *header, fp);
    if ( error != sizeof *header )
        return mas_error(MERR_IO);

    header->length = mas_letohl(header->length);

    return error;
}


int32
riff_read_chunk(FILE *fp, struct riff_chunk_header* header, void** chunk_ptr)
{
    void* chunk;
    
    if ( header->length == 0 || header->length > RIFF_MAX_CHUNKSIZE )
	return mas_error(MERR_INVALID);

    /* allocate space for the object */
    if ( (chunk = masc_rtalloc( header->length )) == 0)
	return mas_error(MERR_MEMORY);
    
    /* read in the data */
    if ( fread(chunk, header->length, 1, fp) != 1 )
	return mas_error(MERR_IO);

    *chunk_ptr = chunk;
    
    return header->length;
}

int32
riff_start_decode( FILE* fp, struct riff_chunk_header** header_ptr )
{
    struct riff_chunk_header* header;
    int32 err;

    header = MAS_NEW( header );

    /** Check RIFF header */
    if ( ( err = riff_read_chunk_header( fp, header ) ) < 0 )
    {
        masc_rtfree( header );
	return err;
    }
    
    if ( riff_cmp_fourcc( header->id, RIFF_ID ) != 0)
    {
        masc_rtfree( header );
	return mas_error(MERR_INVALID);
    }

    *header_ptr = header;
    
    return 0;
}
