// //////////////////////////////////////////////////////////
// endian.c
// Copyright (c) 2013-2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//

#include "EndianTypes.hpp"
#include <stdio.h>
#include <cinttypes>


uint8_t buffer[] = {
  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
  0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x01,
};

struct big_endian_layout
{
  be64_t  a;
  be32_t  b;
  be16_t  c;
  be8_t   d;
};

static_assert(sizeof(big_endian_layout) == 15, "bad padding");

struct little_endian_layout
{
  le64_t  a;
  le32_t  b;
  le16_t  c;
  le8_t   d;
};

static_assert(sizeof(little_endian_layout) == 15, "bad padding");


int main(int argc, char* argv[])
{
  // on little endian systems, twoBytes is stored as 0x01, 0x00 and
  // on big    endian systems, twoBytes is stored as 0x00, 0x01
  short twoBytes = 0x0001;
  // get first byte of twoBytes
  char  oneByte  = *(char*) &twoBytes;

  if (oneByte == 1)
    puts("little endian");
  else
    puts("big endian");

  auto* be_data = reinterpret_cast<big_endian_layout*>(buffer);
  auto* le_data = reinterpret_cast<little_endian_layout*>(buffer);
  
  if (be_data->a != 0x0123456789ABCDEF) { printf("ERROR 1\n"); } else { printf("PASS 1\n"); }
  if (be_data->b != 0x01234567)         { printf("ERROR 2\n"); } else { printf("PASS 2\n"); }
  if (be_data->c != 0x0123)             { printf("ERROR 3\n"); } else { printf("PASS 3\n"); }
  if (be_data->d != 0x01)               { printf("ERROR 4\n"); } else { printf("PASS 4\n"); }
  if (le_data->a != 0xEFCDAB8967452301) { printf("ERROR 5\n"); } else { printf("PASS 5\n"); }
  if (le_data->b != 0x67452301)         { printf("ERROR 6\n"); } else { printf("PASS 6\n"); }
  if (le_data->c != 0x2301)             { printf("ERROR 7\n"); } else { printf("PASS 7\n"); }
  if (le_data->d != 0x01)               { printf("ERROR 8\n"); } else { printf("PASS 8\n"); }

  printf(" %" PRIx64 " %x %x %x \n", be_data->a.toHostEndian(), be_data->b.toHostEndian(), be_data->c.toHostEndian(), be_data->d); 
  printf(" %" PRIx64 " %x %x %x \n", le_data->a.toHostEndian(), le_data->b.toHostEndian(), le_data->c.toHostEndian(), le_data->d); 

  return 0;
}


