Commits

Anonymous committed cc62325

Added the array-from-scratch example.

Comments (0)

Files changed (4)

perl5/ext-embed-internals/docbook/examples/incremental-examples-1/XSTest/MANIFEST

 t/06-return-binary-string.t
 t/07-assign-string-to-ref.t
 t/09-assign-to-array.t
+t/10-array-from-scratch.t
 t/boilerplate.t
 t/lib/scripts/get-24-leak-test.pl
 t/lib/scripts/get-string-leak-test.pl

perl5/ext-embed-internals/docbook/examples/incremental-examples-1/XSTest/lib/XSTest.pm

 
 This function is meant to demonstrate assigning to array values using XS.
 
+=head2 $total = concat_two_array_refs(\@array1, \@array2);
+
+Equivalent to: C<< $total = [@array1, @array2]; >>
+
+This function is meant to demonstrate creating new array references and 
+populating them.
+
 =head1 AUTHOR
 
 Shlomi Fish, C<< <shlomif@iglu.org.il> >>

perl5/ext-embed-internals/docbook/examples/incremental-examples-1/XSTest/lib/XSTest.xs

                 }
             }
         }
+
+AV *
+concat_two_array_refs(array1, array2)
+    AV * array1
+    AV * array2
+
+    INIT:
+        /* Initialize RETVAL to NULL, so we'll know something is wrong
+         * if this indeed the case*/
+        RETVAL = NULL;
+
+    CODE:
+        {
+            AV * ret;
+            AV * current;
+            I32 max_index;
+            I32 i;
+            I32 array_idx;
+            SV * * elem;
+
+            /* av_make() accepts a size and a list of SV's. So this
+             * call creates a new array*/
+            ret = av_make(0, NULL);
+
+            if (ret == NULL)
+            {
+                goto myerror;
+            }
+
+            for(array_idx=0;array_idx<2;array_idx++)
+            {
+                current = (array_idx == 0) ? array1 : array2;
+
+                max_index = av_len(current);
+                for(i=0;i<=max_index;i++)
+                {
+                    elem = av_fetch(current, i, 0);
+                    if (elem == NULL)
+                    {
+                        av_push(ret, &PL_sv_undef);
+                    }
+                    else
+                    {
+                        /* Increment the reference count because we now
+                         * reference it in another place and av_push
+                         * does not do it for us.
+                         * 
+                         * This is a variation of SvREFCNT_inc which has
+                         * some limitations that don't matter here.
+                         * 
+                         * From the documentation (perldoc perlapi):
+                         *
+                         * SvREFCNT_inc_void_NN
+                               Same as SvREFCNT_inc, but can only be used if 
+                               you don't need the return value, and you know
+                               that sv is not NULL.  The macro doesn't need to
+                               return a meaningful value, or check for
+                               NULLness, so it's smaller and faster.
+                         * */
+
+                        SvREFCNT_inc_void_NN(*elem);
+                        av_push(ret, *elem);
+                    }
+                }
+            }
+
+            myerror:
+            RETVAL = ret;
+        }
+    OUTPUT:
+        RETVAL

perl5/ext-embed-internals/docbook/examples/incremental-examples-1/XSTest/t/10-array-from-scratch.t

+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+use XSTest;
+
+{
+    my @array1 = (0, 1, 200, 33);
+    my @array2 = (4004, 50);
+
+    my $combined = XSTest::concat_two_array_refs(\@array1, \@array2);
+    # TEST
+    is_deeply(
+        $combined,
+        [0, 1, 200, 33, 4004, 50],
+        "concat_two_array_refs - 1"
+    );
+}
+
+{
+    my $combined;
+
+    {
+        my @array1 = ("Hon", "Ton", "Gorgon");
+        my @array2 = ("Look", "Mook", "Crook");
+
+        $combined = XSTest::concat_two_array_refs(\@array1, \@array2);
+    }
+
+    # TEST
+    is_deeply(
+        $combined,
+        [qw(Hon Ton Gorgon Look Mook Crook)],
+        "concat_two_array_refs - original go out of scope"
+    );
+}