majestic53 / libanvil

A C++ library for reading and writing Minecraft "Anvil" files
GNU General Public License v3.0
30 stars 12 forks source link

Wrong endian handling #9

Open siarsky opened 4 years ago

siarsky commented 4 years ago

I believe, the library is handling the big endian logic incorrectly.

  1. read file r.-2.-1.mca, chunk 0,0

  2. set a breakpoint in region_file_reader line 312

    311:        case generic_tag::LONG_ARRAY:
    312:        tag = new long_array_tag(name, read_array_value<long>(stream));
  3. debug the code till byte_stream line 63

    63:     for(unsigned int i = 0; i < width; ++i)
    64:         var |= ((T)data.at(i) << (8 * ((width - 1) - i)));
    65:     return SUCCESS;
  4. array data has the following content (hexadecimal) [0]=11, [1]=88, [2]=a4, [3]=52, [4]=29, [5]=10, [6]=88, [7]=43

  5. print data by calling "get_data" OCEAN_FLOOR [LONG ARRAY] : Size 36 : 11 88 A4 52 29 10 88 43 ... expected is: OCEAN_FLOOR [LONG ARRAY] : Size 36 : 43 88 10 29 52 A4 88 11 ...

POSSIBLE REASON:

63:     for(unsigned int i = 0; i < width; ++i)
64:         var |= ((T)data.at(i) << (8 * ((width - 1) - i)));

is already converting big endian into little endian, so an additional convertion in all arrays classes: byte_stream stream(byte_stream::SWAP_ENDIAN); bring the big endian back.

A quick try:

63:     for(unsigned int i = 0; i < width; ++i)
64:         var |= ((T)data.at(i) << (8 * i));

leads to "unknown_tag".

A quick and dirty solution is a removal of all byte_stream stream(byte_stream::SWAP_ENDIAN); calls in the tag/ classes.

PS: r.-2.-1.mca.zip