6

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.

Community
  • 1
  • 1
n535
  • 4,983
  • 4
  • 23
  • 28

3 Answers3

10

This is because the code is meant to run as well 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 the Java standard was big-endian instead.

SSS
  • 4,807
  • 1
  • 23
  • 44
Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
  • 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 Feb 28 '10 at 20:47
  • 2
    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 Feb 28 '10 at 20:55
  • +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 Feb 28 '10 at 21:00
  • Agreed. Choice is not 100% straight forward in Java either... having read quite a few little endian files from that language, myself. – PSpeed Feb 28 '10 at 21:05
  • You definitely have a choice. You can use Java. – President James K. Polk Feb 28 '10 at 21:07
  • 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". – Johan Kotlinski Mar 01 '10 at 10:41
  • 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 Mar 01 '10 at 13:25
  • @PSpeed more natural to who? 'mov 42 register' how would you check that in a natural way... – Jay Feb 13 '15 at 20:35
2

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
  • 178,213
  • 47
  • 333
  • 501
  • Anything except IsLittleEndian property? System.Net.IPAddress.NetworkToHostOrder is very far away from the actual problem though – n535 Feb 28 '10 at 20:51
  • 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 Feb 28 '10 at 21:07
  • 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 Feb 28 '10 at 21:21
  • 1
    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 Feb 28 '10 at 21:45
1

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.

Soroush Mirzaei
  • 936
  • 2
  • 19
  • 34
Wilfred Springer
  • 10,869
  • 4
  • 55
  • 69