Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Jettah on January 12, 2004, 02:28:54 PM
-
Hi,
I'm having some troubles in retrieving the number of bytes a file occupies. The documentation on this subject is not entirely clear (to me, at least).
The following piece of code is used:
struct FileInfoBlock *fib;
if (fib = AllocDosObjectTags(DOS_FILEHANDLE, ADO_FH_Mode))
{if (Examine(, fib))
{fib_Size>;
}
FreeDosObject(DOS_FILEHANDLE, fib);
}
The program crashes when reaching AllocDosObjectTags() (or AllocDosTags for that matter).
I can find documentation about DOS_FILEHANDLE /* few people need it */, but I cannot find anything on ADO_FH_Mode! I have a peculiar feeling that,as it is a tag list, it requires a certain value, like this:
ADO_FH_Mode, , TAG_END
But what has to be supplied for ???. I can't find anything about it.
Or am I fully lost in paradise of Amiga software developement?
Help! HELP! Mommy, please help me!
Regards,
Tjitte
P.S.: When it (my small contribution of software) gets published someday, your name will be mentioned in the accompanying README!
-
if (fib = AllocDosObjectTags(DOS_FILEHANDLE, ADO_FH_Mode))
{if (Examine(, fib))
{fib_Size>;
}
FreeDosObject(DOS_FILEHANDLE, fib);
}
This is completely wrong.
You must alloc FileInfoBlock structure, not filehandle structure! In
addition your taglist is not terminated with TAG_DONE and ADO_FH_MODE
misses tag value.
Allocate DOS_FIB packet and supply an empty taglist (TAG_DONE only)..
-
@itix:
Thanks for your reply.
But, ehm, it, eh, still does not perform the way I intended...
Changed the code to:
struct FileInfoBlock *fib;
if ((struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END))
{if (Examine(, fib)) fib_Size>;
FreeDosObject(DOS_FIB, fib);
}
It still crashes...
Regards,
Tjitte
-
Hello,
Let me give you another solution:
long filesize(FILE *stream)
{
long curpos, length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}
This is plain ANSI-C without Amiga-dependencies, so it should work on all machines...
To call it just open your file with fopen() and give the FilePointer to the function. After that you close the file again with fclose().
Hope that helps...
-
Or, if you dont want to use ANSI C IO for it, you can do what selco describes with dos.library Seek(), which will allow you to determiine the length by seeking to the end of the file from the start.
-
Hi
I used the stuff, but in bad way, I shouldn't even speak about... But it worked. :-)
Well, as DOS was written in BCPL (at least the virst versions of it), all the used pointers had to be LONG aligned.
On the other hand we know that all the compilers do at least SHORT align. So this is what I did:
struct {
short dummy;
struct FileInfoBlock fib;
} buffer;
struct FileInfoBlock *fib = (struct FileInfoBlock *)( ( (long) &buffer.fib )&~3L );
if (Examine(, fib)) fib_Size>;
Now you may kill me. ;-)
But at least you can try if it crashes.
Good luck
-
@selco
This seek method is infinitely slow on FFS and large files, however.
It should be avoided, if only possible.
-
if ((struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END))
Why you have "(struct FileInfoBlock *)fib" there?
-
itix wrote:
if ((struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END))
Why you have "(struct FileInfoBlock *)fib" there?
It's there because AllocDosObject() returns a void *.
In the meantime I've isolated the problem into a separate piece of proza:
#include
#include
#include
#include
void main(void)
{struct FileInfoBlock *fib;
struct Library *DosBase;
BPTR File, x;
char *FileName = "RAM:T/Command-0-T5";
if (DosBase = OpenLibrary("dos.library", 40L))
{if (File = Lock(FileName, SHARED_LOCK))
{if ((struct FileInfoBlock *)fib = AllocDosObjectTags(DOS_FIB, TAG_END))
{if (Examine(File, fib))
{printf("Name = %s\n", fib->fib_Name);
printf("Type = %s\n", (fib->fib_DirEntryType > 0) ? "Directory" : "File";
printf("Size = %ld\n", fib->fib_Size);
}
else printf("ERROR\n");
FreeDosObject(DOS_FIB, fib);
}
if (x = Open(FileName, MODE_OLDFILE))
{printf("File opened\n");
Close(x);
}
UnLock(File);
}
else printf("ERROR: No file locked\n");
CloseLibrary(DosBase);
}
else printf("ERROR: No library opened"\n");
}
This gave me the requested results without troubles. So I draw the conclusion that I'm on the very brink of insight into the matter!
Thanks for all your concern to all of you.
Regards,
Tjitte
-
(struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END)
Yep, you have it on the wrong side.
You mean:
fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, TAG_END)
-
PiR wrote:
(struct FileInfoBlock *)fib = AllocDosObject(DOS_FIB, TAG_END)
Yep, you have it on the wrong side.
You mean:
fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, TAG_END)
Silly me! You are perfectly correct. Thanks mate! And remember: whenever the piece of proza, in which the construct is used, ever gets published, your name will shine in the accompanying README!
Bye!
Topic closed.
Tjitte
-
IIRC one of the main reasons you're supposed to use AllocDosObject() for this is so that you don't have to worry about alignment issues...