We help IT Professionals succeed at work.

I want to Convert a program written in C++ into PERL

zoomer003
zoomer003 asked
on
#include <winsock.h>                  // Windows TCP/IP socket support
#include <stdio.h>
#include <time.h>
#include <conio.h>

// NOTE: These are from the declarations in the SimPLEX software but with the
// NO_SCENARIO state prepended to the start of the list, allowing
// this state to be flagged. This may need modification in the future to match any
// changes to the equivalent enumeration in the SimPLEX software - CHECK !!!

enum State {NO_SCENARIO, INVALID_SCENARIO, INITIALISED, ARMING, RUNNING, PAUSED, ENDED, NUM_STATES };

// Ideally the current state should be tested and commands only sent in valid states,
// (e.g. The RU (run) command is only valid with the software in the INITIALISED state.)
// However this is NOT done in this simple example program

void SelectWinSock1_1();
void CreateSocket();
bool ConnectToServer();
void SendData(char *message);
void read_data ( char *data, int max_chars, int &num_chars_read);
void tidyup();
int get_status();
      
SOCKET      theSocket;      
SOCKADDR_IN theServerAddress;
SOCKADDR_IN theClientAddress;
int         error;                        

#define IN_MSG_LEN      300      // max size for status return

int main(int argc, char* argv[])
{
  bool quit = false;
  char status_c[IN_MSG_LEN+1];      
  char mess[200];
  int num_chars_read;
  int trig_mode = 0;      // Simulator hardware trigger modes
  int sim_status = -1;      // Init to non-valid state
  bool relative_b = true; // Power adjust mode relative by default
  char scen_name[300];
  sprintf(scen_name, "my.scn");

  printf("SimPLEX remote socket interface test prog V1.01 31/1/2005\n\n");

  // Set process priority to above normal
  if ( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) )
  {
            printf ( "Warning: Error setting process priority\n" );
  }

  printf ("Selecting winsock 1.1\n");
  // Select Sockets Version 1.1 as it is more generic than Sockets 2.0
  SelectWinSock1_1();

  printf ("Creating socket\n");
  // This call creates 12 separate sockets  
  // (Sockets[NUM_CHANS]) one for each channel
  CreateSocket();

  printf ("Connecting to server... ");
  // This call connects them to the server
  if (ConnectToServer())
  {
        printf (" ...connected!\n");
  }
  else
  {
        quit = true;
        printf ("....exiting......\n");
        Sleep(3000);      // 3 secs wait so you can see exit message
  }
  while (!quit)
  {
      // Options menu:      
      printf("\n 1. Enter new scenario name\n");
      printf(" 2. Enter new trig mode\n");
      printf(" 3. Select scenario %s\n", scen_name);
      printf(" 4. Set trig mode %d, then Run scenario \n", trig_mode);
      printf(" 5. Stop simulation\n");
      printf(" 6. Rewind simulation\n");
      printf(" 7. Read simulation status\n");
      printf(" 8. Power on/off\n");
      printf(" 9. Power mode\n");
      printf(" A. Power level\n");
      printf(" B. PRN code on/off\n");
      printf(" X. Quit program\n");
      printf(">");
      
      char s[120];

      gets ( s );

      char item = s[0];

      if(item == '1') // Enter new scenario name
      {
            printf("\n Enter new scenario name (including path):\n");
            // Note: if the user wants to specify a path
            // (e.g. c:\scenarios\my_scenario\my.sim) then the '\' characters must be escaped
            // out i.e. user must actually enter c:\\scenarios\\my_scenario\\my.sim
            gets(scen_name);      // get actual data

      }

      else if (item == '2')  // Select new trig mode
      {
            printf("Enter trig mode (0=sw, 1=ext immediate, 2= ext delayed)>");
            scanf("%d", &trig_mode);
      }

      else if (item == '3')  // Select named scenario
      {
            char command[210];
            sprintf (command, "SC,%s", scen_name);
            SendData(command);
            read_data(status_c, IN_MSG_LEN, num_chars_read);      
      }

      else if(item == '4') // Set trigger mode, then run program
      {
            sprintf(mess, "TR,%1d", trig_mode);             
            SendData(mess);
            read_data(status_c, IN_MSG_LEN, num_chars_read);
            printf("Trig command sent\n");

            /*
                  send 'RUN' message,
                  the run begins on the following 1 second tick
            */
            SendData("RU");
            read_data(status_c, IN_MSG_LEN, num_chars_read);
            printf("Run command sent\n");      
            
            if (trig_mode != 0)
            {
                  printf( "**Send external start pulse to start simulation**\n");
            }
      }
      else if (item == '5')            // END message
      {            
            SendData("0 00:00:00,EN");
            read_data(status_c, IN_MSG_LEN, num_chars_read);
      }
      else if (item=='6')                  // REWIND message
      {
            SendData("RW");
            read_data(status_c, IN_MSG_LEN, num_chars_read);
      }
      else if (item=='7')                  // read from SimPLEX
      {
            SendData("NULL");
            read_data ( status_c, IN_MSG_LEN, num_chars_read);
            if(num_chars_read > 0)
            {
                  status_c[num_chars_read]='\0';      // null terminate return string
                  printf ("\nStatus return:%s!\n", status_c);
            }
      }
      else if (item=='8')            // POW_ON command
      {
            char s[120];

            bool all_chans_b = false;
            int tx_i = 0;
            bool by_chan_b = true;
            bool on_b = true;

            //

            printf ( "All channels [N] > " );

            gets ( s );

            if ( s[0] == 'y' || s[0] == 'Y' ) all_chans_b = true;

            //

            if ( !all_chans_b )
            {
                  printf ( "by channel, not TXID [Y] > " );

                  gets ( s );

                  if ( s[0] == 'n' || s[0] == 'N' ) by_chan_b = false;

                  //

                  if ( by_chan_b )
                        printf ( "channel > " );
                  else
                        printf ( "TXID > " );

                  gets ( s );

                  sscanf ( s, "%d", &tx_i );
            }

            //

            printf ( "on [Y] > " );

            gets ( s );

            if ( s[0] == 'n' || s[0] == 'N' ) on_b = false;

            //

            sprintf ( s, "-,POW_ON,v1_a1,%d,%d,%d,%d", on_b, tx_i, by_chan_b, all_chans_b );

            SendData(s);
            read_data(status_c, IN_MSG_LEN, num_chars_read);
      }
      else if (item=='9')  // Power Mode
      {
            char s[120];

            bool all_chans_b = false;
            int tx_i = 0;
            bool by_chan_b = true;

            //

            printf ( "All channels [N] > " );

            gets ( s );

            if ( s[0] == 'y' || s[0] == 'Y' ) all_chans_b = true;

            //

            if ( !all_chans_b )
            {
                  printf ( "by channel, not TXID [Y] > " );

                  gets ( s );

                  if ( s[0] == 'n' || s[0] == 'N' ) by_chan_b = false;

                  //

                  if ( by_chan_b )
                        printf ( "channel > " );
                  else
                        printf ( "TXID > " );

                  gets ( s );

                  sscanf ( s, "%d", &tx_i );
            }

            //

            printf ( "relative [Y] > " );

            gets ( s );

            if ( s[0] == 'n' || s[0] == 'N' )
                  relative_b = false;
            else
                  relative_b = true;
            //

            sprintf ( s, "-,POW_MODE,v1_a1,%d,%d,%d,%d", relative_b, tx_i, by_chan_b, all_chans_b );

            SendData(s);
            read_data(status_c, IN_MSG_LEN, num_chars_read);
      }
      else if (item=='A' || item == 'a')   // Power level
      {
            char s[120];

            bool all_chans_b = false;
            int tx_i = 0;
            bool by_chan_b = true;
            float level_f = 0.0;

            //

            printf ( "All channels [N] > " );

            gets ( s );

            if ( s[0] == 'y' || s[0] == 'Y' ) all_chans_b = true;

            //

            if ( !all_chans_b )
            {
                  printf ( "by channel, not TXID [Y] > " );

                  gets ( s );

                  if ( s[0] == 'n' || s[0] == 'N' ) by_chan_b = false;

                  //

                  if ( by_chan_b )
                        printf ( "channel > " );
                  else
                        printf ( "TXID > " );

                  gets ( s );

                  sscanf ( s, "%d", &tx_i );
            }

            //

            printf ( "new level > " );

            gets ( s );

            sscanf ( s, "%f", &level_f );

            //

            sprintf ( s, "-,POW_LEV,v1_a1,%g,%d,%d,%d,%d", level_f, tx_i, by_chan_b, all_chans_b, !relative_b );

            SendData(s);
            read_data(status_c, IN_MSG_LEN, num_chars_read);
      }
      else if (item=='B' || item=='b' )  // PRN codes ON/OFF command
      {
            char s[120];

            bool all_chans_b = false;
            int chan_i = 0;
            bool on_b = true;

            //

            printf ( "All channels [N] > " );

            gets ( s );

            if ( s[0] == 'y' || s[0] == 'Y' ) all_chans_b = true;

            //

            if ( !all_chans_b )
            {
                  printf ( "channel > " );

                  gets ( s );

                  sscanf ( s, "%d", &chan_i );
            }

            //

            printf ( "PRN code on [Y] > " );

            gets ( s );

            if ( s[0] == 'n' || s[0] == 'N' ) on_b = false;


            //

            sprintf ( s, "-,PRN_CODE,%d,%d,%d", chan_i, all_chans_b, on_b );

            SendData(s);
            read_data(status_c, IN_MSG_LEN, num_chars_read);
      }
      else if (item=='x' || item=='X' )
      {
            quit = true;
      }
  }

  tidyup();
  FreeConsole();

  return 0;
}

void SelectWinSock1_1()
{
    // select WinSock version 1.1
    WORD version = MAKEWORD(1, 1);
    WSADATA wsaData;

    error = WSAStartup(version, &wsaData);
    if (error != 0 )
    {
        printf ("WinSock not available");
        exit(1);
    }

    if (LOBYTE(wsaData.wVersion) != 1 ||
        HIBYTE(wsaData.wVersion) != 1 )
    {
        printf ("WinSock 1.1 not available");
        WSACleanup();
        exit(2);
    }
}
 
void CreateSocket()
{
    // create kernel data structures

    theSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (theSocket == INVALID_SOCKET)
                        printf("Can't create socket\n");
}

bool ConnectToServer()
{
      bool connected = true;

      // Note: We use a hard-wired port number,
      // this is not strictly proper but should be ok
      // for all practical purposes.

    // server is "localhost" on port  15650
    theServerAddress.sin_family = AF_INET;
    theServerAddress.sin_port = htons(15650);

      // EITHER:

    // find IP address of STR4500_rem_pr application. If this is on the same
      // PC as this program then set the hostname to "localhost"
      // If on a different PC then set the network name of the other pc,
      // e.g. the Spirent lab HP vectra PC is "paulc-310"
    HOSTENT* pHost = gethostbyname("localhost");
    in_addr* pHexAddress = (in_addr*) pHost->h_addr_list[0];
    char* DottedAddress = inet_ntoa(*pHexAddress);
    theServerAddress.sin_addr.s_addr = inet_addr(DottedAddress);

      // OR:

      // Alternatively to connect to a STR4500_rem_pr application on a remote system
      // where you know the dotted IP address delete the above and use this:

      // char DottedAddress[20] = "10.24.1.12";      // (for example)
    // theServerAddress.sin_addr.s_addr = inet_addr(DottedAddress);

      // END EITHER/OR

      error = connect(theSocket,
                  (const SOCKADDR*) &theServerAddress,
                  sizeof(SOCKADDR_IN));
      if (error == SOCKET_ERROR)
      {
            printf("Can't connect to server\n");
            connected = false;
      }

      return connected;
}

void SendData(char *message)
{
    // send the message
    error = send(theSocket,
               message,
               strlen(message),
               0);
    if (error == SOCKET_ERROR) printf("Can't send data\n");
}

void read_data ( char *data, int max_chars, int &num_chars_read )
{
      num_chars_read = recv(theSocket, data, max_chars, 0);
      if(num_chars_read == SOCKET_ERROR)
      {
            int error_code = WSAGetLastError();
            printf ("Error in Connection::read_data() error code %d", error_code);
      }
}

// Solicit status message, extract status enum from reply and return it
// Note additional data is returned in top bits of status byte but these
// are not handled here
int get_status()
{
      char data[IN_MSG_LEN +1];
      int num_chars_read;
      int status;

      SendData("NULL");
      read_data(data,IN_MSG_LEN, num_chars_read);
      // message is "Status XX(,last fatal error message)
      sscanf(&data[7],"%x",&status);

      // temporarily print any fatal error message here.
      // ***** Will need to return them and handle them in calling prog. in a real app. ********
      if(num_chars_read > 12)
      {
            // null terminate string, then print it
            data[num_chars_read] = '\0';
            printf("%s\n", data);
      }
      return (status & 0xf);  // for now don't handle higher bits
}

void tidyup()
{
            closesocket(theSocket);
            printf("closing client\n");
}


Comment
Watch Question

evilrixSenior Software Engineer (Avast)
Commented:
Use PerlXS to expose your exising code to Perl so Perl can use it as an extension.
http://en.wikipedia.org/wiki/XS_(Perl)
http://perldoc.perl.org/perlxs.html

Darn site easier that trying to rewrite all that code.

Author

Commented:
yea i tried its not working out for me!! :(
Commented:
XS usually is a nightmare,

You may consider Inline::C for doing this work. It is slightly slower then XS, but much simpler to implement.
cup

Commented:
Silly question: why do you want to change from a compiled language to an interpreted language?  The code will be a lot slower in execution.

Commented:
it isn't stupid at all.

speed in CPU isn't usually a problem when you are working over the network.

Costs with maintenance of the code usually surpasses by far the possible cost in hardware.