Author: allison
Date: Sun Nov 30 18:16:50 2008
New Revision: 33395

Modified:
   branches/pdd22io_part2/src/io/socket_api.c

Log:
[pdd22io] Conversion of Socket API functions.


Modified: branches/pdd22io_part2/src/io/socket_api.c
==============================================================================
--- branches/pdd22io_part2/src/io/socket_api.c  (original)
+++ branches/pdd22io_part2/src/io/socket_api.c  Sun Nov 30 18:16:50 2008
@@ -4,1345 +4,36 @@
 
 =head1 NAME
 
-src/io/io.c - Generic IO
+src/io/socket_api.c - Socket I/O API
 
 =head1 DESCRIPTION
 
-The Parrot IO subsystem uses a per-interpreter stack to provide a layer-based
-approach to IO. Each layer implements a subset of the C<ParrotIOLayerAPI>
-vtable. To find an IO function, Parrot searches the layer stack downwards until
-it finds a non-C<NULL> function pointer for that particular slot.
-
-This file implements the generic functionality. Specific layers are in
-separate files: F<src/io/io_buf.c>, F<src/io/io_stdio.c>, F<src/io/io_unix.c>,
-F<src/io/io_win32.c>, and F<src/io/io_layers.c>.
+These are the primary interface functions for working with socket objects.
 
-The C<ParrotIO> PMC provides the class-based interface that is used in
-Parrot ops. The C<ParrotIO struct> is defined in F<src/io/io_private.h>.
-
-=head2 Resource Functions
-
-=over 4
-
-=cut
-
-*/
-
-#include "parrot/parrot.h"
-#include "io_private.h"
-#include "io.str"
-
-#include <stdarg.h>
-
-/* HEADERIZER HFILE: include/parrot/io.h */
-
-/*
-        The standard streams are:
-
-                interp->piodata->table[PIO_STD*_FILENO].
-*/
-
-
-PIOOFF_T piooffsetzero;
-
-/*
-
-=item C<PMC * new_io_pmc>
-
-Creates and returns a new C<ParrotIO> PMC.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-new_io_pmc(PARROT_INTERP, ARGIN_NULLOK(ParrotIO *io))
-{
-    PMC * const new_pmc     = pmc_new(interp, enum_class_ParrotIO);
-    PMC_data(new_pmc)       = io;
-    PMC_struct_val(new_pmc) = io ? io->stack : NULL;
-    return new_pmc;
-}
-
-/*
-
-=item C<STRING * PIO_make_io_string>
-
-Creates a STRING* suitable for returning results from IO read functions.
-The passed in C<buf> parameter can:
-
-=over 4
-
-=item 1
-
-Point to a NULL STRING
-
-=item 2
-
-Point to a real STRING
-
-=item 3
-
-Point to a fake STRING with (strstart, bufused) holding the *buffer
-information.
-
-=back
-
-In the third case, the buffer or STRING must be able to hold the required
-amount of data. For cases 1 and 2, a NULL C<strstart> tells this function to
-allocate the STRING memory.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-STRING *
-PIO_make_io_string(PARROT_INTERP, ARGMOD(STRING **buf), size_t len)
-{
-    /*
-     * when we get a NULL string, we read a default len
-     */
-    if (*buf == NULL) {
-        *buf = string_make_empty(interp, enum_stringrep_one, len);
-        return *buf;
-    }
-    else {
-        STRING *s = *buf;
-        if (s->bufused < len)
-            Parrot_allocate_string(interp, s, len);
-        return s;
-    }
-}
-
-
-/*
-
-=item C<ParrotIO * PIO_new>
-
-Creates a new IO stream.
-
-The values of C<flags> and C<mode> are set in the returned C<ParrotIO>.
-
-Currently C<iotype> is unused.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-ParrotIO *
-PIO_new(PARROT_INTERP, SHIM(INTVAL iotype), INTVAL flags, INTVAL mode)
-{
-    ParrotIO * const new_io = (ParrotIO *)mem_sys_allocate(sizeof (ParrotIO));
-
-    new_io->fpos     = new_io->lpos = piooffsetzero;
-    new_io->flags    = flags;
-    new_io->mode     = mode;
-    new_io->stack    = interp->piodata->default_stack;
-    new_io->b.flags  = 0;
-    new_io->b.size   = 0;
-    new_io->b.startb = NULL;
-    new_io->b.endb   = NULL;
-    new_io->b.next   = NULL;
-    return new_io;
-}
-
-/*
-
-=item C<PMC * PIO_dup>
-
-Duplicates an IO stream.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-PIO_dup(PARROT_INTERP, ARGIN(PMC *pmc))
-{
-    ParrotIO * const io   = PMC_data_typed(pmc, ParrotIO *);
-    const PIOHANDLE newfd = Parrot_dup(io->fd);
-    ParrotIOLayer * layer = (ParrotIOLayer *)PMC_struct_val(pmc);
-
-    ParrotIO * newio;
-
-    if (!layer) {
-        layer = interp->piodata->default_stack;
-    }
-
-    if (newfd == (PIOHANDLE)-1)
-        Parrot_ex_throw_from_c_args(interp, NULL, 1, "could not dup an fd");
-
-    newio = PIO_fdopen_down(interp, layer, newfd, io->flags);
-    /* io could be null here but we still have
-     * to create a PMC for the caller, no PMCNULL here
-     * as that would cause an exception upon access.
-     */
-    if (newio)
-        newio->stack = layer;
-
-    return new_io_pmc(interp, newio);
-}
-
-/*
-
-=item C<void PIO_destroy>
-
-Destroys the IO stream.  At the moment, this only frees the memory and removes
-the pointers from the PMC.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-PIO_destroy(SHIM_INTERP, ARGMOD(PMC * pmc))
-{
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-
-    if (!io)
-        return;
-    if (io->b.startb && (io->b.flags & PIO_BF_MALLOC)) {
-        mem_sys_free(io->b.startb);
-        io->b.startb = 0;
-    }
-#if 0
-    /*
-     * PIO_destroy is called by PIO_close
-     * XXX can't munmap now
-     */
-    if (io->b.startb && (io->b.flags & PIO_BF_MMAP)) {
-#  ifdef PARROT_HAS_HEADER_SYSMMAN
-        munmap((void*)io->b.startb, io->b.size);
-#  endif
-        io->b.startb = io->b.endb = NULL;
-        io->b.size = 0;
-    }
-#endif
-    if ((io->stack->flags & PIO_L_LAYER_COPIED)) {
-        ParrotIOLayer *p;
-        for (p = io->stack; p;) {
-            ParrotIOLayer *down;
-            /* if top got copied, all have to be malloced */
-            PARROT_ASSERT(p->flags & PIO_L_LAYER_COPIED);
-            down = p->down;
-            if (p->api->Delete)
-                (*p->api->Delete) (p);
-            p = down;
-        }
-    }
-    mem_sys_free(io);
-    PMC_data(pmc) = NULL;
-    PMC_struct_val(pmc) = NULL;
-}
-
-/*
-
-=item C<void PIO_init>
-
-Sets up the interpreter's layer stack and creates the C<STD*> handles.
-
-Called when creating an interpreter.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-PIO_init(PARROT_INTERP)
-{
-    /* Has interp been initialized already? */
-    if (interp->piodata) {
-        /* memsub system is up and running: */
-        /* Init IO stacks and handles for interp instance.  */
-        if (PIO_init_stacks(interp) != 0)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "PIO init stacks failed.");
-
-        /* see also RT #36677 */
-        if (!_PIO_STDIN(interp)) {
-            _PIO_STDIN(interp) = pmc_new(interp, enum_class_Undef);
-        }
-        if (!_PIO_STDOUT(interp)) {
-            _PIO_STDOUT(interp) = pmc_new(interp, enum_class_Undef);
-        }
-        if (!_PIO_STDERR(interp)) {
-            _PIO_STDERR(interp) = pmc_new(interp, enum_class_Undef);
-        }
-
-        if (Interp_debug_TEST(interp, PARROT_START_DEBUG_FLAG)) {
-            PIO_eprintf(NULL, "PIO: IO system initialized.\n");
-        }
-
-        return;
-    }
-
-
-    interp->piodata = mem_allocate_typed(ParrotIOData);
-    if (interp->piodata == NULL)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-            "PIO alloc piodata failure.");
-    interp->piodata->default_stack = NULL;
-    interp->piodata->table         =
-        (PMC **)mem_sys_allocate_zeroed(PIO_NR_OPEN * sizeof (ParrotIO *));
-
-    if (!interp->piodata->table)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-            "PIO alloc table failure.");
-}
-
-/*
-
-=item C<void PIO_finish>
-
-Closes the interpreter's IO resourses.  Called during its interpreter
-destruction.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-PIO_finish(PARROT_INTERP)
-{
-    ParrotIOLayer *layer;
-#if 0
-    PMC *pmc;
-    ParrotIO *io;
-    int i;
-
-    /* When here, the PMC arena is already destroyed, these PMCs
-     * aren't usable any more.
-     * But ParrotIO::destroy should have flushed/closed all PIOs
-     * already. If that's not quite true, we have to separate IO subsys
-     * destruction into two parts (again).
-     */
-    for (i = 0 ; i < PIO_NR_OPEN; i++) {
-        if ((pmc = interp->piodata->table[i])) {
-            layer = PMC_struct_val(pmc);
-            io = PMC_data(pmc);
-            PIO_close_down(interp, layer, io);
-        }
-    }
-#endif
-    /*
-     * TODO free IO of std-handles
-     */
-    for (layer = interp->piodata->default_stack; layer;) {
-        ParrotIOLayer * const down = layer->down;
-        if (layer->api->Delete)
-            (*layer->api->Delete) (layer);
-        layer = down;
-    }
-    mem_sys_free(interp->piodata->table);
-    interp->piodata->table = NULL;
-    mem_sys_free(interp->piodata);
-    interp->piodata = NULL;
-
-}
-
-/*
-
-=item C<void PIO_internal_shutdown>
-
-IO system destructor, called on destruction of the last interpreter.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-PIO_internal_shutdown(PARROT_INTERP)
-{
-    PARROT_ASSERT(! interp->parent_interpreter);
-    mem_sys_free(interp->piolayers);
-    interp->piolayers = NULL;
-}
-
-/*
-
-=item C<INTVAL PIO_init_stacks>
-
-Initializes the interpreter's default IO stack by pushing on the IO
-layers (OS-specific first).
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_init_stacks(PARROT_INTERP)
-{
-    ParrotIOLayer *p, *bottom = NULL;
-    int fill, n, i;
-
-    /* First push the platform specific OS layer */
-    /* Optimize this to keep a default stack and just
-     * call copy stack.
-     */
-#ifdef PIO_OS_UNIX
-    PIO_push_layer(interp, PMCNULL, PIO_base_new_layer(&pio_unix_layer));
-#endif
-#ifdef PIO_OS_WIN32
-    PIO_push_layer(interp, PMCNULL, PIO_base_new_layer(&pio_win32_layer));
-#endif
-#ifdef PIO_OS_STDIO
-    PIO_push_layer(interp, PMCNULL, PIO_base_new_layer(&pio_stdio_layer));
-#endif
-    PIO_push_layer(interp, PMCNULL, PIO_base_new_layer(&pio_buf_layer));
-
-    fill = 0;
-    if (!interp->piolayers) {
-        n = 5;  /* 2 default layers for now + utf8, mmap, string */
-        if (interp->parent_interpreter) {
-            PARROT_ASSERT(interp->parent_interpreter->piolayers);
-            interp->piolayers = interp->parent_interpreter->piolayers;
-        }
-        else {
-            interp->piolayers = mem_allocate_n_typed(n + 1, ParrotIOLayer *);
-            fill = 1;
-        }
-    }
-
-    /* Note: All layer pushes should be done before init calls */
-    for (i = 0, p = interp->piodata->default_stack; p; p = p->down) {
-        bottom = p;
-        if (fill) {
-            PARROT_ASSERT(i < n); /* XXX n can be undefined at this point. */
-            interp->piolayers[i++] = p;
-            interp->piolayers[i]   = NULL;
-        }
-    }
-    /*
-     * Init calls where done top down, which seem quite wrong  - lower
-     * levels need first to open e.g. STD*. Then the buffered layer can
-     * set linebuffering or such
-     */
-    for (p = bottom; p; p = p->up) {
-        if (p->api->Init) {
-            if ((*p->api->Init) (interp, p) != 0) {
-                /* ignore err
-                 * see also #36677
-                char buf[1024];
-                sprintf(buf, "Parrot IO: Failed init layer(%s).\n", p->name);
-                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, 
buf);
-                */
-                ;
-            }
-        }
-    }
-    if (fill) {
-        PARROT_ASSERT(i == 2);
-        PARROT_ASSERT(interp->piolayers[2] == NULL);
-        interp->piolayers[2] = PIO_utf8_register_layer();
-        interp->piolayers[3] = PIO_mmap_register_layer();
-        interp->piolayers[4] = PIO_string_register_layer();
-        interp->piolayers[5] = NULL;
-    }
-
-    return 0;
-}
-
-/*
-
-=item C<INTVAL PIO_base_init>
-
-Init routine called once for each layer at interpreter creation time.
-This is similar to a Perl module C<INIT {}> block.
-
-This default implementation does nothing and returns C<0>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_base_init(SHIM_INTERP, SHIM(ParrotIOLayer *l))
-{
-    return 0;
-}
-
-
-/*
-
-=back
-
-=head2 Generic top-level C<ParrotIO> interface
-
-=over 4
-
-=item C<INTVAL PIO_parse_open_flags>
-
-Parses C<*flagstr> for Perl-style file open mode flags (C<< < >>, C<< > >>,
-C<<< >> >>>, C<< +< >>, C<< +> >>) and returns the combined generic bit flags.
-
-The low level OS layers may then interpret the generic bits differently
-depending on platform.
-
-XXX BD Should this be static?
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-INTVAL
-PIO_parse_open_flags(ARGIN_NULLOK(const char *flagstr))
-{
-    INTVAL flags;
-    const char *s;
-
-    if (!flagstr || !(*flagstr))
-        return 0;
-    flags = 0;
-    s = flagstr;
-    /* Set mode flags - <, >, >>, +<, +> */
-    switch (*s++) {
-        case '+':
-            flags |= (PIO_F_WRITE | PIO_F_READ);
-            switch (*s++) {
-                case '<':
-                    break;
-                case '>':
-                    flags |= PIO_F_TRUNC;
-                    break;
-                default:
-                    return 0;
-            }
-            break;
-        case '<':
-            flags |= PIO_F_READ;
-            break;
-        case '>':
-            flags |= PIO_F_WRITE;
-            if (*s == '>') {
-                flags |= PIO_F_APPEND;
-                s++;
-            }
-            else {
-                flags |= PIO_F_TRUNC;
-            }
-            break;
-        case '-':       /* -| read from pipe */
-            if (*s == '|') {
-                flags |= PIO_F_PIPE | PIO_F_READ;
-                s++;
-            }
-            break;
-        case '|':       /* |- write to pipe */
-            if (*s == '-') {
-                flags |= PIO_F_PIPE | PIO_F_WRITE;
-                s++;
-            }
-            break;
-        default:
-            return 0;
-    }
-
-    /* TODO: add ? and ! for block/non-block */
-    switch (*s++) {
-        case '\0':
-            /* No extra arguments */
-            break;
-        default:
-            return 0;
-    }
-
-    return flags;
-}
-
-/*
-
-=item C<INTVAL PIO_peek>
-
-Iterates down the stack to the first layer implementing "Peek" API.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_peek(PARROT_INTERP, ARGMOD(PMC *pmc), ARGOUT(STRING **buffer))
-{
-    ParrotIOLayer * const l  = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO      * const io = (ParrotIO *)PMC_data0(pmc);
-    if (!io)
-        return -1;
-    return PIO_peek_down(interp, l, io, buffer);
-}
-
-
-
-/*
-
-=item C<INTVAL PIO_pioctl>
-
-General purpose interface for manipulating IO objects and layer attributes.
-
-Refer to the C<PIOCTL*> values in F<include/parrot/io.h>.
-
-All C<set> operations return C<0> on success and a negative value on error.
-C<get> operations use the return value as the value requested, but should
-always be C<< >= 0 >>. A negative value indicates an error. This may be too
-limited, but we will see. --Melvin
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_pioctl(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL cmd, INTVAL arg)
-{
-
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-    ParrotIOBuf *b;
-    if (!io)
-        return -1;
-    b = &io->b;
-
-    switch (cmd) {
-       case PIOCTL_CMDSETRECSEP: io->recsep = arg;
-
-       case PIOCTL_CMDGETRECSEP: return io->recsep;
-
-       case PIOCTL_CMDSETBUFTYPE:
-            if (arg == PIOCTL_NONBUF)
-               return PIO_setbuf(interp, pmc, 0);
-            else if (arg == PIOCTL_LINEBUF)
-               return PIO_setlinebuf(interp, pmc);
-            else if (arg == PIOCTL_BLKBUF)
-               return PIO_setbuf(interp, pmc, PIO_UNBOUND);
-            else return -1;
-
-       case PIOCTL_CMDGETBUFTYPE:
-            if (io->flags & PIO_F_LINEBUF) return PIOCTL_LINEBUF;
-            if (io->flags & PIO_F_BLKBUF) return PIOCTL_BLKBUF;
-            return PIOCTL_NONBUF;
-
-       case PIOCTL_CMDSETBUFSIZE:
-            return PIO_setbuf(interp, pmc, arg);
-
-       case PIOCTL_CMDGETBUFSIZE:
-             if (b) return b->size;
-             else return -1;
-       default: return -1;
-    }
-}
-
-/*
-
-=item C<INTVAL PIO_setbuf>
-
-Sets the buffer size for C<*pmc> to C<bufsize>. Returns C<0> if the
-buffering was enabled.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_setbuf(PARROT_INTERP, ARGMOD(PMC *pmc), size_t bufsize)
-{
-    ParrotIOLayer * const layer = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO      * const io    = (ParrotIO *)PMC_data0(pmc);
-    if (!io)
-        return -1;
-    PIO_flush(interp, pmc);
-    return PIO_setbuf_down(interp, layer, io, bufsize);
-}
-
-/*
-
-=item C<INTVAL PIO_setlinebuf>
-
-Enables line buffering for C<*pmc>. Returns C<0> if line buffering was
-successfully set, or already enabled.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_setlinebuf(PARROT_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIOLayer * const l  = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO      * const io = (ParrotIO *)PMC_data0(pmc);
-    if (!io)
-        return -1;
-
-    return PIO_setlinebuf_down(interp, l, io);
-}
-
-/*
-
-=item C<PMC * PIO_open>
-
-Creates and returns a C<ParrotIO> PMC for C<*spath>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-PIO_open(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGIN(const char *spath), ARGIN(const char *sflags))
-{
-    ParrotIO *io;
-    const INTVAL flags = PIO_parse_open_flags(sflags);
-
-    if (!layer) {
-        layer = interp->piodata->default_stack;
-    }
-
-    io = PIO_open_down(interp, layer, spath, flags);
-    /* io could be null here but we still have to
-     * to create a PMC for the caller, no PMCNULL here
-     * as that would cause an exception upon access.
-     */
-    if (io) {
-        io->stack = layer;
-    }
-
-    return new_io_pmc(interp, io);
-}
-
-/*
-
-=item C<PMC * PIO_fdopen>
-
-Creates and returns a C<ParrotIO> PMC for C<*spath> on an existing, open
-file descriptor.
-
-This is used particularly to initialize the C<STD*> IO handles onto the
-OS IO handles (0, 1, 2).
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-PIO_fdopen(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer), PIOHANDLE fd,
-        ARGIN(const char *sflags))
-{
-    ParrotIO *io;
-    INTVAL flags;
-
-    if (!layer) {
-        layer = interp->piodata->default_stack;
-    }
-
-    flags = PIO_parse_open_flags(sflags);
-    if (!flags)
-        return NULL;
-
-    io = PIO_fdopen_down(interp, layer, fd, flags);
-    /* io could be null here but we still have to
-     * to create a PMC for the caller, no PMCNULL here
-     * as that would cause an exception upon access.
-     */
-    if (io) {
-        io->stack = layer;
-    }
-
-    return new_io_pmc(interp, io);
-}
-
-/*
-
-=item C<INTVAL PIO_close>
-
-Flushes, closes, and destroys the C<ParrotIO> PMC C<*pmc>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_close(PARROT_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-    if (!io)
-        return -1;
-    else {
-        INTVAL res;
-        ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-        PIO_flush(interp, pmc); /* XXX boe: is this neccessary here? */
-        res =  PIO_close_down(interp, l, io);
-        PIO_destroy(interp, pmc);
-
-        return res;
-    }
-}
-
-/*
-
-=item C<void PIO_flush>
-
-Flushes the C<ParrotIO> PMC C<*pmc>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-PIO_flush(PARROT_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIOLayer * const l  = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO      * const io = (ParrotIO *)PMC_data0(pmc);
-    INTVAL                ignored;
-
-    if (!io)
-        return;
-
-    ignored = PIO_flush_down(interp, l, io);
-    UNUSED(ignored);
-}
-
-/*
-
-=item C<STRING * PIO_reads>
-
-Return a new C<STRING*> holding up to C<len> bytes.
-
-=cut
-
-*/
-
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-STRING *
-PIO_reads(PARROT_INTERP, ARGMOD(PMC *pmc), size_t len)
-{
-    STRING               *res;
-    ParrotIOLayer * const l   = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO      * const io  = (ParrotIO *)PMC_data0(pmc);
-    INTVAL                ignored;
-
-    if (!io)
-        return new_string_header(interp, 0);
-
-    if (io->b.flags & PIO_BF_MMAP) {
-        res           = new_string_header(interp, 0);
-        res->charset  = Parrot_iso_8859_1_charset_ptr;   /* XXX binary */
-        res->encoding = Parrot_fixed_8_encoding_ptr;
-    }
-    else {
-        res = NULL;
-        res = PIO_make_io_string(interp, &res, len);
-    }
-
-    res->bufused = len;
-    ignored      = PIO_read_down(interp, l, io, &res);
-    UNUSED(ignored);
-
-    return res;
-}
-
-/*
-
-=item C<INTVAL PIO_read>
-
-Reads up to C<len> bytes from C<*pmc> and copies them into C<*buffer>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-INTVAL
-PIO_read(PARROT_INTERP, ARGMOD(PMC *pmc), ARGIN(char *buffer), size_t len)
-{
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-    STRING *res = new_string_header(interp, 0);
-    if (!io)
-        return -1;
-
-    res->strstart = buffer;
-    res->bufused = len;
-    return PIO_read_down(interp, l, io, &res);
-}
-
-/*
-
-=item C<INTVAL PIO_write>
-
-Writes C<len> bytes from C<*buffer> to C<*pmc>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-INTVAL
-PIO_write(PARROT_INTERP, ARGMOD(PMC *pmc), ARGIN(const void *buffer), size_t 
len)
-{
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-    DECL_CONST_CAST;
-
-    if (!io)
-        return -1;
-
-    if (io->flags & PIO_F_WRITE) {
-        STRING fake;
-        /* TODO skip utf8 translation layers if any */
-        fake.strstart = (char *) PARROT_const_cast(void *, buffer);
-        fake.strlen = fake.bufused = len;
-        fake.charset = Parrot_default_charset_ptr;
-        fake.encoding = Parrot_default_encoding_ptr;
-        return PIO_write_down(interp, l, io, &fake);
-    }
-    else
-        return 0;
-}
-
-/*
-
-=item C<PIOOFF_T PIO_seek>
-
-Moves the read/write position of C<*pmc> to offset C<bytes> from the
-position indicated by C<w>. Typically C<w> will be C<0> for the start of
-the file, C<1> for the current position, and C<2> for the end.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PIOOFF_T
-PIO_seek(PARROT_INTERP, ARGMOD(PMC *pmc), PIOOFF_T offset, INTVAL w)
-{
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-    if (!io)
-        return -1;
-
-    return PIO_seek_down(interp, l, io, offset, w);
-}
-
-/*
-
-=item C<PIOOFF_T PIO_tell>
-
-Returns the current read/write position of C<*pmc>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PIOOFF_T
-PIO_tell(PARROT_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-    if (!io)
-        return -1;
-
-    return PIO_tell_down(interp, l, io);
-}
-
-/*
-
-=item C<INTVAL PIO_eof>
-
-Returns a boolean value indication whether C<*pmc>'s current read/write
-position is C<EOF>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-INTVAL
-PIO_eof(SHIM_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-
-    /* io could be null here, but rather than return a negative error
-     * we just fake EOF since eof test is usually in a boolean context.
-     */
-    if (io) {
-        return (io->flags & (PIO_F_EOF)) ? 1 : 0;
-    }
-    return 1;
-}
-
-/*
-
-=item C<INTVAL PIO_puts>
-
-Writes C<*s> tp C<*pmc>. C string version.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_puts(PARROT_INTERP, ARGMOD(PMC *pmc), ARGIN(const char *s))
-{
-    return PIO_write(interp, pmc, s, strlen(s));
-}
-
-/*
-
-=item C<INTVAL PIO_putps>
-
-Writes C<*s> to C<*pmc>. Parrot string version.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_putps(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD_NULLOK(STRING *s))
-{
-    ParrotIOLayer * const l  = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO      * const io = (ParrotIO *)PMC_data0(pmc);
-
-    if (PMC_IS_NULL(pmc)
-    || !VTABLE_isa(interp, pmc, CONST_STRING(interp, "ParrotIO")))
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-            "Cannot put to non-PIO PMC");
-
-    if (!io)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-            "Cannot put to a closed PIO handle");
-
-    if (!s)
-        return 0;
-#if ! DISABLE_GC_DEBUG
-    /* trigger GC for debug - but not during tests */
-    if (0 && GC_DEBUG(interp))
-        Parrot_do_dod_run(interp, GC_trace_stack_FLAG);
-#endif
-    return PIO_write_down(interp, l, io, s);
-}
-
-/*
-
-=item C<INTVAL PIO_fprintf>
-
-Writes a C string format with varargs to C<*pmc>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_fprintf(PARROT_INTERP, ARGMOD(PMC *pmc), ARGIN(const char *s), ...)
-{
-    va_list args;
-    INTVAL ret;
-
-    va_start(args, s);
-
-    ret=PIO_putps(interp, pmc, Parrot_vsprintf_c(interp, s, args));
-
-    va_end(args);
-
-    return ret;
-}
-
-/*
-
-=item C<INTVAL PIO_printf>
-
-Writes a C string format with varargs to C<stdout>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-PIO_printf(PARROT_INTERP, ARGIN(const char *s), ...)
-{
-    va_list args;
-    INTVAL ret;
-
-    va_start(args, s);
-
-    if (interp) {
-        STRING * const str = Parrot_vsprintf_c(interp, s, args);
-        ret=PIO_putps(interp, _PIO_STDOUT(interp), str);
-    }
-    else {
-        /* Be nice about this...
-         **   XXX BD Should this use the default PIO_STDOUT or something?
-         */
-        ret=vfprintf(stdout, s, args);
-    }
-
-    va_end(args);
-
-    return ret;
-}
-
-/*
-
-=item C<INTVAL PIO_eprintf>
-
-Writes a C string format with varargs to C<stderr>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_IGNORABLE_RESULT
-INTVAL
-PIO_eprintf(NULLOK(PARROT_INTERP), ARGIN(const char *s), ...)
-{
-    va_list args;
-    INTVAL ret;
-
-    va_start(args, s);
-
-    if (interp) {
-        STRING * const str = Parrot_vsprintf_c(interp, s, args);
-
-        ret=PIO_putps(interp, _PIO_STDERR(interp), str);
-    }
-    else {
-        /* Be nice about this...
-        **   XXX BD Should this use the default PIO_STDERR or something?
-        */
-        ret=vfprintf(stderr, s, args);
-    }
-
-    va_end(args);
-
-    return ret;
-}
-
-/*
-
-=item C<PIOHANDLE PIO_getfd>
-
-Returns C<*pmc>'s file descriptor, or C<0> if it is not defined.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PIOHANDLE
-PIO_getfd(SHIM_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIO * const io = (ParrotIO *)PMC_data0(pmc);
-
-    if (io)
-        return io->fd;
-
-    return (PIOHANDLE)0;        /* XXX that's plain wrong --leo */
-}
-
-/*
-
-=back
-
-=head2 C<PIO_STD*> Functions
-
-=over 4
-
-=item C<PMC * PIO_STDIN>
-
-Returns the C<ParrotIO> PMC for C<stdin>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-PIO_STDIN(PARROT_INTERP)
-{
-    return _PIO_STDIN(interp);
-}
-
-/*
-
-=item C<PMC * PIO_STDOUT>
-
-Returns the C<ParrotIO> PMC for C<stdout>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-PIO_STDOUT(PARROT_INTERP)
-{
-    return _PIO_STDOUT(interp);
-}
-
-/*
-
-=item C<PMC * PIO_STDERR>
-
-Returns the C<ParrotIO> PMC for C<stderr>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC *
-PIO_STDERR(PARROT_INTERP)
-{
-    return _PIO_STDERR(interp);
-}
-
-/*
-
-=back
-
-=head2 DOD-related Functions
-
-=over 4
-
-=item C<void Parrot_IOData_mark>
-
-Called from C<trace_active_PMCs()> to mark the IO data live.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_IOData_mark(PARROT_INTERP, ARGIN(ParrotIOData *piodata))
-{
-    INTVAL i;
-    ParrotIOTable table = piodata->table;
-
-    /* this was i < PIO_NR_OPEN, but only standard handles 0..2 need
-     * to be kept alive AFAIK -leo
-     */
-    for (i = 0; i < 3; i++) {
-        if (table[i]) {
-            pobject_lives(interp, (PObj *)table[i]);
-        }
-    }
-}
-
-/*
-
-=back
-
-=head2 Offset Functions
-
-These are used to create offsets for the C<seek> op.
+=head2 Networking Functions
 
 =over 4
 
-=item C<PIOOFF_T PIO_make_offset>
-
-Returns C<offset>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PIOOFF_T
-PIO_make_offset(INTVAL offset)
-{
-    return offset;
-}
-
-/*
-
-=item C<PIOOFF_T PIO_make_offset32>
-
-C<hi> is shifted 32 bytes to the left and C<or>ed together with C<lo>.
-This allows 64-bit seeks with only 32-bit C<INTVALS>.
-
 =cut
 
 */
 
-PIOOFF_T
-PIO_make_offset32(INTVAL hi, INTVAL lo)
-{
-    return ((PIOOFF_T)hi << 31) | lo;
-}
-
-/*
-
-=item C<PIOOFF_T PIO_make_offset_pmc>
-
-Returns the return value of the C<get_integer> vtable method on C<*pmc>.
-
-=cut
+#include "parrot/parrot.h"
+#include "io_private.h"
+#include "io.str"
 
-*/
+#include <stdarg.h>
 
-PIOOFF_T
-PIO_make_offset_pmc(PARROT_INTERP, ARGMOD(PMC *pmc))
-{
-    /* XXX: Maybe use bignums here */
-    return VTABLE_get_integer(interp, pmc);
-}
+/* HEADERIZER HFILE: include/parrot/io.h */
 
 /*
 
 =back
 
-=head2 Networking Functions
 
 =over 4
 
-=item C<INTVAL PIO_poll>
+=item C<INTVAL Parrot_io_poll>
 
 Polls C<*pmc> for the events in C<which> every C<sec> seconds + C<usec>
 microseconds.
@@ -1353,23 +44,18 @@
 
 PARROT_EXPORT
 INTVAL
-PIO_poll(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL which, INTVAL sec, INTVAL 
usec)
+Parrot_io_poll(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL which, INTVAL sec, 
INTVAL usec)
 {
-    ParrotIOLayer *l;
-    ParrotIO      *io;
-
     if (PMC_IS_NULL(pmc))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Can't poll NULL pmc");
+            "Can't poll a NULL socket object");
 
-    l  = (ParrotIOLayer *)PMC_struct_val(pmc);
-    io = (ParrotIO *)PMC_data0(pmc);
-    return PIO_poll_down(interp, l, io, which, sec, usec);
+    return PIO_POLL(interp, pmc, which, sec, usec);
 }
 
 /*
 
-=item C<PMC * PIO_socket>
+=item C<PMC * Parrot_io_socket>
 
 Creates and returns a socket using the specified address family, socket type,
 and protocol number. Check the returned PMC with a boolean test to see whether
@@ -1383,21 +69,15 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PMC *
-PIO_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto)
+Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto)
 {
     ParrotIOLayer * const l = interp->piodata->default_stack;
-    ParrotIO * const io = PIO_socket_down(interp, l, fam, type, proto);
-    /* We have to create a PMC here even if the IO handle
-     * didn't create because caller has to be able to
-     * check with a bool test. Can't use a NULL PMC in a bool
-     * test as that will cause an exception.
-     */
-    return new_io_pmc(interp, io);
+    return PIO_NEW_SOCKET(interp, l, fam, type, proto);
 }
 
 /*
 
-=item C<INTVAL PIO_recv>
+=item C<INTVAL Parrot_io_recv>
 
 Receives a message from the connected socket C<*pmc> in C<*buf>.  Returns C<-1>
 if it fails.
@@ -1408,19 +88,17 @@
 
 PARROT_EXPORT
 INTVAL
-PIO_recv(PARROT_INTERP, ARGMOD(PMC *pmc), ARGOUT(STRING **buf))
+Parrot_io_recv(PARROT_INTERP, ARGMOD(PMC *pmc), ARGOUT(STRING **buf))
 {
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
-    if (!io)
+    if (Parrot_io_socket_is_closed(pmc))
         return -1;
 
-    return PIO_recv_down(interp, l, io, buf);
+    return PIO_RECV(interp, pmc, buf);
 }
 
 /*
 
-=item C<INTVAL PIO_send>
+=item C<INTVAL Parrot_io_send>
 
 Sends the message C<*buf> to the connected socket C<*pmc>.  Returns
 C<-1> if it cannot send the message.
@@ -1432,19 +110,17 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-PIO_send(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *buf))
+Parrot_io_send(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *buf))
 {
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
-    if (!io)
+    if (Parrot_io_socket_is_closed(pmc))
         return -1;
 
-    return PIO_send_down(interp, l, io, buf);
+    return PIO_SEND(interp, pmc, buf);
 }
 
 /*
 
-=item C<INTVAL PIO_connect>
+=item C<INTVAL Parrot_io_connect>
 
 Connects C<*pmc> to C<*address>.  Returns C<-1> on failure.
 
@@ -1454,19 +130,17 @@
 
 PARROT_EXPORT
 INTVAL
-PIO_connect(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *address))
+Parrot_io_connect(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *address))
 {
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
-    if (!io)
+    if (Parrot_io_socket_is_closed(pmc))
         return -1;
 
-    return PIO_connect_down(interp, l, io, address);
+    return PIO_CONNECT(interp, pmc, address);
 }
 
 /*
 
-=item C<INTVAL PIO_bind>
+=item C<INTVAL Parrot_io_bind>
 
 Binds C<*pmc>'s socket to the local address and port specified by
 C<*address>.  Returns C<-1> on failure.
@@ -1477,19 +151,17 @@
 
 PARROT_EXPORT
 INTVAL
-PIO_bind(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *address))
+Parrot_io_bind(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *address))
 {
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
-    if (!io)
+    if (Parrot_io_socket_is_closed(pmc))
         return -1;
 
-    return PIO_bind_down(interp, l, io, address);
+    return PIO_BIND(interp, address);
 }
 
 /*
 
-=item C<INTVAL PIO_listen>
+=item C<INTVAL Parrot_io_listen>
 
 Listens for new connections on socket C<*pmc>.  Returns C<-1> on failure.
 
@@ -1500,19 +172,17 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-PIO_listen(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL backlog)
+Parrot_io_listen(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL backlog)
 {
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
-    if (!io)
+    if (Parrot_io_socket_is_closed(pmc))
         return -1;
 
-    return PIO_listen_down(interp, l, io, backlog);
+    return PIO_LISTEN(interp, pmc, backlog);
 }
 
 /*
 
-=item C<PMC * PIO_accept>
+=item C<PMC * Parrot_io_accept>
 
 Accepts a new connection and returns a newly created C<ParrotIO> socket.
 Returns C<NULL> on failure.
@@ -1525,41 +195,13 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 PMC *
-PIO_accept(PARROT_INTERP, ARGMOD(PMC *pmc))
-{
-    ParrotIO *io2;
-    ParrotIOLayer * const l = (ParrotIOLayer *)PMC_struct_val(pmc);
-    ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
-
-    /* XXX - return NULL or -1 -- c (02 July 2006) */
-    if (!io)
-        return NULL;
-
-    io2 = PIO_accept_down(interp, l, io);
-    return new_io_pmc(interp, io2);
-}
-
-/*
-
-=item C<INTVAL PIO_isatty>
-
-Returns a boolean value indicating whether C<*pmc> is a console/tty.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-INTVAL
-PIO_isatty(SHIM_INTERP, ARGMOD(PMC *pmc))
+Parrot_io_accept(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
-    const ParrotIO * const io = (ParrotIO *)PMC_data(pmc);
 
-    if (!io)
-        return 0;
+    if (Parrot_io_socket_is_closed(pmc))
+        return -1;
 
-    return (io->flags & PIO_F_CONSOLE) ? 1 : 0;
+    return PIO_ACCEPT(interp, l, io);
 }
 
 /*
@@ -1568,25 +210,7 @@
 
 =head1 SEE ALSO
 
-F<io/io_buf.c>,
-F<io/io_passdown.c>,
-F<io/io_stdio.c>,
-F<io/io_unix.c>,
-F<io/io_win32.c>,
-F<io/io_private.h>.
-
-=head1 HISTORY
-
-Initially written by Melvin Smith.
-
-Some ideas and goals from Perl 5.7 and Nick Ing-Simmons' work.
-
-=head1 TODO
-
-Rework to use copy-on-write IO stacks rather than creating a new stack for each
-IO stream.
-
-Add support for loadable layers in Parrot bytecode.
+F<io/api.c>
 
 =cut
 

Reply via email to