/* ParrotIO.pmc
 *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
 *  CVS Info
 *     $Id: parrotio.pmc,v 1.13 2003/10/05 17:42:09 leo Exp $
 *  Overview:
 *     These are the vtable functions for Parrot IO
 *  Data Structure and Algorithms:
 *  History:
 *     Initial version by leo 2003/06/23
 *  Notes:
 *  References:
 */

#include "parrot/parrot.h"

/* This class is actually part of the io subsystem */
#include "../io/io_private.h"

static void
enter_nci_method(struct Parrot_Interp *interpreter, PMC *method_table,
		 void *func, const char *name, const char *proto)
{
    PMC *method;

    method = pmc_new(interpreter, enum_class_NCI);
    VTABLE_set_string_keyed(interpreter, method, func,
	    string_make(interpreter, proto, strlen(proto),
		NULL, PObj_constant_FLAG|PObj_external_FLAG, NULL));
    VTABLE_set_pmc_keyed(interpreter, method_table,
	    key_new_string(interpreter,
		string_make(interpreter, name,
		    strlen(name), NULL,
		    PObj_constant_FLAG|PObj_external_FLAG, NULL)),
	    method);
}

void Parrot_NCI_class_init(Parrot_Interp, int);
void Parrot_PerlHash_class_init(Parrot_Interp, int);
void Parrot_PerlUndef_class_init(Parrot_Interp, int);

pmclass ParrotIO need_ext {

    void class_init () {
        PMC *method_table;

        /* These classes are needed now so make sure they are inited */
        Parrot_NCI_class_init(interp, enum_class_NCI);
        Parrot_PerlHash_class_init(interp, enum_class_PerlHash);
        Parrot_PerlUndef_class_init(interp, enum_class_PerlUndef);

        method_table = pmc_new(INTERP, enum_class_PerlHash);

        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_close), "close", "iIP");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_flush), "flush", "vIP");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_read), "read", "iIPii");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_write), "write", "iIPii");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_setbuf), "setbuf", "iIPi");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_setlinebuf), "setlinebuf", "iIP");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_puts), "puts", "iIPt");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_seek), "seek", "iIPiii");
        enter_nci_method(INTERP, method_table,
                         F2DPTR(PIO_eof), "eof", "iIP");

        Parrot_base_vtables[enum_class_ParrotIO]->method_table = method_table;
    }

    void init () {
	PObj_active_destroy_SET(SELF);
    }

    void destroy () {
	ParrotIO *io = PMC_data(SELF);
        if (io) {
            /* shared filehandles will only get flushed */
            if (io->flags & PIO_F_SHARED) {
                PIO_flush(interpreter, SELF);
            }
            else {
                PIO_close(interpreter, SELF);
            }
        }
    }

    void clone (PMC *dest) {
	VTABLE_init(INTERP, dest);
	/* For now both PMCs refer to the same ParrotIO object.
	 * If we have different IO layers, we might copy these structures
	 */
	PMC_data(dest) = PMC_data(SELF);
	dest->cache.struct_val = SELF->cache.struct_val;
    }

    INTVAL get_bool() {
	return !PIO_eof(INTERP, SELF);
    }

}
