This file is indexed.

/usr/lib/perl5/XS/Object/Magic.pm is in libxs-object-magic-perl 0.4-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
package XS::Object::Magic;

use strict;
use warnings;

require 5.008001;
use parent qw(DynaLoader);

our $VERSION = '0.04';
$VERSION = eval $VERSION;

sub dl_load_flags { 0x01 }

__PACKAGE__->bootstrap($VERSION);

__PACKAGE__

__END__

=pod

=head1 NAME

XS::Object::Magic - Opaque, extensible XS pointer backed objects using C<sv_magic>

=head1 SYNOPSIS

	package MyObject;

	use XS::Object::Magic;

	sub new {
		my $class = shift;

		# create any object representation you like
		my $self = bless {}, $class;

		$self->build_struct;

		return $self;
	}


	# or using Moose

	package MyObject;
	use Moose;

	sub BUILD {
		shift->build_struct;
	}


	# then in XS

	MODULE = MyObject  PACKAGE = MyObject

	void build_struct (SV *self)
		PREINIT:
			my_struct_t *thingy;
		CODE:
			thingy = create_whatever();

			/* note that we dereference self first. This
			 * can be done using an XS typemap of course */
			xs_object_magic_attach_struct(aTHX_ SvRV(self), thingy);


	void foo (SV *self)
		PREINIT:
			my_struct_t *thingy;
		INIT:
			thingy = xs_object_magic_get_struct_rv(aTHX_ self);
		CODE:
			my_struct_foo(thingy); /* delegate to C api */


	/* using typemap */
	void foo (my_struct_t *thingy)
		CODE:
			my_struct_foo(thingy);

	/* or better yet */
	PREFIX = my_struct_

	void
	my_struct_foo (thingy)
		my_struct_t *thingy;


	/* don't forget a destructor */
	void
	DESTROY (my_struct_t *thingy)
		CODE:
			Safefree(thingy);

			/* note that xs_object_magic_get_struct() will
			 * still return a pointe which is now invalid */


=head1 DESCRPTION

This way of associating structs with Perl space objects is designed to supercede
Perl's builtin C<T_PTROBJ> with something that is designed to be:

=over 4

=item Extensible

The association of the pointer using C<sv_magicext> can be done on any data
type, so you can associate C structs with any representation type.

This means that you can add pointers to any object (hand coded, L<Moose> or
otherwise), while still having instance data in regular hashes.

=item Opaque

The C pointer is neither visible nor modifiable from Perl space.

This prevents accidental corruption which could lead to segfaults using
C<T_PTROBJ> (e.g. C<$$ptr_obj = 0>).

=back

=head1 C API

=over 4

=item void *xs_object_magic_get_struct_rv(aTHX_ SV *sv)

When called on the object reference it will check that the C<sv> is a reference,
dereference it and return the associated pointer using
C<xs_object_magic_get_struct>.

Basically the same as C<xs_object_magic_get_struct(aTHX_ SvRV(sv)> but croaks
if no magic was found.

Note that storing a C<NULL> pointer will B<not> cause an error.

=item void *xs_object_magic_get_struct(aTHX_ SV *sv)

Fetches the pointer associated with C<sv>.

Returns C<NULL> if no pointer is found. There is no way to distinguish this
from having a C<NULL> pointer.

=item MAGIC *xs_object_magic_get_mg (aTHX_ SV *sv)

Fetches the appropriate C<MAGIC> entry for the struct pointer storage from
C<sv>.

This lets you manipulate C<mg->mg_ptr> if you need to.

=item void xs_object_magic_attach_struct(aTHX_  SV *sv, void *ptr)

Associates C<ptr> with C<sv> by adding a magic entry to C<sv>.

=item SV *xs_object_magic_create(aTHX_ void *ptr, HV *stash)

Convenience function that creates a hash object blessed to C<stash> and
associates it with C<ptr>.

Can be used to easily create a constructor:

	SV *
	new(char *class)
		CODE:
			RETVAL = xs_object_magic_create(
				(void *)test_new(),
				gv_stashpv(class, 0)
			);
		OUTPUT: RETVAL

=item int xs_object_magic_has_struct(aTHX_ SV *sv)

Returns 1 if the SV has XS::Object::Magic magic, 0 otherwise.

=item int xs_object_magic_has_struct_rv(aTHX_ SV *self)

Returns 1 if the SV references an SV that has XS::Object::Magic magic,
0 otherwise.

This lets you write a quick predicate method, like:

    void
    my_struct_has_struct (self)
            SV *self;
            PPCODE:
                    EXTEND(SP, 1);
                    if(xs_object_magic_has_struct_rv(aTHX_ self))
                            PUSHs(&PL_sv_yes);
                    else
                            PUSHs(&PL_sv_no);

Then you can check for the existence of your struct from the Perl
side:

    if( $object->has_struct ) { ... }

=item int xs_object_magic_detach_struct(aTHX_ SV *sv)

Removes the XS::Object::Magic magic from the given SV.  Returns 1 if
something is removed, 0 otherwise.

=item int xs_object_magic_detach_struct_rv(aTHX_ SV *self)

Likes C<xs_object_magic_detach_struct>, but takes a reference to the
magic-containing SV instead of the SV itself.  The reference to the SV
is typically C<$self>.

Returns 0 if the SV is not a reference, otherwise returns whatever
C<xs_object_magic_detach_struct> returns.

=back

=head1 TYPEMAP

The included typemap provides a C<T_PTROBJ_MG> entry which only supports the
C<INPUT> conversion.

This typemap entry lets you declare methods that are invoked directly on the
associated pointer. In your own typemap add an entry:

	TYPEMAP
	my_pointer_t *	T_PTROBJ_MG

and then you can use C<my_pointer_t> as the argument type of the invocant:

	I32
	method (self)
		my_pointer_t *self;
		CODE:
			...

Note that there is no C<OUTPUT> conversion. In order to return your object you
need to use C<ST(0)> or some other means of getting the invocant.

=head1 VERSION CONTROL

L<http://github.com/nothingmuch/xs-object-magic>

=head1 AUTHOR

Florian Ragwitz, Yuval Kogman

=head1 COPYRIGHT & LICENSE

	Copyright (c) 2009 Florian Ragwitz, Yuval Kogman. All rights reserved
	This program is free software; you can redistribute
	it and/or modify it under the same terms as Perl itself.

=cut