/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* ** Copyright (c) 2013 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** This file implements the i/o-related parts of the library. */ #include "fossil-scm/fossil-internal.h" #include <assert.h> #include <errno.h> /* Only for debugging */ #include <stdio.h> #define MARKER(pfexp) \ do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \ printf pfexp; \ } while(0) /** ** fsl_appendf_f() impl which sends its output to fsl_output(). state ** must be a (fsl_cx*). */ static fsl_int_t fsl_appendf_f_fsl_output( void * state, char const * s, fsl_int_t n ){ return fsl_output( (fsl_cx *)state, s, (fsl_size_t)n ) ? -1 : n; } int fsl_outputfv( fsl_cx * f, char const * fmt, va_list args ){ if(!f || !fmt) return FSL_RC_MISUSE; else if(!*fmt) return FSL_RC_RANGE; else{ long const prc = fsl_appendfv( fsl_appendf_f_fsl_output, f, fmt, args ); return (prc>=0) ? 0 : FSL_RC_IO; } } int fsl_outputf( fsl_cx * f, char const * fmt, ... ){ if(!f || !fmt) return FSL_RC_MISUSE; else if(!*fmt) return FSL_RC_RANGE; else{ int rc; va_list args; va_start(args,fmt); rc = fsl_outputfv( f, fmt, args ); va_end(args); return rc; } } int fsl_output( fsl_cx * cx, void const * src, fsl_size_t n ){ if(!cx || !src) return FSL_RC_MISUSE; else if(!n || !cx->output.out) return 0; else return cx->output.out( cx->output.state.state, src, n ); } int fsl_flush( fsl_cx * f ){ return f ? (f->output.flush ? f->output.flush(f->output.state.state) : 0) : FSL_RC_MISUSE; } int fsl_flush_f_FILE(void * _FILE){ return _FILE ? (fflush((FILE*)_FILE) ? fsl_errno_to_rc(errno, FSL_RC_IO) : 0) : FSL_RC_MISUSE; } int fsl_output_f_FILE( void * state, void const * src, fsl_size_t n ){ return !state ? FSL_RC_MISUSE : ((1 == fwrite(src, n, 1, state ? (FILE*)state : stdout)) ? 0 : FSL_RC_IO); } int fsl_input_f_FILE( void * state, void * dest, fsl_size_t * n ){ FILE * f = (FILE*) state; if( !state || !dest || !n ) return FSL_RC_MISUSE; else if( !*n ) return FSL_RC_RANGE; *n = (fsl_size_t)fread( dest, 1, *n, f ); return *n ? 0 : (feof(f) ? 0 : FSL_RC_IO); } void fsl_finalizer_f_FILE( void * state, void * mem ){ if(mem){ fsl_fclose((FILE*)mem); } } #undef MARKER