digitalmars.D - endian: std.inbuffer/std.outbuffer is not a sufficient
- Brian Bober (97/97) Sep 22 2004 We still need an bigendian, bigendian, littleendian, etc attribute.
We still need an bigendian, bigendian, littleendian, etc attribute. The assumption that you'd only need to deal with this on stream I/O on individual variables is false because of needing to input/output entire structures from memory. Does std.inbuffer in the Phobos system library (http://www.digitalmars.com/d/) provide a method to define an entire structure from memory and have the correct endianness reflected? I don't like the idea of having to overload outbuffer for structs differently on different systems depending upon endianness. It sounds really yucky to have to overload in all these cases. The solution in part 3 is what people have suggested years ago. The only other viable method would to have something that works like printf with formatting characters that specify endianness of the data characters... I'll show that in part 5. 1) On C/C++ system-specific where the endianness is known to be the same as the data in memory, you could do the following pseudocode: struct someimageheader { short a; short b; long c; long d; char e[2]; } someimageheader ih; void somefunc() { memcpy(&ih,somemem,12); } and would fill the buffer properly. 2) I don't see how outbuffer could do this kind of thing... It seems like you'd have to read in the values one at a time and explicitly convert their endianness... Although this is essentially the same thing that happens on cross-platform code in C++, it'd be nice to be able to do something like this this: struct someimageheader { bigendian short a; bigendian short b; bigendian long c; bigendian long d; char e[2]; } or equivalent if you know every variable will be the proper value (char, of course, has no endianness): bigendian struct someimageheader { short a; short b; long c; long d; char e[2]; } 3) You could make it so structs defined with inbigendian or outbigendian can not be worked with directly unless you copy it to a normal structure. So the code I showed in 1 would be equivalent to this (there is probably a better way to do this, but I'm just trying to give an idea): bigendian struct be_someimageheader { short a; short b; long c; long d; char e[2]; } struct someimageheader { short a; short b; long c; long d; char e[2]; } be_someimageheader beih; someimageheader ih; void somefunc() { memcpy(&beih,somemem,12); ih=beih; } 4) This could also work for: void somefunc() { bigendian int a=5; int b=a; } On a little-endian machine, it'd convert endianness. 5) The only viable solution I can think of would be to have a function that can reorder bytes in a struct based on some formatting character like this: structreorder(void * struct, va_list commands) example: structreorder((void *)&ih, "r%s", "r%s", "r%l", r%l", "%b"); Which means, "reorder short,reorder short,reorder long,reorder long, don't reorder byte" I think this suffers from having to rewrite the formatting every time you change the struct, and doesn't save anything from overloading the outbuffer functions.
Sep 22 2004