/* @(#)osutest.c	19.1 (ES0-DMD) 02/25/03 14:33:05 */
/*===========================================================================
  Copyright (C) 1995 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++   
.TYPE           Program
.LANGUAGE       C
.IDENTIFICATION	osuTEST
.VERSION 1.0	06-Oct-1987: Creation
.AUTHOR         Francois Ochsenbein [ESO-IPG]
.KEYWORDS       Test of osu routines
.ENVIRONMENT    
.COMMENTS       

-------------------------------------------------------------------------*/

#include   <osdev.h>
#include   <osfile.h>		/* To use timing functions	*/
#include   <atype.h>
#include   <macrogen.h>

#define IO_MAX	(90*512)

static char msg[8192];
static int f, fd;
/* static struct devstat info; */
static char buffer[IO_MAX];
static char c1[132];
static char c0[132];

char *osmsg(), *oshenv(), *osuname();
long oshtime(), oshgmt();


main()
{ long int st, n, sec;
  char *p; 
  int i, l, op;
  double ft;

  puts("==== Testing OSU (special Units access) routines ====");
  puts("     Type ? for Help");

  while(1)
  { printf("Your choice: "); if (!gets(msg)) break;
    if (msg[0] == '.')  strcpy(msg,c0);
    else                strcpy(c0,msg);
    switch(toupper(msg[0]))
    { default: puts("*** Uknown Command!");
      case 'H': help(); continue;

      case 'O':		/* Open */
	switch(toupper(msg[1]))
	{ default:   op = READ; break;	/* Read */
	  case 'W':  op = WRITE; break;
	  case 'A':  op = APPEND; break;
	  case 'M':  op = READ_WRITE; break;
	}
	for (i=2; isspace(msg[i]); i++) ;
	switch(toupper(msg[i]))
	{ case 'D':	l = 1024;	/* Default Density */	break;
	  default : 	l = 0; break;
	}
	printf("Density or Sector Size [%d]: ", l); gets(c1);
	if (c1[0])	l = atoi(c1);
	st = osuopen(&msg[i], op, l);
	if (st >= 0)	f = st, printf("Blocksize of unit is %d bytes\n", 
				osubsize(f));
	break;

      case 'C':		/* Close */
      	st = osuclose(f, toupper(msg[1]) == 'D');	break;
      

      case 'i': case 'I':		/* Retrieve Info	*/
	printf("Info for: %d (%s)\t", 
		f,			/* File Number	*/
		osuname(f));            /* file name */
#if 0
	printf("density=%d, ", 
		info.density);		/* file size in BYTES */
	printf("device=%c, ", 
		info.device_type);           	/* creation date */
#endif
	printf("bsize=%d, ", 
		osubsize(f));		/* Block file size in BYTES */
	puts("");
	break;

      case 'R':		/* Read n bytes */
      	n = get_bytes(&msg[1]);			/* n */
      	st = osuread(f, buffer, n);
      	if (st < 0)
      	{	if (*osmsg() == 0)	{ puts("====EOF===="); continue; }
      		else			break; /* Error */
      	}
      	if (st > n)	puts("====Truncated Text====");
	write(1, buffer, st);
	puts("");
	break;
      
      case 'P':		/* Write text */
	if (msg[1] == EOS) { printf("Text: ") ; gets(&msg[2]);}
	/* Complete with template when size required */
	i = strlen(&msg[2]);
	n = osubsize(f);
	while(i%n)	msg[2+i] = ' ', i++;
      	st = osuwrite(f, &msg[2], i);
      	break;

      case 'W':		/* Write a file */
	if (msg[1] == EOS) { printf("File: ") ; gets(&msg[2]);}
	fd = osdopen(&msg[2], READ);
	if (fd < 0) { printf("Bad File %s: %s\n", &msg[2], osmsg()); break;}
	printf("Specify your prefered block size in Kb: "); gets(msg);
	n = atoi(msg);
	if (n <= 0)	n = 1; n *= 1024;
	while ((l = osdread(fd, buffer, n)) > 0)
	      	st = osuwrite(f, buffer, l);
      	if (st <= 0)	break;

      case 'M':		/* Write TMs */
      	st = osufclose(f);
      	break;

      case '@':		/* Select File Number */
        f = atoi(&msg[1]);
        printf("Selected file is %d\n", f);
        continue;
      
      case 'F':		/* File Seek n */
	switch(toupper(msg[1]))
	{ default:   op = FILE_START; break;	/* From Start */
	  case 'E':  op = FILE_END; break;
	  case 'C':  op = FILE_CURRENT; break;
	}
      	n = atol(&msg[2]);			/* n */
	st = osufseek(f, n, op);
	break;
      
      case 'S':		/* Block Seek n */
	switch(toupper(msg[1]))
	{ default:   op = FILE_START; break;	/* From Start */
	  case 'E':  op = FILE_END; break;
	  case 'C':  op = FILE_CURRENT; break;
	}
      	n = atol(&msg[2]);			/* n */
	st = -1; /*osubseek(f, n, op);*/
	break;
      
      case 'T':		/* Tell */
	st = -1; /* osufeet(f); */
	ft = st; ft /= 1.e3;		/* Tell Feet */
	st = osuftell(f);
	n = -1; /*osubtell(f);		/* Tell Block */
	printf("Now in File %d, Block %d - Tape length %8.3ft\n", 
		st, n, ft);
	break;
      
      case 'Z': 	/* T E S T performances reading  / writing*/
	l = atoi(&msg[2]);	/* Number of KBytes to read */
	if (l < 1)	l = 1;
	l *= 1024;
	if (l > sizeof(buffer))	l = sizeof(buffer);
	for (i=0; i<n; i++)   buffer[i] = msg[i&1];
	if (msg[1] == 'w' || msg[1] == 'W') {
		printf("Number of Kbytes to write: ");
		gets(msg); n = atoi(msg) * 1024;
		if (n < l) n = l;
		n /= l;
		printf("Starting writing %d blocks of %d bytes each...\n",n, l);
		sec = oshtime();
		for (i=0; i<n; i++)
			if ((st = osuwrite(f, buffer, l)) <= 0)	break;
		printf("%d bytes written in %ds\n", i*l, oshtime() - sec);
	} else {
		printf("Number of Kbytes to read: ");
		gets(msg); n = atoi(msg) * 1024;
		if (n < l) n = l;
		n /= l;
		printf("Starting reading %d blocks of %d bytes each...\n",n, l);
		sec = oshtime();
		for (i=0; i<n; i++)
			if ((st = osuread(f, buffer, l)) <= 0)	break;
		printf("%d bytes read in %ds\n", i*l, oshtime() - sec);
	}
	break;

    }
    printf("Status is %d", st);
    if (st < 0) printf(": %s",osmsg());
    puts("");
  }
}

help()
{
  printf("Current file is %d\n", f);
  puts("Possibilities are: ? Help");
  puts("                   @ f :              select Unit f");
  puts("                   C[d]               Close [with dismount] Current Unit");
  puts("                   FS|FE|FC n:        File Seek Start|End|Current");
  puts("                   I                  Display info about Unit");
  puts("                   M                  Close File (Write TMs)");
  puts("                   OR|OW|OA|OM  dev   Open (Read Write Modify Append)");
  puts("                   P text:            Put text");
  puts("                   R n:               Read n bytes");
  puts("                   SS|SE|SC n:        Block Seek Start|End|Current to n");
  puts("                   T :                Tell position of Current file");
  puts("                   W file             Write a complete file");
  puts("                   ZR|ZW n:           Performance Read|Write by n Kbytes");
  return(0);
}

int get_bytes(msg)
	char	*msg;	/* IN: String containing number or numberK */
{
	char	*p;
	int	k;

   for (k=0, p = msg; (k == 0) && *p; p++)
   {	if (*p == 'k')	k = 1;
	if (*p == 'K')	k = 1;
   }
   if (k)	k = 1024, *p = ' ';
   else		k = 1;
   k *= atoi(msg);
   return(k);
}
