/*
* Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
* Copyright (c) 2013-2016 Carbonite, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information: Carbonite Inc., 756 N Pastoria Ave
* Sunnyvale, CA 94085, or: http://www.zmanda.com
*/
#ifndef AMANDA_AMGLUE_H
#define AMANDA_AMGLUE_H
#include "../config/config.h"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <glib.h>
#include <glib-object.h>
/* These defines are missing from older glibs, so we add them here */
#ifndef G_MAXINT8
#define G_MAXINT8 (127)
#endif
#ifndef G_MININT8
#define G_MININT8 (-127-1)
#endif
#ifndef G_MAXUINT8
#define G_MAXUINT8 (255)
#endif
#ifndef G_MAXINT16
#define G_MAXINT16 (32767)
#endif
#ifndef G_MININT16
#define G_MININT16 (-32767-1)
#endif
#ifndef G_MAXUINT16
#define G_MAXUINT16 (65535)
#endif
#ifndef G_MAXINT32
#define G_MAXINT32 (2147483647)
#endif
#ifndef G_MININT32
#define G_MININT32 (-2147483647-1)
#endif
#ifndef G_MAXUINT32
#define G_MAXUINT32 (4294967295U)
#endif
/*
* prototypes for ghashtable.c
*/
/* Turn a GLib hash table (mapping strings to strings) into a reference
* to a Perl hash table.
*
* @param hash: GLib hash table
* @returns: Perl hashref
*/
SV *g_hash_table_to_hashref(GHashTable *hash);
/* Turn a GLib hash table (mapping strings to GSList of strings) into a reference
* to a Perl hash table.
*
* @param hash: GLib hash table
* @returns: Perl hashref
*/
SV *g_hash_table_to_hashref_gslist(GHashTable *hash);
/* Turn a GLib hash table (mapping strings to property_t) into a reference
* to a Perl hash table.
*
* @param hash: GLib hash table
* @returns: Perl hashref
*/
SV *g_hash_table_to_hashref_property(GHashTable *hash);
/*
* prototypes for gerror.c
*/
/* Call perl's croak (die) for a GError (if there is one)
*
* @note This is not thread-safe
* @note This function does not return if error is non-NULL
*
* @param domain: String to prefix to error message (followed by ": ")
* @param error: The GError pointer
*/
void croak_gerror(const char *domain, GError **error);
/*
* prototypes for bigint.c
*/
/*
* These functions handle conversion of integers to and from Perl-compatible
* values. Most perls do not natively support 64-bit integers, so these functions
* interface with the Math::BigInt module to support those integers. The functions
* also handle conversions from floating-point to integer values, with silent fraction
* truncation, as perl automatically promotes integers to doubles on overflow.
*/
/* Convert an (unsigned) integer to a Perl SV. These will always produce a
* Math::BigInt object. Any failure is fatal. *All* C-to-Perl integer conversions
* must use these functions.
*
* NOTE - NOTE - NOTE
*
* Due to the way SWIG constructs return values, *any* outgoing typemap (out or
* argout) must use the following syntax:
* SP += argvi; PUTBACK;
* $result = sv_2mortal(amglue_newSVi64(...));
* SPAGAIN; SP -= argvi; argvi++;
* This has the effect of saving the arguments added to the perl stack so far, by
* setting the global perl stack to a point above them.
*
* @param v: value to convert
* @returns: pointer to a new SV (refcount=1)
*/
SV *amglue_newSVi64(gint64 v);
SV *amglue_newSVu64(guint64 v);
/* Convert a Perl SV to an integer of the specified size. These functions should
* be used for *all* Perl-to-C integer conversions, since the Perl value may be a
* Math::BigInt object. All of these functions will call croak() on an overflow
* condition, rather than silently truncate.
*
* @param sv: perl value to convert
* @returns: value of the given type
*/
gint64 amglue_SvI64(SV *sv, gchar **err);
guint64 amglue_SvU64(SV *sv, gchar **err);
gint32 amglue_SvI32(SV *sv, gchar **err);
guint32 amglue_SvU32(SV *sv, gchar **err);
gint16 amglue_SvI16(SV *sv, gchar **err);
guint16 amglue_SvU16(SV *sv, gchar **err);
gint8 amglue_SvI8(SV *sv, gchar **err);
guint8 amglue_SvU8(SV *sv, gchar **err);
/*
* prototypes for objwrap.c
*/
/* Return a new SV with refcount 1 representing the given C object
* with the given class.
*
* @param c_obj: the object to represent
* @param perl_class: the perl with which to bless and tie the SV
*/
SV * new_sv_for_c_obj(gpointer c_obj, const char *perl_class);
/* Return the C object buried in an SV, asserting that the perl SV is
* derived from derived_from. Returns NULL for undefined perl values.
*
* This function is based on SWIG's SWIG_Perl_ConvertPtr. The INT2PTR
* situation certainly looks strange, but is documented in perlxs.
*
* @param sv: the SV to convert
* @param derived_from: perl class from which the SV should be derived
* @return: underlying pointer
*/
gpointer c_obj_from_sv(SV *sv, const char *derived_from);
/*
* prototypes for xferwrap.c
*/
/* declare structs */
struct Xfer;
struct XferElement;
/* Return a new SV representing a transfer.
*
* @param xfer: the transfer to represent
*/
SV *new_sv_for_xfer(struct Xfer *xfer);
/* Return a new SV representing a transfer element.
*
* @param xe: the transfer element to represent
*/
SV *new_sv_for_xfer_element(struct XferElement *xe);
/* Convert an SV to an Xfer. The Xfer's reference count is not
* incremented -- this is a "borrowed" reference.
*
* @param sv: the perl value
* @returns: pointer to the corresponding transfer, or NULL
*/
struct Xfer *xfer_from_sv(SV *sv);
/* Convert an SV to an XferElement. The element's reference count is
* not incremented -- this is a "borrowed" reference.
*
* @param sv: the perl value
* @returns: pointer to the corresponding transfer element, or NULL.
*/
struct XferElement *xfer_element_from_sv(SV *sv);
/*
* prototypes for source.c
*/
typedef enum amglue_Source_state {
AMGLUE_SOURCE_NEW,
AMGLUE_SOURCE_ATTACHED,
AMGLUE_SOURCE_DESTROYED
} amglue_Source_state;
/* There is *one* amglue_Source object for each GSource; this
* allows us to attach amglue-related information to the
* GSource. See amglue/source.c for more detail. */
typedef struct amglue_Source {
GSource *src;
GSourceFunc callback;
gint refcount;
amglue_Source_state state;
SV *callback_sv;
} amglue_Source;
/* Get the amglue_Source object associated with this GSource, creating a
* new one if necessary, and increment its refcount.
*
* The 'callback' parameter should be a C function with the
* appropriate signature for this GSource. The callback will
* be given the amglue_Source as its 'data' argument, and should
* invoke its callback_sv as a Perl sub with the appropriate
* parameters. Simple GSources can use amglue_source_callback_simple,
* below.
*
* This amglue_Source object can be returned directly to perl via a
* SWIG binding; it will be bound as an Amanda::MainLoop::Source
* object, and its memory management will be handled correctly.
*
* @param gsrc: the GSource object to wrap
* @param callback: function to trigger a perl callback
* @returns: an amglue_Source with appropriate refcount
*/
amglue_Source *amglue_source_get(GSource *gsrc, GSourceFunc callback);
/* Create a new amglue_Source object for this GSource. Use this when
* the GSource was just created and does not yet have a corresponding
* amglue_Source.
*
* @param gsrc: the GSource object to wrap
* @param callback: function to trigger a perl callback
* @returns: an amglue_Source with appropriate refcount
*/
amglue_Source *amglue_source_new(GSource *gsrc, GSourceFunc callback);
/* Increment the refcount on an amglue_Source */
#define amglue_source_ref(aS) aS->refcount++
/* Unref an amglue_Source object, freeing it if its refcount reaches
* zero. */
#define amglue_source_unref(aS) if (!--(aS)->refcount) amglue_source_free((aS))
void amglue_source_free(amglue_Source *);
#endif /* AMANDA_AMGLUE_H */