/* @(#)osatest.c	19.1 (ES0-DMD) 02/25/03 14:33:04 */
/*===========================================================================
  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	osaTEST
.VERSION 1.0	06-Oct-1987: Creation
.VERSION 1.1	22-Jun-1989: Test if length not exceeded...
.AUTHOR         Francois Ochsenbein [ESO-IPG]
.KEYWORDS       Test of osa routines
.ENVIRONMENT    
.COMMENTS       

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

#include   <atype.h>
#include   <osfile.h>
#include   <osdefos.h>
#include   <macrogen.h>

#ifndef IO_MAX
#define IO_MAX	32768
#endif

char *osmsg();

#define osaflush	osawait

static char msg[132], charop[132];
static char record[IO_MAX] = "abcdefghijklmnopqrstuvwxyz";
static int f;

static struct {
	char buf[80];
	int  lim;
	} embedded;

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

  puts("==== Testing OSA (Ascii file access) routines ====");
  puts("     Type ? for Help");

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

      case 'C':		/* Close */
      	st = osaclose(f);	break;
      
      case 'F':		/* Flush */
      	st = osaflush(f);	break;
      
#if 0
      case 'i': case 'I':		/* Retrieve Info	*/
	st = osdinfo(f, &info);
	printf("Info for: %d (%s)\n\t", 
		f,			/* File Number	*/
		info.filename);            /* file name */
	printf("\tsize=%d, ", 
		info.filesize);		/* file size in BYTES */
	printf("date=%d, ", 
		info.date);           	/* creation date */
	printf("uid=%X,prot=%3o, ss=%d\n",
		info.owner,			/* owner (UID) id */
		info.protection,		/* protection */
		info.blocksize);		/* sector_size */
/*
	printf("Seconds elapsed since creation: %d\n",	oshtime(0) - info.date);
*/
	break;
#endif

      case 'L':		/* List File */
      	for (i = atoi(&msg[1]); --i >=0; )
      	{	if (osaread(f, record, 1) == 1)
	      		osawrite(1, record, 1);
      	}
      	break;
      
      case 'O':		/* Open */
	i = 1;
	switch(toupper(msg[i]))
	{ case ' ':  op = READ; break;
	  default:   op = READ; i = 2; break;	/* Read */
          case EOS:  printf("File Name: ");	gets(&msg[i]); break;
	  case 'W':  op = WRITE; i = 2; break;
	  case 'A':  op = APPEND; i = 2; break;
	  case 'M':  op = READ_WRITE; i = 2; break;
	}
	while (msg[i] == ' ')	i++;	/* Skip leading blanks */
	if (msg[i] == EOS){ printf("File Name: "); gets(&msg[i]); }
	printf("VMS options F n or V n: "); gets(charop);
	if (charop[0])	osfop(charop[0], atoi(charop+1));
	st = osaopen(&msg[i], op);
	if (st >= 0)	f = st;
	break;

      case '@':		/* Select File Number */
        f = atoi(&msg[1]);
        printf("Selected file is %d\n", f);
        continue;
      
      case 'R':		/* Read n bytes */
      	n = atoi(&msg[1]);			/* n */
      	embedded.lim = -1;
      	if (n < 2)	 i=1, n = sizeof(embedded.buf),
      		st = osaread(f, embedded.buf, n);
      	else	i=0, st = osaread(f, record, n);
      	if (st < 0)
      	{	if (*osmsg() == 0)	{ puts("====EOF===="); continue; }
      		else			break; /* Error */
      	}
      	if (st > n)	puts("====Truncated Text====");
      	if (i)
      	{	puts(embedded.buf);
      		if (embedded.lim != -1) 
      			printf("****> Number -1 changed to %d\n", embedded.lim);
      	}
      	else	puts(record);
        break;
        
#if 0
      case 'D':		/* Dump n bytes */
      	l = atoi(&msg[1]);			/* n */
      	n = osbtell(f);
      	st = osbread(f, record, l);
      	if (st < 0)
      	{	if (*osmsg() == 0)	{ puts("====EOF===="); continue; }
      		else			break; /* Error */
      	}
      	if (st > l)	puts("====Truncated Text====");
	dump(n, record, l);
	break;
#endif
      
      case 'S':		/* 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 = osaseek(f, n, op);
	break;
      
#if 0
      case 'M':		/* Truncate File */
	st = osacut(f);
	break;
#endif
      
      case 'T':		/* Tell */
	st = osatell(f);
	break;
      
      case 'W':		/* Write text */
	if (msg[1] == EOS) { printf("Text: ") ; gets(&msg[2]);}
      	st = osawrite(f, &msg[2], strlen(&msg[2]));
      	break;

      case 'Z':		/* Benchmark for Read / Write	*/
	osaseek(f, 0, FILE_START);
	n = 0;
	for (i = 0; i < 80; i++)	record[i] = i + '~'- 79;
	record[80] = EOS;
#if 0
	oshela(INIT_CLOCK);
	oshcpu(INIT_CLOCK);
#endif
	switch(toupper(msg[1]))
	{ 
	  case 'W':	/* Writing Test of 80-byte records */
		record[80] = '\n';
		printf("Starting writing 1000 records of 80 bytes...\n");
		for (i=1000, st=0; (--i>=0) && (st>=0); )
			st = osawrite(f,record,81);
		n = (999-i)*80;
		break;
	  case 'R':	/* Reading Complete File */
		for (n=0, st=0; (st>=0); n += st)
			st = osaread(f,record,81);
		break;
	}
#if 0
	printf("Total bytes read/written: %d --- CPU: %d/100s, Elapsed: %ds\n", 
		n, oshcpu(GET_CLOCK), oshela(GET_CLOCK));
#endif
    }
    printf("Status is %d", st);
    if (st < 0) printf(": %s",osmsg());
    puts("");
  }
  ospexit(0);
}

help()
{
  printf("Current file is %d\n", f);
  puts("Possibilities are: ? Help");
  puts("                   @ f              select File f");
  puts("                   C                Close Current File");
#if 0
  puts("                   D n              Dump n bytes");
#endif
  puts("                   F                Flush File");
  puts("                   I                Display info about file");
  puts("                   L n              List n bytes to stdout");
  puts("                   OR|OW|OA|OM name Open (Read Write Modify Append)");
  puts("                   R n              Read n bytes");
  puts("                   SS|SE|SC n       Seek Start|End|Current to offset n");
  puts("                   T                Tell position of Current file");
  puts("                   W text           Write (put) text");
  puts("                   ZR|ZW            Benchmark Read/Write/Put/Get");
  return(0);
}
dump(pos, str, len)
	long pos;	/* IN: Present file position */
	char *str;	/* IN: Record to dump	*/
	int  len;	/* IN: Length of record to dump */
{
	static char line[80];
	char *p, *pe;
	long x;
	static char xdig[] = {'0','1','2','3','4','5','6','7','8','9',
			'A','B','C','D','E','F'};
	int i;
  
  for (p = str, pe = str + len; p < pe; pos += 20)
  {	for (i = 0; i < sizeof(line)-1; i++)	line[i] = ' ';
  	i = 7; line[i] = ':';
  	for (x = pos; (i>0) && (x>0); x /= 10)
  		line[--i] = (x%10) + '0';
  	for (i=0; (i < 20); i++, p++, len--)
	{	if (len <= 0)		continue;
		if (isprint(*p))	line[i+59] = *p;
		else			line[i+59] = '~';
		line[9 +i*2+i/2] = xdig[(*p&0xf0)>>4];
		line[10+i*2+i/2] = xdig[(*p&0x0f)];
	}
	line[58] = ':';
	line[79] = '\0';
	puts(line);
  }
}
