// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: testprog.cpp
// C++ Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: glNET Software
// File Creation Date: 09/20/1999
// Date Last Modified: 05/25/2001
// Copyright (c) 2001 glNET Software
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
This is a test program for the device cache classes.
*/
// ----------------------------------------------------------- //
#include "gxsfile.h"
#ifdef __MSVC_DEBUG__
#include "leaktest.h"
#endif
void ClearInputStream(istream &s)
{
char c;
s.clear();
while(s.get(c) && c != '\n') { ; }
}
void InputString(char *mesg, MemoryBuffer &s)
{
cout << mesg << ": ";
char buf[255];
for(int i = 0; i < 255; i++) buf[i] = 0;
cin >> buf;
s.Load(buf, (strlen(buf) + 1));
s[s.length()] += '\0'; // Null terminate the string
}
void InputInt(char *mesg, int &i)
{
cout << mesg << ": ";
cin >> i;
ClearInputStream(cin);
}
void Menu()
{
cout << endl;
cout << "(?) Display this menu" << endl;
cout << "(D) Copy a Datagram Socket to a disk file" << endl;
cout << "(F) Copy a disk file to another disk file" << endl;
cout << "(P) Copy a Serial port to a disk file" << endl;
cout << "(Q) Quit this program" << endl;
cout << "(S) Copy a Stream Socket to a disk file" << endl;
cout << endl;
}
int CopyStreamSocketToFile(gxsFile *dev)
// Copies data from a stream socket to the memory cache
// and flushes the cache buffers to a disk file.
{
MemoryBuffer s;
InputString("Enter the name of the output file", s);
if(!dev->OpenOutputFile((char *)s)) {
cout << "Could not open the " << (char *)s << " file" << endl;
return 0;
}
int port;
InputInt("Enter the server's port number", port);
gxStream server;
gxsSocket_t remote_socket;
unsigned byte_count = 0;
cout << "Initializing the GX stream server..." << endl;
if(server.StreamServer(port) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
// Get the host name assigned to this machine
char hostname[gxsMAX_NAME_LEN];
if(server.HostName(hostname) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
cout << "Opening stream server on host " << hostname << endl;
int server_up = 1;
cout << "Listening on port " << port << endl;
remote_socket = server.Accept();
if(remote_socket < 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
while(server_up) {
// Read the block following a client connection
gxBlockHeader gx;
if(server.ReadClientHeader(gx) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
// Get the client info
char client_name[gxsMAX_NAME_LEN]; int r_port = -1;
server.GetClientInfo(client_name, r_port);
cout << client_name << " connecting on port " << r_port << endl;
// Read the status byte to determine what to do with this block
__ULWORD__ block_status = gx.block_status;
__SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8);
switch(status) {
// Process each block of data
case gxSendBlock :
cout << "Reading " << gx.block_length << " bytes from " << client_name
<< " remote port " << r_port << endl << flush;
if(!dev->CopyStreamSocketToFile(&server, gx)) {
cout << "Error copying from stream to the file." << endl;
return 0;
}
byte_count += (__ULWORD__)gx.block_length;
break;
case gxKillServer:
cout << "Client shutdown the server" << endl;
server.Close();
server_up = 0;
break;
default:
cout << "Only accepting raw data blocks" << endl;
cout << "The \"" << status << "\" command was rejected" << endl;
server.CloseRemoteSocket();
break;
}
}
cout << "Number of cache buckets in use = " << dev->BucketsInUse() << endl;
dev->Flush(); // Flush all the cache buffers before exiting
dev->CloseOutputFile();
cout << "Exiting..." << endl;
return 1;
}
int CopyDatagramSocketToFile(gxsFile *dev)
// Copies data from a stream socket to the memory cache
// and flushes the cache buffers to a disk file.
{
MemoryBuffer s;
InputString("Enter the name of the output file", s);
if(!dev->OpenOutputFile((char *)s)) {
cout << "Could not open the " << (char *)s << " file" << endl;
return 0;
}
int port;
InputInt("Enter the server's port number", port);
gxDatagram server;
unsigned byte_count = 0;
cout << "Initializing the GX datagram server..." << endl;
if(server.DatagramServer(port) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
// Get the host name assigned to this machine
char hostname[gxsMAX_NAME_LEN];
if(server.HostName(hostname) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
cout << "Opening GX datagram server on host " << hostname << endl;
// Find out what port was really assigned
int assigned_port;
if(server.PortNumber(assigned_port) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
cout << "Port assigned is " << assigned_port << endl;
int server_up = 1;
while(server_up) {
// Read the block following a client connection
gxBlockHeader gx;
if(server.ReadClientHeader(gx) != 0) {
cout << server.SocketExceptionMessage() << endl;
return 1;
}
// Get the client info
char client_name[gxsMAX_NAME_LEN]; int r_port = -1;
server.GetClientInfo(client_name, r_port);
cout << client_name << " connecting on port " << r_port << endl;
// Read the status byte to determine what to do with this block
__ULWORD__ block_status = gx.block_status;
__SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8);
switch(status) {
// Process each block of data
case gxSendBlock :
cout << "Reading " << gx.block_length << " bytes from " << client_name
<< " remote port " << r_port << endl << flush;
if(!dev->CopyDatagramSocketToFile(&server, gx)) {
cout << "Error copying from stream to the file." << endl;
return 0;
}
byte_count += (__ULWORD__)gx.block_length;
break;
case gxKillServer:
cout << "Client shutdown the server" << endl;
server.Close();
server_up = 0;
break;
default:
cout << "Only accepting raw data blocks" << endl;
cout << "The \"" << status << "\" command was rejected" << endl;
break;
}
}
cout << "Number of cache buckets in use = " << dev->BucketsInUse() << endl;
dev->Flush(); // Flush all the cache buffers before exiting
dev->CloseOutputFile();
cout << "Exiting..." << endl;
return 1;
}
void CopyFileToFile(gxsFile *dev)
{
MemoryBuffer in, out;
InputString("Enter the name of the input file", in);
if(!dev->OpenInputFile(in)) {
cout << "Cannot open the specified file!" << endl;
return;
}
InputString("Enter the name of the output file", out);
if(!dev->OpenOutputFile(out)) {
cout << "Cannot open the specified file!" << endl;
return;
}
unsigned byte_count = 0;
if(!dev->CopyFileToFile(byte_count)) {
cout << "Error copying file." << endl;
return;
}
cout << "Number of cache buckets in use = " << dev->BucketsInUse() << endl;
cout << "Flushing the device cache..." << endl;
dev->Flush();
dev->CloseInputFile(); dev->CloseOutputFile();
cout << "Finished processing file." << endl;
cout << "Byte count = " << byte_count << endl;
}
void CopySerialPortToFile(gxsFile *dev)
{
MemoryBuffer out, port;
InputString("Enter the name of the serial device", port);
InputString("Enter the name of the output file", out);
if(!dev->OpenOutputFile(out)) {
cout << "Cannot open the specified file!" << endl;
return;
}
unsigned byte_count = 0;
gxSerialCommServer server;
cout << "Initializing the GX serial port server..." << endl;
int rv = server.InitCommServer(port);
if(rv != gxSerialComm::scomm_NO_ERROR) {
cout << server.SerialCommExceptionMessage() << endl;
return;
}
cout << "Opening GX serial port server on " << (char*)port << endl;
int server_up = 1;
while(server_up) {
// Wait for a block header.
gxBlockHeader gx;
if(server.ReadHeader(gx) != 0) {
cout << server.SerialCommExceptionMessage() << endl;
return;
}
cout << "Client connecting on " << (char *)port << endl;
// Read the status byte to determine what to do with this block
__ULWORD__ block_status = gx.block_status;
__SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8);
switch(status) {
// Process each block of data
case gxSendBlock :
cout << "Reading database block " << gx.block_length
<< " bytes in length" << endl;
if(!dev->CopySerialPortToFile(&server, gx)) {
cout << "Error copying from serial port to the file." << endl;
return;
}
byte_count += (__ULWORD__)gx.block_length;
break;
case gxKillServer:
cout << "Client shutdown the server" << endl;
server.Close();
server_up = 0;
break;
default:
cout << "Only accepting raw data blocks" << endl;
cout << "The \"" << status << "\" command was rejected" << endl;
break;
}
}
cout << "Number of cache buckets in use = " << dev->BucketsInUse() << endl;
cout << "Flushing the device cache..." << endl;
dev->Flush();
dev->CloseOutputFile();
cout << "Finished processing file." << endl;
cout << "Byte count = " << byte_count << endl;
}
void SetupServer(int server_type)
{
int cache_size = 1024;
gxsFile dev(cache_size); // Device cache used to process a file
cout << "Creating a device cache using " << cache_size
<< " cache buckets." << endl;
cout << "Reserving " << (sizeof(gxDeviceBucket) * cache_size)
<< " bytes of memory." << endl;
cout << "Number of cache buckets in use = " << dev.BucketsInUse() << endl;
cout << endl;
switch(server_type) {
case gxSOCKET_STREAM_SERVER:
CopyStreamSocketToFile(&dev);
Menu();
break;
case gxSOCKET_DATAGRAM_SERVER:
CopyDatagramSocketToFile(&dev);
Menu();
break;
case gxSOCKET_SERIAL_PORT_SERVER:
CopySerialPortToFile(&dev);
Menu();
break;
case gxSOCKET_LOCAL_FILE_SYSTEM:
CopyFileToFile(&dev);
Menu();
break;
default:
break;
}
}
int main()
{
#ifdef __MSVC_DEBUG__
InitLeakTest();
#endif
Menu();
char key;
int rv = 1;
while(rv) {
if (!cin) {
ClearInputStream(cin);
if (!cin) {
cout << "Input stream error" << endl;
return 0;
}
}
cout << endl;
cout << '>';
cin >> key;
if (!cin) continue;
switch(key) {
case 'd' : case 'D' :
ClearInputStream(cin);
SetupServer(gxSOCKET_DATAGRAM_SERVER);
break;
case 'f' : case 'F' :
ClearInputStream(cin);
SetupServer(gxSOCKET_LOCAL_FILE_SYSTEM);
break;
case 'p' : case 'P' :
ClearInputStream(cin);
SetupServer(gxSOCKET_SERIAL_PORT_SERVER);
break;
case 's' : case 'S' :
ClearInputStream(cin);
SetupServer(gxSOCKET_STREAM_SERVER);
break;
case 'q' : case 'Q' :
rv = 0;
break;
case '?' :
Menu();
break;
default:
cout << "Unrecognized command" << endl;
cout << endl;
}
}
return 0;
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //