// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: testprog.cpp // Compiler Used: MSVC40, egcs-2.90.29, HP CPP 10.24 // Produced By: Doug Gaer // File Creation Date: 09/20/1999 // Date Last Modified: 06/21/2000 // Copyright (c) 2000 Dougas M. Gaer // ----------------------------------------------------------- // // ------------- Program Description and Details ------------- // // ----------------------------------------------------------- // /* The VBS C++ classes are copyright (c) 2000, by Douglas M. Gaer. All those who put this code or its derivatives in a commercial product MUST mention this copyright in their documentation for users of the products in which this code or its derivative classes are used. Otherwise, you have the freedom to redistribute verbatim copies of this source code, adapt it to your specific needs, or improve the code and release your improvements to the public provided that the modified files carry prominent notices stating that you changed the files and the date of any change. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE, YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. This is a test program for the device cache classes. */ // ----------------------------------------------------------- // #include "vbsfile.h" void SkipToEol(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; SkipToEol(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(vbsFile *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); vbStream server; vbsSocket_t remote_socket; unsigned byte_count = 0; cout << "Initializing the VB stream server..." << endl; if(server.StreamServer(port) != 0) { cout << server.SocketExceptionMessage() << endl; return 1; } // Get the host name assigned to this machine char hostname[vbsMAX_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 vbBlockHeader vb; if(server.ReadClientHeader(vb) != 0) { cout << server.SocketExceptionMessage() << endl; return 1; } // Get the client info char client_name[vbsMAX_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 = vb.Status; __SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8); switch(status) { // Process each block of data case vbSendBlock : cout << "Reading " << vb.Length << " bytes from " << client_name << " remote port " << r_port << endl << flush; if(!dev->CopyStreamSocketToFile(&server, vb)) { cout << "Error copying from stream to the file." << endl; return 0; } byte_count += (__ULWORD__)vb.Length; break; case vbKillServer: 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(vbsFile *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); vbDatagram server; unsigned byte_count = 0; cout << "Initializing the VB datagram server..." << endl; if(server.DatagramServer(port) != 0) { cout << server.SocketExceptionMessage() << endl; return 1; } // Get the host name assigned to this machine char hostname[vbsMAX_NAME_LEN]; if(server.HostName(hostname) != 0) { cout << server.SocketExceptionMessage() << endl; return 1; } cout << "Opening VB 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 vbBlockHeader vb; if(server.ReadClientHeader(vb) != 0) { cout << server.SocketExceptionMessage() << endl; return 1; } // Get the client info char client_name[vbsMAX_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 = vb.Status; __SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8); switch(status) { // Process each block of data case vbSendBlock : cout << "Reading " << vb.Length << " bytes from " << client_name << " remote port " << r_port << endl << flush; if(!dev->CopyDatagramSocketToFile(&server, vb)) { cout << "Error copying from stream to the file." << endl; return 0; } byte_count += (__ULWORD__)vb.Length; break; case vbKillServer: 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(vbsFile *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(vbsFile *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; vbSerialCommServer server; cout << "Initializing the VB serial port server..." << endl; int rv = server.InitCommServer(port); if(rv != vbSerialComm::scomm_NO_ERROR) { cout << server.SerialCommExceptionMessage() << endl; return; } cout << "Opening VB serial port server on " << (char*)port << endl; int server_up = 1; while(server_up) { // Wait for a block header. vbBlockHeader vb; if(server.ReadHeader(vb) != 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 = vb.Status; __SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8); switch(status) { // Process each block of data case vbSendBlock : cout << "Reading variable block " << vb.Length << " bytes in length" << endl; if(!dev->CopySerialPortToFile(&server, vb)) { cout << "Error copying from serial port to the file." << endl; return; } byte_count += (__ULWORD__)vb.Length; break; case vbKillServer: 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; vbsFile dev(cache_size); // Device cache used to process a file cout << "Creating a device cache using " << cache_size << " cache buckets." << endl; cout << "Reserving " << (sizeof(MEMTYPE) * cache_size) << " bytes of memory." << endl; cout << "Number of cache buckets in use = " << dev.BucketsInUse() << endl; cout << endl; switch(server_type) { case vbSOCKET_STREAM_SERVER: CopyStreamSocketToFile(&dev); Menu(); break; case vbSOCKET_DATAGRAM_SERVER: CopyDatagramSocketToFile(&dev); Menu(); break; case vbSOCKET_SERIAL_PORT_SERVER: CopySerialPortToFile(&dev); Menu(); break; case vbSOCKET_LOCAL_FILE_SYSTEM: CopyFileToFile(&dev); Menu(); break; default: break; } } int main() { Menu(); char key; int rv = 1; while(rv) { if (!cin) { // Input is in fail state SkipToEol(cin); // Go to end of line if (!cin) { // Can't fix cout << "Input stream is broken" << endl; return 0; } } cout << endl; cout << '>'; cin >> key; if (!cin) continue; // Fix at top of loop switch(key) { case 'd' : case 'D' : SkipToEol(cin); SetupServer(vbSOCKET_DATAGRAM_SERVER); break; case 'f' : case 'F' : SkipToEol(cin); SetupServer(vbSOCKET_LOCAL_FILE_SYSTEM); break; case 'p' : case 'P' : SkipToEol(cin); SetupServer(vbSOCKET_SERIAL_PORT_SERVER); break; case 's' : case 'S' : SkipToEol(cin); SetupServer(vbSOCKET_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 --------- // // ------------------------------- //