view th_ioctx.c @ 184:b256db93cf25

Initial import of th_file module.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 20 Jan 2016 16:40:05 +0200
parents 28fd04f43a95
children b392293047da
line wrap: on
line source

/*
 * Standard I/O context helpers
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2012 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */
#include "th_ioctx.h"
#include "th_string.h"

/* Simple STD I/O contexts
 */
BOOL th_ioctx_init(th_ioctx_t *ctx, const char *filename,
    void (*error)(struct _th_ioctx_t *, const int, const char *msg),
    void (*msg)(struct _th_ioctx_t *, const char *msg))

{
    if (ctx == NULL || filename == NULL)
        return FALSE;

    memset(ctx, 0, sizeof(*ctx));
    ctx->error = error;
    ctx->msg   = msg;
    ctx->line  = 1;

    if ((ctx->filename = th_strdup(filename)) == NULL)
        return FALSE;
    
    return TRUE;
}


BOOL th_ioctx_open(th_ioctx_t *ctx, const char *filename, const char *mode,
    void (*error)(struct _th_ioctx_t *, const int, const char *msg),
    void (*msg)(struct _th_ioctx_t *, const char *msg))
{
    if (!th_ioctx_init(ctx, filename, error, msg) || mode == NULL)
        return FALSE;

    if ((ctx->fp = fopen(filename, mode)) == NULL)
        return FALSE;

    return TRUE;
}


void th_ioctx_close(th_ioctx_t *ctx)
{
    if (ctx != NULL)
    {
        th_free(ctx->filename);
        ctx->filename = NULL;

        if (ctx->fp != NULL)
            fclose(ctx->fp);
        ctx->fp = NULL;
    }
}


void th_ioctx_error(th_ioctx_t *ctx, const int err, const char *fmt, ...)
{
    char *msg;
    va_list ap;

    va_start(ap, fmt);
    msg = th_strdup_vprintf(fmt, ap);
    va_end(ap);

    if (ctx->error != NULL)
        ctx->error(ctx, err, msg);
    else
        THERR("'%s' #%" TH_PRIu_SIZE_T ": %s\n", ctx->filename, ctx->line, msg);

    th_free(msg);
}


th_ioctx_t *th_ioctx_new(const char *filename,
    void (*error)(struct _th_ioctx_t *, const int, const char *msg),
    void (*msg)(struct _th_ioctx_t *, const char *msg))
{
    th_ioctx_t *ctx = th_malloc0(sizeof(th_ioctx_t));
    if (ctx == NULL)
        return NULL;
    
    th_ioctx_init(ctx, filename, error, msg);
    ctx->allocated = TRUE;
    return ctx;
}


void th_ioctx_free(th_ioctx_t *ctx)
{
    th_ioctx_close(ctx);

    if (ctx->allocated)
        th_free(ctx);
}