views:

323

answers:

3

Well, the "Endianness" theme was always a little bit confusing to me, but i have never faced any problems which required me to even think about the default behaviour of binary writers/readers that i used. I am writing a PNG decoder in c# right now. PNG file format specification states that all numbers are stored in a big endian notation (which i find very natural). However, i was very surprised when i noticed, that .NET's BinaryReader/Writer works with a little endian notation. What confused me even more, was the fact, that java's binary IO works with a big endian notation (a am not a java programmer, so maybe i am wrong). So i started to think about the following questions:

1 - Why are things as they are? I mean a Base Class Library default behaviour. 2 - Why there is no way to choose a preferred notation when using .NET's System.IO ?

I am currently using Jon Skeet's MiscUtil and it works like a charm (thanks, man =) ). But it would be cool to see this functionality in a Base Class Library.

+6  A: 

This is because the code is meant to run as good as possible on the most important platform. C#/.NET is from Microsoft and runs mostly on x86 platforms. x86 is little-endian, so it makes sense to make the library little-endian. Java is made by Sun, and the Sun SPARC was big-endian, thus Java standard was big-endian aswell.

kotlinski
What about compact and micro frameworks? Even though, i agree, that this may have been a factor, .NET,s nature is kinda platform-independent.
n535
Java was designed to be platform independent which is why they went with the more natural ordering. .NET comes by its platform independence secondarily and was primarily designed to normalize the various languages on the Windows platform and bring newer language features like garbage collection, etc.. The MS/intel world tends to be myopic in this way and thus most of the files that a windows programmer would read are little endian. Little endian is/was the preferred ordering on intel chips.
PSpeed
+1 Well, that makes sense of-course, but still does not explain the absence of choice. It worth nothing to implement this in a BCL in a very efficient way.
n535
Agreed. Choice is not 100% straight forward in Java either... having read quite a few little endian files from that language, myself.
PSpeed
You definitely have a choice. You can use Java.
GregS
I have to admit big-endian coming from SPARC architecture is a guess from me. But I would be willing to bet money on that political/economical concerns weighed heavier than that big-endian is more "natural".
kotlinski
<shrug> For a long time in my own software career "little endian" was also known as "intel byte ordering". It is pretty easy to argue that "big endian" is more natural for humans... in base 10, that's how we write. And with the x86 looping architecture, "little endian" was definitely more efficient back in the day for that architecture. But it always seemed like every other architecture was big endian.
PSpeed
A: 

The BCL contains things in the System.BitConverter static class that allow you to deal with system endianness. All methods in BitConverter are essentially platform agnostic as a result.

In addition, the System.Net.IPAddress.NetworkToHostOrder method allows you to change endianness from big to little endian, and vice versa.

Robert Harvey
Anything except IsLittleEndian property? System.Net.IPAddress.NetworkToHostOrder is very far away from the actual problem though
n535
I'm not sure I understand your problem. I read and write binary files all the time with BinaryReader and BinaryWriter, and if the byte order is not being read or written the way I want, I just swap the bytes (typically using `NetworkToHostOrder`). What's the big deal?
Robert Harvey
Well, there is no actual 'problem'. Indeed, you can work with PNG in .NET, so i think that .NET core developers do not have a problem as well. But i am also concerned, that it will be more efficient to interpret bytes correctly on the fly (when reading) without further reversing. Of course, it is not so hard to implement by myself, but i think such things should be provided within a framework, just because they are quite common (that explain the existence of things like MiscUtil). The only thing i am actually trying to figure out, are there some serious reasons, why we do not have this in NET
n535
NetworkToHostOrder is very fast. I have to believe that the time it takes to read the bytes from a file is at least two orders of magnitude longer than the required time to flip the bytes.
Robert Harvey
A: 

I guess it boils down to always being able to deal with both, regardless of the platform you're on. Preon is trying to hide some of that complexity by allowing you to declaratively (using annotations) define the mapping between your in-memory data representation, and the encoded representation.

So if this is part of your data structure:

public Image {
int width;
int height;
}

then defining the mapping to a natural big endian representation would be as easy as this:

public Image {
@BoundNumber int width;
@BoundNumber int height;
}

However, if the representation is little endian, then you can do this:

public Image {
@BoundNumber(byteOrder=LittleEndian) int width;
@BoundNumber(byteOrder=LittleEndian) int height;
}

In both cases, creating a Codec for this data structure is the same:

Codec<Image> codec = Codecs.create(Image.class);

I know some people were talking about porting this to .NET as well.

Wilfred Springer