/*
 file 3r_testbench.c
 (C) 2003 Yann GUIDON <whygee@f-cpu.org>

 Recursive Range Reduction,
 testbench source code
 version Wed Dec 31 02:26:20 CET 2003

 compile with:
    gcc 3r_testbench.c -o 3r
 or
    gcc -DPHASING 3r_testbench.c -o 3r
*/

#include <stdio.h>   /* for printf */
#include <stdlib.h>  /* for malloc */
#include <string.h>  /* for memset */

#ifdef PHASING
#include "3r_phasing-in.c"
#else
#include "3r_simple.c"
#endif

/********* Some tests *********/

/* cyclic data */
unsigned long int S[31]={
 9, 2, 1, 3, 0xFFFF, 1010, 1031, 1,
 920, 0, 0xFFFF, 1243, 115, 31, 10, 0,
 9, 2, 1, 3, 0xFFFF, 1010, 1031, 1,
 920, 0, 0xFFFF, 1243, 115, 31, 10};

/* what does happen when
  only one bit is encoded ? */
unsigned long int T[31]={
 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 1,
 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0};

/* watching the logarithmic
   overhead in worst case situation: */
unsigned long int U[16]={
 0xBEE0, 0xBEE1, 0xBEE2, 0xBEE3,
 0xBEE4, 0xBEE5, 0xBEE6, 0xBEE7,
 0xBEE8, 0xBEE9, 0xBEEA, 0xBEEB,
 0xBEEC, 0xBEED, 0xBEEE, 0xBEEF};

/* "spiky" input data: */
unsigned long int V[16]={
 0, 0xFFFF, 0, 0xFFFF,
 0, 0xFFFF, 0, 0xFFFF,
 0, 0xFFFF, 0, 0xFFFF,
 0, 0xFFFF, 0, 0xFFFF};

/* where the decoded output goes: */
unsigned long int W[32];

unsigned char bitstream[5000];

void test_cpr(unsigned long int *P, int cpt) {
  int i, init_size;

  init_size = shift_count + (stream_length<<3);

  printf("\nInitial data:\n");
  for (i=0; i<cpt; i++)
    printf("%lX ",P[i]);

  printf("\n\nEncoding:\n");
  encode_3R(cpt, P);

  printf("\n ====> result = %d bits\n\n",
    shift_count + (stream_length<<3) - init_size);
}

void test_dcpr(unsigned long int *P, int cpt) {
  int i;

  printf("\n\nDecoding:\n");
  decode_3R(cpt, W);

  printf("\nDecoded data:\n");
  for (i=0; i<cpt; i++)
    printf("%lX ",W[i]);

  if (memcmp(W,P,i*sizeof(*P))!=0){
    printf("\nError !\n");
    exit(1);
  }

  printf("\n\n   ---------------------\n\n");
}

int main(void) {
  int i;

  /* initialises the binary stream : */
  stream = &bitstream[0];
  stream_length = 0;
  shift_count = 0;
  reservoir = 0;

  test_cpr(S, 16);
  test_cpr(T, 16);
  test_cpr(U, 16);
  test_cpr(U, 32);
  test_cpr(V, 16);

  /* look for the effects of rotation */
  for (i=0; i< 16; i++)
    test_cpr(&S[i], 16);

  for (i=0; i< 16; i++)
    test_cpr(&T[i], 16);

  printf("\n\nTotal result : %d bits\n\n",
      shift_count + (stream_length<<3));

  /* flush the reservoir */
  if (shift_count > 0)
    stream[stream_length++] = reservoir;

  /* clear the bitstream variables */
  stream_length = 0;
  shift_count = 0;
  reservoir = 0;

  test_dcpr(S, 16);
  test_dcpr(T, 16);
  test_dcpr(U, 16);
  test_dcpr(U, 32);
  test_dcpr(V, 16);

  for (i=0; i< 16; i++)
    test_dcpr(&S[i], 16);

  for (i=0; i< 16; i++)
    test_dcpr(&T[i], 16);

  return 0;
}


