/* this is the sources of IO tests (Test_printf,Test_Write,Test_Read)  */

#include <stdio.h>
#include <stdlib.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/timer.h>
#include <math.h>
#include "compiler.h"

/****** posbb_tests.c/Test_printf ******************************************
*
*   NAME
*     Test_printf -- Tests the speed of the ANSI function printf().
*
*   SYNOPSIS
*     time = Test_printf( int precision )
*     ULONG Test_printf( int );
*
*   FUNCTION
*     Writes 1,000 times the string "printf test in progress...\n" to stdout
*     and returns the time taken.
*
*   INPUT
*     int precision     the precision of the results. Can be any of
*                       POSBB_PREECISION#?. The higher is the precision wanted,
*                       the higher the time taken. precision is useful on faster
*                       machines,on wich the times will be too low.
*
*
*   RESULT
*     time - number of 1/1000 seconds spent.
*
*   EXAMPLE
*     See posbb.c/Perform_Tests().
*
*   NOTE
*     In future versions it will return a float.
*
*   BUGS
*     It hasn't bugs,but since it can't turn off multitasking,the result
*     could change if the user runs some program or move windows.
*
****************************************************************************
*/
ULONG Test_printf( precision , freeze, mt)
int precision;
BOOL freeze,mt;
{
  ULONG time,secs;
  int c;
  char tmpstr[20];
  struct timeval *time1,*time2;
  time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
#ifndef NOFORBID
  if (freeze == TRUE) Forbid();
#endif
  if (mt)
  {
     printf("Press RETURN to start");
     getchar();
  }
  else  GetSysTime(time1);   /* This gets the system time using timer.device. It is opened by posbb.c */

  for ( c = 0; c<1000*precision; c++ )
  {
    printf("printf test in progress...\n");
  }
  if (mt)
	{
	  DisplayBeep();
	  printf("Test finished. Type in the number of seconds taken:");
	  secs = atoi(gets(tmpstr));
	}
	else GetSysTime(time2);
#ifndef NOFORBID
  if (freeze == TRUE) Permit();
#endif
  if (mt) time = secs * 1000;
  else
  {
    SubTime(time2,time1);
    time = (time2->tv_secs)*1000+(time2->tv_micro)/1000;
  }
  POSBB_FreeMem(time1,sizeof(struct timeval));
  POSBB_FreeMem(time2,sizeof(struct timeval));
  return time;

}
/****** posbb_tests.c/Test_Write ********************************************
*
*   NAME
*     Test_Write -- Tests disk writing speed.
*
*   SYNOPSIS
*     time = Test_Write( STRPTR filename,int precision )
*     double Test_Write( STRPTR ,int );
*
*   FUNCTION
*     Writes a block of data to a file,with dos.library/Write() (in the Amiga
*     version).
*
*   INPUT
*     STRPTR filename   the name of the file to write to.
*
*     int precision     the precision of the results. Can be any of
*                       POSBB_PREECISION#?. The higher is the precision wanted,
*                       the higher the time taken. precision is useful on faster
*                       machines,on wich the times will be too low.
*
*   RESULT
*     time - Time spent ins econds.
*            Returns TRUE if something went wrong ( memory or disk space usually).
*            In future may return differents error codes.
*
*   EXAMPLE
*     See posbb.c/Perform_Tests.
*
*   BUGS
*     No known bugs.
*
****************************************************************************
*/
ULONG Test_Write(STRPTR filename,int precision,BOOL freeze,BOOL mt)
{
  struct timeval *time1,*time2;
  ULONG buf;
  int c;
  ULONG secs,time;
  BPTR file;
  char tmpstr[20];

  time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);

  if ( buf=POSBB_AllocMem(262144,0))
  {
    if (file = (BPTR) Open(filename,MODE_NEWFILE))
    {
#ifndef NOFORBID
      if (freeze == TRUE) Forbid();
#endif
    if (mt)
      {
	printf("Press RETURN to start");
	getchar();
      }
      else  GetSysTime(time1);   /* This gets the system time using timer.device. It is opened by posbb.c */

      for (c = 0;c<20*precision;c++ )
      {
      Write(file,buf,262144);
      }
if (mt)
	{
	  DisplayBeep();
	  printf("Test finished. Type in the number of seconds taken:");
	  secs = atoi(gets(tmpstr));
	}
	else GetSysTime(time2);
#ifndef NOFORBID
      if (freeze == TRUE) Permit();
#endif
      POSBB_FreeMem(buf,262144);
      Close(file);
    }
  }
  else return TRUE;
  if (mt) time = secs * 1000;
  else
  {
    SubTime(time2,time1);
    time = (time2->tv_secs)*1000+(time2->tv_micro)/1000;
  }
  POSBB_FreeMem(time1,sizeof(struct timeval));
  POSBB_FreeMem(time2,sizeof(struct timeval));

  if (file=(BPTR) 0) return TRUE;
  else return time;
}
/****** posbb_tests.c/Test_Read ********************************************
*
*   NAME
*     Test_Read -- Tests disk reading speed.
*
*   SYNOPSIS
*     time = Test_Read( STRPTR filename,int precision )
*     ULONG Test_Read( STRPTR, int );
*
*   FUNCTION
*     Reades a block of data from a file,with dos.library/Read() (in the
*     Amiga version).
*
*   INPUT
*     STRPTR filename   the name of the file to read from
*     int precision     the precision of the results. Can be any of
*                       POSBB_PREECISION#?. The higher is the precision wanted,
*                       the higher the time taken. precision is useful on faster
*                       machines,on wich the times will be too low.
*
*   RESULT
*     time - Time spent in seconds.
*            Returns TRUE if something went wrong ( memory or disk space
*            usually). In future may return differents error codes.
*
*   EXAMPLE
*     See posbb.c/Perform_Tests.
*
*   NOTES
*     In future versions it will use different functions depending on dos.library version.
*     With dos.library V 36+ it will use buffered routines,unbuffered on previous versions.
*     The results given by Test_Read() and Test_Write() depend not only on the disk/filesystem
*     speed, but also on disk fragmentation. For a more reliable test of your HD use
*     other programs.
*.
*   BUGS
*     No known bugs.
*
****************************************************************************
*/
ULONG Test_Read(STRPTR filename,int precision,BOOL freeze,BOOL mt)
{
  struct timeval *time1,*time2;
  ULONG buf;
  int c;
  ULONG secs,time;
  BPTR file=(BPTR) 0;
  char tmpstr[20];

  time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);

  if ( buf = POSBB_AllocMem(262144,0))
  {
    if (file = (BPTR) Open(filename,MODE_OLDFILE))
    {
#ifndef NOFORBID
      if (freeze == TRUE) Forbid();
#endif
    if (mt)
      {
	printf("Press RETURN to start");
	getchar();
      }
      else  GetSysTime(time1);   /* This gets the system time using timer.device. It is opened by posbb.c */

      for (c=0;c<20*precision;c++)
      {
      Read(file,buf,262144);
      }
if (mt)
	{
	  DisplayBeep();
	  printf("Test finished. Type in the number of seconds taken:");
	  secs = atoi(gets(tmpstr));
	}
	else GetSysTime(time2);
#ifndef NOFORBID
      if (freeze == TRUE) Permit();
#endif
      Close(file);
    }
    POSBB_FreeMem(buf,262144);
  }
  else return TRUE;
  if (mt) time = secs * 1000;
  else
  {
    SubTime(time2,time1);
    time = (time2->tv_secs)*1000+(time2->tv_micro)/1000;
  }
  POSBB_FreeMem(time1,sizeof(struct timeval));
  POSBB_FreeMem(time2,sizeof(struct timeval));
  if (file = (BPTR) 0) return TRUE;
  else return time;
} 
/* qsort isn't finished,yet
int my_comp(s1,s2)
char **s1,**s2;
{
   return(strcmp(*s1, *s2));
}
ULONG Test_qsort(precision)
int precision;
{
ULONG time,secs; int c;
  struct timeval *time1,*time2;
  if (freeze == TRUE) Forbid();
  GetSysTime(time1);
  for(c = 0;c<100*precision;c++){
  qsort(StrList,1000,sizeof(char *),my_comp);
  }
  GetSysTime(time2);
  if (freeze == TRUE) Permit();
  return (time2->tv_secs);
} */
