Trying to parse a file

BlitzMax Forums/BlitzMax Beginners Area/Trying to parse a file

PaulJG(Posted 2005) [#1]
I'm trying to learn how to correctly parse a 3DS file - for the experience - but having alittle trouble.

It seems the first 2 bytes are Hex numbers describing the current chunk identifer.. which I can get fine.

But the next 4 bytes contain the length of the chunk..

I'm not sure if its suppose to be in hex or just a decimal number, I presume its decimal..

So how do I read all four bytes, and get them to combine to be one number ?

I'm using this:
For cnt = 1 To 4
l_chunk_length = l_chunk_length + ReadByte(l_file)
Next


Which is giving me 34

I've no idea if this is the correct sum.. in a hex editor the 4 bytes are: 20 02 00 00

Is this correct ?


fredborg(Posted 2005) [#2]
Look up streams in the module reference, there you can see the different ways to load bytes from a file.
Local my3DSfile:String = "something.3ds"

Local l_file = ReadFile("littleendian::"+my3DSfile)
If l_file
	'
	' Print the file size 
	Print "Filesize: "+FileSize(my3DSfile)

	'
	' Each chunk ID in a 3DS file is 2 bytes long, also known
	' as a Short in BlitzMax
	chunk:Int = ReadShort(l_file)

	'
	' The size of the chunk is located right after the chunk ID,
	' it is an Integer which consist of 4 bytes.
	chunk_size:Int = Readint(l_file)

	'
	' The very first chunk ID in a 3DS file should be $4D4D, so
	' let's check to see if it is a 3DS file
	If chunk = $4D4D
		Print "Yep, it's a 3DS file!"
	Else
		Print "This isn't a 3DS file!"
	EndIf
	Print "Chunk ID:   "+Hex(chunk)
	Print "Chunk Size: "+chunk_size
	
	CloseStream l_file
Else
	Print "File does not exist!"
EndIf
Whether a number is hex or not, the computer doesn't care about. If you want to know the decimal value of a hex number just use:
Print $4D4D
And I'd like to warn you that the 3DS file format, isn't very well documented...well, it is documented a lot of places, often incomplete, and everybody seem to have their own version of it...And it's quite complex if you have never written a file loader before. So be sure you really want to write it :)

The very first chunk should have the same size as the file. So you can check it by going:
If chunk_size = FileSize(myfile$)
  Print "Seems all right..."
Else
  Print "Maybe something is wrong..."
EndIf



Floyd(Posted 2005) [#3]
The four bytes in the example are 32,2,0,0. That appears to be in little endian format. So the length would be 32 + 2*256 +0*256*256 + 0*256*256*256 = 544.

You would read these with a single ReadInt. But you have to be careful because BlitzMax is multi-platform. A PC would read this correctly. But the Mac defaults to big endian.

When you open the stream (or incbin ) you should specify which format it uses. Instead of "yourfile.3ds" use "littleendian::yourfile.3ds" and it will read correctly on all machines.

This is going to be a recurring problem as people post file handling code that works only for PC, or only for Mac.

And, while I'm thinking of cross platform problems, be careful of case sensitivity in file names. Windows is case insensitive so yourfile and YourFile are the same. But on the Mac file names may or may not be case sensitive, depending on how the file system is set up.


PaulJG(Posted 2005) [#4]
Big thanks guys ! :)

Is it just me.. I dont seem to have any docs for module commands. (page is missing - they dont seem to be in Marks beta download zip either !)


Yan(Posted 2005) [#5]
I'm not sure if its suppose to be in hex or just a decimal number, I presume its decimal..


When you're reading a data file (which you are) this is irrelevant. The data is stored as bytes. Hex, binary and decimal are just ways to express the value of those bytes.

If I had 11 copies of BMAX for instance, I could write that number as 11, %00001011, $0B or even XI. I would still have 11 copies, I'd just be representing them in different ways. The same thing is true with data.

Obviously, if the file was a text file, that would be a completely different matter.


I apologise if the above comes across as patronising, it wasn't meant to be. I've seen similar things written on this forum quite a few times and I thought that I might be able to clear this up for some people.


fredborg(Posted 2005) [#6]
Paul, if your docs are missing you need to use:
BMK makedocs
Or, try out this:
http://www.blitzbasic.com/Community/posts.php?topic=42438