sdebug.c 3.22 KB
/* GNU mailutils - a suite of utilities for electronic mail
   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Library Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   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.  See the
   GNU Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <mailutils/sys/sdebug.h>
#include <mailutils/error.h>

int
_mu_debug_stream_ref (mu_debug_t debug)
{
  struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
  return mu_refcount_inc (sdebug->refcount);
}

void
_mu_debug_stream_destroy (mu_debug_t *pdebug)
{
  if (pdebug && *pdebug)
    {
      struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)*pdebug;
      if (mu_refcount_dec (sdebug->refcount) == 0)
	{
	  if (sdebug->stream)
	    {
	      if (sdebug->close_on_destroy)
		stream_close (sdebug->stream);
	      stream_destroy (&sdebug->stream);
	    }
	  mu_refcount_destroy (&sdebug->refcount);
	  free (sdebug);
	}
      *pdebug = NULL;
    }
}

int
_mu_debug_stream_set_level (mu_debug_t debug, size_t level)
{
  struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
  sdebug->level = level;
  return 0;
}

int
_mu_debug_stream_get_level (mu_debug_t debug, size_t *plevel)
{
  struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
  if (plevel)
    *plevel = sdebug->level;
  return 0;
}

int
_mu_debug_stream_print (mu_debug_t debug, size_t level, const char *mesg)
{
  struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
  size_t n = 0;
  int status;

  if (mesg == NULL)
    return MU_ERROR_INVALID_PARAMETER;

  if (!(sdebug->level & level))
    return 0;

  status =  stream_write (sdebug->stream, mesg, strlen (mesg), sdebug->offset,
			  &n);
  sdebug->offset += n;
  return status;
}

static struct _mu_debug_vtable _mu_debug_stream_vtable =
{
  _mu_debug_stream_ref,
  _mu_debug_stream_destroy,

  _mu_debug_stream_get_level,
  _mu_debug_stream_set_level,
  _mu_debug_stream_print
};

int
mu_debug_stream_create (mu_debug_t *pdebug, stream_t stream,
			int close_on_destroy)
{
  struct _mu_debug_stream *sdebug;

  if (pdebug == NULL || stream == NULL)
    return MU_ERROR_INVALID_PARAMETER;

  sdebug = calloc (sizeof (*sdebug), 1);
  if (sdebug == NULL)
    return MU_ERROR_NO_MEMORY;

  mu_refcount_create (&sdebug->refcount);
  if (sdebug->refcount == NULL)
    {
      free (sdebug);
      return MU_ERROR_NO_MEMORY;
    }

  sdebug->level = 0;
  sdebug->offset = 0;
  sdebug->stream = stream;
  sdebug->close_on_destroy = close_on_destroy;
  sdebug->base.vtable = &_mu_debug_stream_vtable;
  *pdebug = &sdebug->base;
  return 0;
}