/*	RQmanager - Record Queue Manager
*/

#include	<std.h>
#include	<stdio.h>
#include	<qioret.h>
#include	"recqueue.h"

#define	LINE_LENGTH	78

static TEXT	command[80];
static QUEUE	*queue = NULL;
static TEXT	buffer[Q_BUF_SIZE];
static INTEGER	rec_size = 16;

main ()
{
STRING	string;
INTEGER	count, amount;
LONG	location;

while (printf ("RQM> "), gets (command))
    {
    switch (toupper (*command))
	{
	case 'S':

	if (isdigit (*(string = nxtword (command))))
	    rec_size = atoi (string);
	else if (queue)
	    printf ("File record size is %d bytes.\n", RQ_size (queue));
	else
	    printf ("Record size desired is %d bytes.\n", rec_size);
	break;

	case 'O':

	if (*(string = nxtword (command)))
	    {
	    if (queue)
		printf ("Queue file already open.\n");
	    else if (! (queue = RQ_open (string, rec_size)))
		{
		printf ("%s\n", ioerrmsg (IO_ERROR));
		if (IO_ERROR == IE_BAD)
		    printf ("Requested record size is %d bytes.\n", rec_size);
		if (IO_ERROR == QUEUE_BUSY)
		    printf ("The file is being used by another task.\n");
		}
	    else
		rec_size = RQ_size (queue);
	    }
	else if (queue)
	    printf ("%s\n", fgetname (queue->file, string));
	else
	    nofile:
	    printf ("No queue file open.\n");
	break;

	case 'T':

	if (queue)
	    printf ("There are %d records in the queue.\n",
		RQ_total_records (queue));
	else
	    goto nofile;
	break;

	case 'C':

	if (queue)
	    {
	    if (! RQ_close (queue))
		printf ("%s\n", ioerrmsg (IO_ERROR));
	    queue = NULL;
	    }
	else
	    goto nofile;
	break;

	case 'R':

	if (*(string = nxtword (command)))
	    {
	    zero (buffer, rec_size);
	    for (count = 0; count < rec_size;)
		{
		if (! *string)
		    break;
		else if (*string == '-' && ! *(string + 1) &&
		    ! (printf ("more> "), gets (string = command)))
			goto done;
		else if (*string == '\\' && isdigit (*(string + 1)))
		    {
		    buffer[count++] = atoi (++string);
		    while (isdigit (*string))
			string++;
		    }
		else
		    buffer[count++] = *string++;
		}
	    }
	else
	    {
	    for (count = 0, amount = LINE_LENGTH; count < rec_size; count++)
		{
		if (! amount)
		    {
		    printf ("\n");
		    amount = LINE_LENGTH;
		    }
		if (buffer[count] < ' ' || buffer[count] > '~')
		    {
		    if (amount < 5)
			{
			printf ("\n");
			amount = LINE_LENGTH;
			}
		    printf ("<%3d>", buffer[count] & IS_BYTE);
		    amount -= 5;
		    }
		else
		    {
		    printf ("%c", buffer[count]);
		    amount--;
		    }
		}
	    if (amount != LINE_LENGTH)
		printf ("\n");
	    }
	break;

	case 'G':
	case 'P':

	if (queue)
	    {
	    if (isdigit (*(string = nxtword (command))))
		{
		count = atoi (string);
		if (! (string = RQ_get (queue, count)))
		    {
		    printf ("%s\n", ioerrmsg (IO_ERROR));
		    if (IO_ERROR == EOQ)
			printf ("No such record.\n");
		    }
		else
		    {
		    if (toupper (*command) == 'P')
			{
			copy (string, buffer, rec_size);
			if (! RQ_update (queue))
			    printf ("%s\n", ioerrmsg (IO_ERROR));
			}
		    else
			copy (buffer, string, rec_size);
		    }
		}
	    else
		printf ("Which record?\n");
	    }
	else
	    goto nofile;
	break;

	case 'D':

	switch (toupper (command[2]))
	    {
	    case 'Q':

	    if (queue)
		{
		if (! RQ_dequeue (queue, buffer, rec_size))
		    printf ("%s\n", ioerrmsg (IO_ERROR));
		}
	    else
		goto nofile;
	    break;

	    case 'L':

	    if (queue)
		{
		if (isdigit (*(string = nxtword (command))))
		    {
		    if (! RQ_delete (queue, atoi (string)))
			printf ("%s\n", ioerrmsg (IO_ERROR));
		    }
		else
		    printf ("Which record?\n");
		}
	    else
		goto nofile;
	    break;

	    default:

	    goto syntax;
	    break;
	    }
	break;

	case 'E':

	if (queue)
	    {
	    if (! RQ_enqueue (queue, buffer, rec_size))
		printf ("%s\n", ioerrmsg (IO_ERROR));
	    }
	else
	    goto nofile;
	break;

	case 'L':

	if (queue)
	    {
	    if (*(string = nxtword (command)))
		{
		switch (toupper (*string))
		    {
		    case 'Q':

		    list_queue:
		    printf ("\n\
queue->file(name)    - %s\n\
       location      - %10ld\n\
       end           - %10ld\n\
       record_number - %u\n\
       record        - %5u\n\
       &buffer       - %5u\n\
       update        - %s\n",
fgetname (queue->file, string + 2),
queue->location,
queue->end,
queue->record_number,
queue->record,
&queue->buffer,
(queue->update ? "TRUE" : "FALSE"));
		    if (! *string)
			goto list_header;
		    break;

		    case 'H':

		    list_header:
		    printf ("\n\
queue->control.head  - %10ld\n\
               tail  - %10ld\n\
               empty - %10ld\n\
               record_size - %d\n\
               total_records - %u\n",
queue->control.head,
queue->control.tail,
queue->control.empty,
queue->control.record_size,
queue->control.total_records);
		    break;

		    case 'R':

		    for (
			count = 0, location = queue->control.head;
			count < queue->control.total_records;
			count++
			)
			{
			if (! RQ_get (queue, count))
			    {
			    printf ("%s\n", ioerrmsg (IO_ERROR));
			    break;
			    }
			else
			    {
			    printf ("%5d: %10ld<-%10ld->%ld\n", count,
				queue->record->previous, location,
				queue->record->following);
			    location = queue->record->following;
			    }
			}
		    break;

		    default:

		    goto syntax;
		    break;
		    }
		}
	    else
		goto list_queue;
	    }
	else
	    goto nofile;
	break;

	default:

	syntax:
	printf ("\n\
Open [<filename>]\n\
    (default is queue filename)\n\
Close\n\
Size [<record size>]\n\
    (default is current record size)\n\
Total records\n\
Get <record number>\n\
Put <record number>\n\
DELete <record number>\n\
Enqueue\n\
DEQueue\n\
Record [<data>]\n\
    \\<value> enters that data value\n\
    - at EOL indicates more data to follow\n\
    (default is record buffer dump)\n\
List [Queue | Header | Trace]\n\
    (default is Queue and Header listings)\n\
^Z (exit)\n\n");
	break;
	}
    }
done:
if (queue && ! RQ_close (queue))
    printf ("%s\nWhile closing the queue file.\n",
	ioerrmsg (IO_ERROR));
exit ();
}
