Steve Hay <[EMAIL PROTECTED]> writes:
>Nick Ing-Simmons wrote:
>>If you use the MAGIC * as the "signature" it can't fail ;-)
>>
>An excellent idea.
>
>So attached is hopefully my final take.

Which looks fine - I see there is another mail though so will 
study that.

>
>Using sv_magic(), I've dropped the re-use of the SV in the 2nd arg since 
>(a) I couldn't pull that trick if I actually wanted to use mg_obj for 
>something else and (b) the subsequent mg_find() call is always 
>_immediately_ after sv_magic() anyway so no other magic could have been 
>added.  the MAGIC * is then stored within the struct itself.  Later on 
>(and possibly in another part of the code, when mg_find() wouldn't be 
>"safe"), the pointer stored with the struct is used to verify that the 
>correct MAGIC * was found.
>
>Using sv_magicext() is even easier since it returns the MAGIC * for us.
>
>Thanks (once again!) for your help.
>
>- Steve
>
>
>------------------------------------------------
>Radan Computational Ltd.
>
>The information contained in this message and any files transmitted with it are 
>confidential and intended for the addressee(s) only.  If you have received this 
>message in error or there are any problems, please notify the sender immediately.  
>The unauthorized use, disclosure, copying or alteration of this message is strictly 
>forbidden.  Note that any views or opinions presented in this email are solely those 
>of the author and do not necessarily represent those of Radan Computational Ltd.  The 
>recipient(s) of this message should check it and any attached files for viruses: 
>Radan Computational will accept no liability for any damage caused by any virus 
>transmitted by this email.
>#include "EXTERN.h"
>#include "perl.h"
>#include "XSUB.h"
>
>#include "ppport.h"
>
>typedef struct {
>  MAGIC *mg;
>  char *buf;
>} Foo;
>
>static Foo *FooAlloc(pTHX);
>static void FooFree(pTHX_ Foo *foo);
>static int MagicFooFree(pTHX_ SV *sv, MAGIC *mg);
>
>static MGVTBL Foo_vtbl = {
>  NULL,
>  NULL,
>  NULL,
>  NULL,
>  MagicFooFree
>};
>
>static Foo *FooAlloc(pTHX) {
>  Foo *foo;
>  Newz(0, foo, 1, Foo);
>  Newz(0, foo->buf, 1024, char);
>  strcpy(foo->buf, "Hello, world.");
>  return foo;
>}
>
>static void FooFree(pTHX_ Foo *foo) {
>  Safefree(foo->buf);
>  Safefree(foo);
>}
>
>static int MagicFooFree(pTHX_ SV *sv, MAGIC *mg) {
>  FooFree(aTHX_ (Foo *)mg->mg_ptr);
>  return 1;
>}
>
>MODULE = Foo           PACKAGE = Foo           
>
>void
>magicfoo()
>PPCODE:
>{
>  SV *sv;
>  Foo *foo;
>  MAGIC *mg;
>  // Initialise
>  foo = FooAlloc(aTHX);
>  sv = NEWSV(0, 0);
>  sv_magic(sv, NULL, PERL_MAGIC_ext, (char *)foo, 0);
>  // This mg_find() can't fail since we're doing it straight away.
>  if (!(mg = mg_find(sv, PERL_MAGIC_ext)))
>    croak("Can't find new magic");
>  foo->mg = mg;
>  mg->mg_virtual = &Foo_vtbl;
>  SvREADONLY_on(sv);
>  // Use it.  This could be much later in another function, so we
>  // need to check that mg_find() found the right magic.
>  if (!(mg = mg_find(sv, PERL_MAGIC_ext)))
>    croak("Can't find magic");
>  if (!(foo = (Foo *)(mg->mg_ptr)))
>    croak("Can't find magic pointer");
>  if (foo->mg != mg)
>    croak("Found wrong magic pointer");
>  //printf("%s\n", foo->buf);
>  // Clean up
>  SvREFCNT_dec(sv);
>}
>
>void
>magicextfoo()
>PPCODE:
>{
>  SV *sv;
>  Foo *foo;
>  MAGIC *mg;
>  // Initialise
>  foo = FooAlloc(aTHX);
>  sv = NEWSV(0, 0);
>  if (!(mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &Foo_vtbl, (char *)foo, 0)))
>    croak("Can't add magic");
>  foo->mg = mg;
>  SvREADONLY_on(sv);
>  // Use it.  This could be much later in another function, so we
>  // need to check that mg_find() found the right magic.
>  if (!(mg = mg_find(sv, PERL_MAGIC_ext)))
>    croak("Can't find magic");
>  if (!(foo = (Foo *)(mg->mg_ptr)))
>    croak("Can't find magic pointer");
>  if (foo->mg != mg)
>    croak("Found wrong magic pointer");
>  //printf("%s\n", foo->buf);
>  // Clean up
>  SvREFCNT_dec(sv);
>}

Reply via email to