<[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