<[EMAIL PROTECTED]> writes:
>Hi Nick,
>
>my name is Doug Brann, and you don't know me. I'm sorry to be mailing this to
>you directly, but I've tried posting to the perl-xs newsgroup several times
>without success. It's the first time I've ever tried posting to a newsgroup, so
>I don't know if there is some problem with the news server, or the idiot trying
>to post (me, that is). If you don't have the time to answer this, if you would
>please forward it to the newsgroup, I'd be grateful.
>
>Anyhow, here's my problem:
>
>I have a perl script that is doing something like:
>
>%data = &Reader::new("file");

You are only passing "file" and not the class.
Did you mean:

%data = Reader->new("file");

>
>foreach (keys %data) {
>  print ("$_ is of type $data{$_});
>}
>
>in the foreach block, the response is UNKNOWN, when I'm hoping it will say
>ARRAY. 

There are syntax errors in that - at least a missing ".

>It I get the hash key out, but not the correct array type. When I try to
>access the array, I get fatal errors in the script.
>
>Here's a chunk of the offending xs code:
>
>void
>new (CLASS, filename)
> char *CLASS
> char *filename
>PREINIT
> AV *data = NULL;
> SV *sv = NULL;
> double *data_ptr;
> unsigned int count;
> unsigned int size;
> FILE = *file;
> char name[1024]; /* name is only 1023 long */
> unsigned int i;
>PPCODE:
> if((file=fopen(filename, "rb")) == NULL) {

As you declared this as taking two args (CLASS and filename) 
and only passed one I would expect this to fail.

>   printf("couldn't open %s\n", filename);
>   XSRETURN_UNDEF;

You would probably be better off with 
    XSRETURN(0); // return empty list

Otherwise you have done 

   %data = (undef);

> }
>
> count = 0;
> name[1023] = '\0'; /*need a null terminator */
> done = 0;
> while (feof(file)){

Surely you mean while (!feof(file)) ?

>  /* read in the name */
>  fread(&name, 1, 1023, file);

You could look at the count of items returned and 
use 0 items rather than :

>  if(feof(file)) {     // wrong sense again.
>   continue;
>  }
>  
>  /* now get the size */
>  fread(&size, 4, 1, file);

   fread(&size, sizeof(size), 1, file);  // would be safer.
>
>  /* get some memory and the data */
>  data_ptr = (double*)safemalloc(sizeof(double) * size);
>  if(data_ptr == NULL) {
>   printf("couldn't get memory");
>   XSRETURN_UNDEF;
>  }
>
>  fread (data_ptr, sizeof(double) * size, 1, file);

   fread(data_ptr, sizeof(double), size, file); // intended use of fread


>  data = (AV*) sv_2mortal((SV*)newAV());

   I don't think the AV should be mortal...

>  av_extend(data, size);
>
>  for (i = 0; i < size; i++)
>   /* boy I wish I could fread the data straight into */
>   /* an AV array without this step !! */

    // You could read it into a "pack-ed" string.

>   av_store(data, i newSVnv(data_ptr[i])); 
>  }
>
>  XPUSHs(sv_2mortal(newSVpv(name, 1024)));

I am unclear about the length there - is this a normal C string?

>  XPUSHs(sv_2mortal(newRV_noinc((SV*)data)));

The RV should be mortal, but as AV is as well, the AV will be 
freed from under it...


>  count++;
>  safefree(data_ptr);
> } /* while */
>
>XSRETURN(count *2);
>
>
>Can you help me? I've looked in the archives of the newsgroup and found a
>similar problem, and tried duplicating the code, to no avail.

The XS/perl parts look okay. It is your use of stdio that is 
dodgy.

>
>specifically I read "Adding an array as a hash entry - Cloutier, Christian
>Date: 05-29-03 11:07" 
>
>Thanks in advance for any help you can give.
>
>-Doug Brann
>
>
>
>
>
>------------------------------------------------------------
>This email was sent from Netspace Webmail: http://www.netspace.net.au

Reply via email to