|
-
Jun 27th, 2011, 10:58 AM
#1
Thread Starter
Fanatic Member
[RESOLVED] Reversed file format (Java)
Hello everyone.
I discovered that java uses a reversed way of storing data. For example, the integer value 2 has the following byte values:
In "Windows" format:
[2] [0] [0] [0]
In "Java" format:
[0] [0] [0] [2]
The binary readers of both languages seem to use the same different format.
Now my question: What is the easiest way to read binary values (Integer, Single, etc.) in VB .NET from a java formatted file?
I already made functions like these:
Code:
Private Shared Function revRead(ByVal s As IO.BinaryReader, ByVal length As Integer) As Byte()
Dim rval(length - 1) As Byte
s.Read(rval, 0, length)
Array.Reverse(rval)
Return rval
End Function
Private Shared Function readString(ByVal s As IO.BinaryReader) As String
Dim stringlength As Short = BitConverter.ToInt16(revRead(s, 2), 0)
Dim chars(stringlength - 1) As Char
s.Read(chars, 0, stringlength)
Return chars
End Function
But they require the (slower) BitConverter to make the read bytes into a value. Is there a "vanilla way" around, some setting for inverted reading in the binary reader or a different class? Or do I have to keep using this Reverse byte method?
-
Jun 27th, 2011, 11:37 AM
#2
Re: Reversed file format (Java)
This will obviously be different for different data types, but this should work for integers:
Code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim javaBytes = New Byte() {0, 0, 0, 2}
Dim value = JavaConversion.ToInt32(javaBytes)
Console.WriteLine(value)
End Sub
End Class
Public Class JavaConversion
'//constructors
Private Sub New()
End Sub
'//methods
Public Shared Function GetBytes(ByVal value As Integer) As Byte()
Return New Byte() {CByte((value >> 24) And &HFF), _
CByte((value >> 16) And &HFF), _
CByte((value >> 8) And &HFF), _
CByte(value And &HFF)}
End Function
Public Shared Function ToInt32(ByVal b As Byte()) As Integer
Return ((b(0) And &HFF) << 24) + _
((b(1) And &HFF) << 16) + _
((b(2) And &HFF) << 8) + _
((b(3) And &HFF))
End Function
End Class
-
Jun 27th, 2011, 11:42 AM
#3
Thread Starter
Fanatic Member
Re: Reversed file format (Java)
Bit conversion works on integers, since it is a simple addition function (byte 0 * 2 ^ 0 + byte 1 * 2 ^ 8 etc), but I can't imagine bit conversions with Single (float) values, any way to do that?
EDIT
I see I need a function to convert a java stored integer/single into a VB .NET integer/single, like this:
(bytes) [0] [0] [0] [64]
(int) 1073741824 -> 64
(single) 2 -> 8,96831E-44
Then I could make simple overloaded functions for it:
Code:
Public Function Invert(ByVal value As Integer) As Integer
Public Function Invert(ByVal value As Single) As Single
Inverting the value twice should result in the first value.
EDIT2
Ok, I think I know what my problem is, and others have as well. I need to convert Big-Endian values to Little-Endian values and vice versa.
What I did was storing the data in a byte array and do it like that, but it requires the bitconverter to retrieve the value again.
I have seen some bit shifting that swaps the format of an integer, but what about the Single/Double/Long/Decimal (?) ?
Last edited by bergerkiller; Jun 27th, 2011 at 12:07 PM.
-
Jun 27th, 2011, 12:00 PM
#4
Re: Reversed file format (Java)
I think that this would be good to look through.
-
Jun 27th, 2011, 12:18 PM
#5
Re: Reversed file format (Java)
Don't mix up your bits with your bytes. Endianness is the word to research; how do you like your eggs cracked? Are you a Big-Endian or a Little-Endian?
With respect to floating point values, BitConverter is perhaps the easiest option (that I know of) in VB.Net, the documentation does discuss endianness and provides examples.
If you are familiar with C# you can use an unsafe context and pointers to do this also, perhaps quite a bit quicker than BitConverter (don't know, not tested)
-
Jun 27th, 2011, 12:28 PM
#6
Thread Starter
Fanatic Member
Re: Reversed file format (Java)
Combined the two functions of ForumAccount and ended up with this:
Code:
Public Shared Function Endian(ByVal value As Integer) As Integer
Return Endian(CUInt(value And &HFF))
End Function
Public Shared Function Endian(ByVal value As UInteger) As UInteger
Return (value << 24) + ((value >> 8) << 16) + ((value >> 16) << 8) + (value >> 24)
End Function
It requires quite some bit shifting, I think the bitconverter would perform better. Thanks everyone, bit converter it is, although I will make simple converters, like these:
Code:
Public Shared Function Invert(ByVal value As Integer) As Integer
Dim b() As Byte = BitConverter.GetBytes(value)
Array.Reverse(b)
Return BitConverter.ToInt32(b, 0)
End Function
Public Shared Function Invert(ByVal value As Single) As Single
Dim b() As Byte = BitConverter.GetBytes(value)
Array.Reverse(b)
Return BitConverter.ToSingle(b, 0)
End Function
(Please ignore the CType issues, I can always make distinct names)
Code:
MsgBox(Invert(CSng(2)))
I'll mark this thread resolved, if anyone knows of a native VB .NET method (which does not require that much bit shifting), feel free to post anyways.
Last edited by bergerkiller; Jun 27th, 2011 at 12:50 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|