#include <stdio.h>
#include <stdlib.h>
#include "iomanip.h"
#include "iostream.h"
#include "newcasts.h"
#include "stdiobuf.h"

void put_stdio_stats(FILE* file)
{
  FILE f = *file;

  cerr << resetiosflags(ios::adjustfield|ios::basefield) << setiosflags(ios::right) << hex << setfill('0');

  cerr << "FILE        " << setw(8) << file << endl;
  cerr << "__ptr       " << setw(8) << reinterpret_cast(void*, f.__ptr) << endl;
  cerr << "__icnt      " << setw(8) << f.__icnt << endl;
  cerr << "__ocnt      " << setw(8) << f.__ocnt << endl;
  cerr << "__flag      " << setw(8) << f.__flag << endl;
  cerr << "__base      " << setw(8) << reinterpret_cast(void*, f.__base) << endl;
  cerr << "__file      " << setw(8) << f.__file << endl;
  cerr << "__pos       " << setw(8) << f.__pos << endl;
  cerr << "__bufsiz    " << setw(8) << f.__bufsiz << endl;
  cerr << "__signature " << setw(8) << f.__signature << endl;
  cerr << "__extrap    " << setw(8) << f.__extrap << endl;
  cerr << endl;

  if(f.__extrap != 0)
  {
    cerr << "Extra data  ";
    int *field = reinterpret_cast(int*, f.__extrap)-2;

    for(int i = 0; i < 16; ++i)
      cerr << setw(8) << *field++ << ' ';

    cerr << endl;
    cerr << endl;
  }

  if(f.__ocnt > 0)
  {
    cerr << "Output queue |";
    for(unsigned char* p = f.__base; p < f.__ptr; ++p)
      cerr << char(*p);
    cerr << '|' << endl << endl;
  }

  if(f.__icnt > 0)
  {
    cerr << "Input queue |";
    for(unsigned char* p = f.__ptr; p < f.__ptr+f.__icnt; ++p)
      cerr << char(*p);
    cerr << '|' << endl << endl;
  }
}

int main()
{
  FILE* f = fopen("TestFile", "w+");
  stdiobuf* buf = new stdiobuf(f, 16);
  ostream fout(buf);
  istream fin(buf);

  put_stdio_stats(f);

  for(int i = 0; fin && i < 64; ++i)
  {
    cout << "Seeking before write" << endl;
    put_stdio_stats(f);
    fout.rdbuf()->pubseekoff(0, ios::end);
    put_stdio_stats(f);

    cout << endl << "Writing " << char('a'+i) << endl;
    fout << char('a'+i);
    put_stdio_stats(f);

    cout << "Seeking before read" << endl;
    put_stdio_stats(f);
    fin.rdbuf()->pubseekpos(0);
    put_stdio_stats(f);

    char c;
    if(fin >> c)
    {
      cout << endl << "Reading " << c << endl;
      put_stdio_stats(f);
    }
    else
    {
      cerr << "Read failed" << endl;
      put_stdio_stats(f);
    }
  }

  fclose(f);

  return 0;
};
