Previous: R Functions, Up: Reference

4.2 C Structures

Below are the definitions for struct Rconn and struct fileconn copied from src/include/Rconnections.h. Additional comments by this author are inserted between special delimiters of the form /** comment **/.

struct Rconn {
    /** class name (null terminated) **/
    char* class;

    /** description (null terminated), can be a filename, url, or other 
        identifier, depending on the connection type 
    char* description;
    int enc; /* the encoding of 'description' */

    /** file operation mode (null terminated) **/
    char mode[5];

    /** text       - true if connection operates on text
        isopen     - true if connection is open
        incomplete - used in @code{do_readLines}, @code{do_isincomplete}, 
                     and text_vfprintf, From `?connections`: true if last 
                     read was blocked, or for an output text connection whether 
                     there is unflushed output
        canread    - true if connection is readable
        canwrite   - true if connection is writable
        canseek    - true if connection is seekable
        blocking   - true if connection reads are blocking
        isGzcon    - true if connection operates on gzip compressed data 
    Rboolean text, isopen, incomplete, canread, canwrite, canseek, blocking, 

    /** function pointers for I/O operations **/
    /** open - called when the connection should be opened
        args: struct Rconn * - an initialized connection to be opened
        return: Rboolean - true if connection successfully opened, false otherwise
    Rboolean (*open)(struct Rconn *);
    /** close - called when the connection should be closed
        args: struct Rconn * - a connection to be closed
    void (*close)(struct Rconn *); /* routine closing after auto open */
    /** destroy - called after the connection is closed in order to free memory, 
        and other cleanup tasks
        args: struct Rconn * - a connection to be closed
    void (*destroy)(struct Rconn *); /* when closing connection */
    /** vfprintf - variable argument list version of printf for a connection
        args: struct Rconn * - a connection where items should be printed
              const char *   - a format string in the style of the printf family
              va_list        - a variable argument list containing the items 
                               referred to in the format string
        return: int - number of characters printed, negative on failure
    int (*vfprintf)(struct Rconn *, const char *, va_list);
    /** fgetc - get a (re-encoded) character from the connection
        args: struct Rconn * - a connection to be read
        return: int - a (re-encoded) character, or R_EOF
    int (*fgetc)(struct Rconn *);
    /** fgetc_internal - get a character from the connection
        args: struct Rconn * - a connection to be read
        return: int - a character, or R_EOF
    int (*fgetc_internal)(struct Rconn *);
    /** seek - seek to a new position in the connection
        args: struct Rconn * - a connection to seek
              double         - offset to seek relative to origin, apparently 
                               double is used here to avoid using 
                               integer types, i.e. long int, which is 
                               the prototype of the corresponding parameter 
                               in fseek, as defined in stdio.h
              int            - the origin of seeking, 1 (and any except 2 and
                               3) if relative to the beginning of the 
                               connection, 2 if relative to the current 
                               connection read/write position, 3 if relative to 
                               the end of the connection
              int            - currently only used by file_seek to select 
                               the read or write position when the offset is NA
        return: double - the read/write position of the connection before 
                         seeking, negative on error double is again used to 
                         avoid integer types
    double (*seek)(struct Rconn *, double, int, int);
    /** truncate - truncate the connection at the current read/write position.
        args: struct Rconn * - a connection to be truncated
    void (*truncate)(struct Rconn *);
    /** fflush - called when the connection should flush internal read/write buffers
        args: struct Rconn * - a connection to be flushed
        return: int - zero on success, non-zero otherwise
    int (*fflush)(struct Rconn *);
    /** read - read in the style of fread
        args: void *         - buffer where data is read into
              size_t         - size (in bytes) of each item to be read
              size_t         - number of items to be read
              struct Rconn * - a connection to be read
        return: size_t - number of _items_ read
    size_t (*read)(void *, size_t, size_t, struct Rconn *);
    /** write - write in the style of fwrite
        args: void *         - buffer containing data to be written
              size_t         - size (in bytes) of each item to be written
              size_t         - number of items to be written
              struct Rconn * - a connection to be written
        return: size_t - number of _items_ written
    size_t (*write)(const void *, size_t, size_t, struct Rconn *);
    /** cached and pushBack data
        nPushBack   - number of lines of cached/pushBack storage
        posPushBack - read position on current line of storage
        PushBack    - cached/pushBack data lines ('\n' delimited)
        save        - used to store the character following a \n, if not \r
        save2       - used to store a character from Rconn_ungetc
    int nPushBack, posPushBack; /* number of lines, position on top line */
    char **PushBack;
    int save, save2;

    /** character re-encoding with iconv
        encname   - character encoding string (null terminated), this string 
                    must be one of the standard encoding strings used by [lib]iconv
        inconv    - input character encoding context (iconv_t)
        outconv   - output character encoding context (iconv_t)
        iconvbuff - input character encoding buffer
        oconvbuff - output character encoding buffer
        next      - only used by dummy_fgetc, points to the next re-encoded 
                    character for reading
        init_out  - storage for output iconv initialization sequence 
        navail    - iconv buffer offset
        inavail   - iconv buffer offset
        EOF_signalled - true if EOF reached
        UTF8out   - true if connection writes UTF8 encoded characters
    char encname[101];
    /* will be iconv_t, which is a pointer. NULL if not in use */
    void *inconv, *outconv;
    /* The idea here is that no MBCS char will ever not fit */
    char iconvbuff[25], oconvbuff[50], *next, init_out[25];
    short navail, inavail;
    Rboolean EOF_signalled;
    Rboolean UTF8out;

    /** finalization pointers
        id     - unique id, used to "ensure that the finalizer does not 
                 try to close connection after it is alread closed"
                 (quoted from source code), but also to identify the
                 connection to be finalized. Using an arbitrary but
                 unique id here is clever, it means the connections 
                 internals are further protected from passing references 
                 to connection structures.
        ex_ptr - external pointer, referenced by finalizer code
    void *id;
    void *ex_ptr;

    /** private user data (i.e. FILE *, offsets etc.) **/
    void *private;

typedef struct fileconn {
    /** stream pointer for file connection **/
    FILE *fp; 

    /** read/write offsets **/
#if defined(HAVE_OFF_T) && defined(HAVE_FSEEKO)
    off_t rpos, wpos;
#ifdef Win32
    off64_t rpos, wpos;
    long rpos, wpos;

    /** last_was_write - true if last file operation was write **/
    Rboolean last_was_write;

    /** raw - true if a raw file connection **/
    Rboolean raw; 

#ifdef Win32
    /** anon_file - true if file is temporary or 'anonymous' **/
    Rboolean anon_file;

    /** name - expanded filename of temporary file **/
    char name[PATH_MAX+1];
} *Rfileconn;