[perl-Cairo] Add cairo_perl_sv_is_defined and cairo_perl_sv_is_ref



commit a2705b2b2a5565539a14cd3159c7e79dc6de117d
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Sun Aug 7 19:56:34 2011 +0200

    Add cairo_perl_sv_is_defined and cairo_perl_sv_is_ref

 Cairo.xs             |   38 ++++++++++++++++++++++++++++++++++++--
 cairo-perl-private.h |    8 +++++---
 2 files changed, 41 insertions(+), 5 deletions(-)
---
diff --git a/Cairo.xs b/Cairo.xs
index 3174f51..ac78b68 100644
--- a/Cairo.xs
+++ b/Cairo.xs
@@ -63,12 +63,46 @@ cairo_perl_set_isa (const char *child_package,
 	av_push (isa, newSVpv (parent_package, 0));
 }
 
+/* Copied from Glib/Glib.xs. */
+cairo_bool_t
+cairo_perl_sv_is_defined (SV *sv)
+{
+	/* This is adapted from PP(pp_defined) in perl's pp.c */
+
+	if (!sv || !SvANY(sv))
+		return FALSE;
+
+	switch (SvTYPE(sv)) {
+	    case SVt_PVAV:
+		if (AvMAX(sv) >= 0 || SvGMAGICAL(sv)
+		    || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
+			return TRUE;
+		break;
+	    case SVt_PVHV:
+		if (HvARRAY(sv) || SvGMAGICAL(sv)
+		    || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
+			return TRUE;
+		break;
+	    case SVt_PVCV:
+		if (CvROOT(sv) || CvXSUB(sv))
+			return TRUE;
+		break;
+	    default:
+		if (SvGMAGICAL(sv))
+			mg_get(sv);
+		if (SvOK(sv))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 /* ------------------------------------------------------------------------- */
 
 void *
 cairo_object_from_sv (SV *sv, const char *package)
 {
-	if (!SvOK (sv) || !SvROK (sv) || !sv_derived_from (sv, package))
+	if (!cairo_perl_sv_is_ref (sv) || !sv_derived_from (sv, package))
 		croak("Cannot convert scalar %p to an object of type %s",
 		      sv, package);
 	return INT2PTR (void *, SvIV ((SV *) SvRV (sv)));
@@ -87,7 +121,7 @@ cairo_object_to_sv (void *object, const char *package)
 void *
 cairo_struct_from_sv (SV *sv, const char *package)
 {
-	if (!SvOK (sv) || !SvROK (sv) || !sv_derived_from (sv, package))
+	if (!cairo_perl_sv_is_ref (sv) || !sv_derived_from (sv, package))
 		croak("Cannot convert scalar %p to a struct of type %s",
 		      sv, package);
 	return INT2PTR (void *, SvIV ((SV *) SvRV (sv)));
diff --git a/cairo-perl-private.h b/cairo-perl-private.h
index 622d59c..dc8f759 100644
--- a/cairo-perl-private.h
+++ b/cairo-perl-private.h
@@ -33,10 +33,12 @@ const char * cairo_perl_package_table_lookup (void *pointer);
 		croak (Nullch);					\
 	}
 
+cairo_bool_t cairo_perl_sv_is_defined (SV *sv);
+#define cairo_perl_sv_is_ref(sv) \
+	(cairo_perl_sv_is_defined (sv) && SvROK (sv))
 #define cairo_perl_sv_is_array_ref(sv) \
-	(SvOK (sv) && SvROK (sv) && SvTYPE (SvRV(sv)) == SVt_PVAV)
-
+	(cairo_perl_sv_is_ref (sv) && SvTYPE (SvRV(sv)) == SVt_PVAV)
 #define cairo_perl_sv_is_hash_ref(sv) \
-	(SvOK (sv) && SvROK (sv) && SvTYPE (SvRV(sv)) == SVt_PVHV)
+	(cairo_perl_sv_is_ref (sv) && SvTYPE (SvRV(sv)) == SVt_PVHV)
 
 #endif /* _CAIRO_PERL_PRIVATE_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]