Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web


// =================================================================
//
//  Copyright (C) 2003 Alex Vinokur
//
//  For conditions of distribution and use, see
//  copyright notice in common.h
//
// =================================================================


// #################################################################
//
//  SOFTWARE : C++ Stream-Compatible TCP/IP Sockets Demo Application
//  FILE     : demoapp.cpp
//
//  DESCRIPTION :
//         Demo2 application related class implementation
//         (non-template methods)
//
// #################################################################


// ==================
#include "demoapp2.h"
// ==================


// ##########################################################
// ### IMPORTANT : DONT CHANGE, ONLY ADD (See Note below) ###
// ##########################################################
map<string, BasicCallAction*> BasicPartner::call_action_s;

map<string, BasicCallPrepareReply*> ApplicationRun::map_replies_s;

template <typename T>
map<string, BasicCallPrepareSubReply*> CallPrepareReply<T>::map_subreplies_s;

// ##########################################################
// ##########################################################




// ---------------------
// ---------------------
// Constructor-0
BasicCallPrepareReply::BasicCallPrepareReply ()
{
SET_CTOR_TRACE;
}

// ---------------------
// Destructor
BasicCallPrepareReply::~BasicCallPrepareReply ()
{
SET_DTOR_TRACE;
}


// ---------------------
// ---------------------
// Constructor-0
BasicCallPrepareSubReply::BasicCallPrepareSubReply ()
{
SET_CTOR_TRACE;
}

// ---------------------
// Destructor
BasicCallPrepareSubReply::~BasicCallPrepareSubReply ()
{
SET_DTOR_TRACE;
}





// ---------------------
// ---------------------

// Constructor-0
ApplicationInit::ApplicationInit ()
{
SET_CTOR_TRACE;

  // ---------
  show_logo ();
  // ---------

  // ------------------------------
  assert (BasicPartner::call_action_s.empty());
  // ------------------------------
#define  ADD_CALL_ACTION(t) \
   BasicPartner::call_action_s[typeid(t).name()] = \
   static_cast<BasicCallAction*> (new TemplateCallAction<t> ())

  ADD_CALL_ACTION(int);
  ADD_CALL_ACTION(string);
  ADD_CALL_ACTION(Too);


  // ------------------------------
#define  ADD_SINGLE_REPLY_ACTION(t1, t2) \
   CallPrepareReply<t1>::map_subreplies_s[typeid(t2).name()] = \
   static_cast<BasicCallPrepareSubReply*> ( \
      new CallPrepareSubReply<t1, t2> () \
      )

  assert (CallPrepareReply<int>::map_subreplies_s.empty());
  ADD_SINGLE_REPLY_ACTION(int, int);
  ADD_SINGLE_REPLY_ACTION(int, string);
  ADD_SINGLE_REPLY_ACTION(int, Too);

  assert (CallPrepareReply<string>::map_subreplies_s.empty());
  ADD_SINGLE_REPLY_ACTION(string, int);
  ADD_SINGLE_REPLY_ACTION(string, string);
  ADD_SINGLE_REPLY_ACTION(string, Too);

  assert (CallPrepareReply<Too>::map_subreplies_s.empty());
  ADD_SINGLE_REPLY_ACTION(Too, int);
  ADD_SINGLE_REPLY_ACTION(Too, string);
  ADD_SINGLE_REPLY_ACTION(Too, Too);



  // ------------------------------
#define  ADD_FULL_REPLY_ACTION(t) \
   ApplicationRun::map_replies_s[typeid(t).name()] = \
   static_cast<BasicCallPrepareReply*> ( \
      new CallPrepareReply<t> () \
      )

  ADD_FULL_REPLY_ACTION(int);
  ADD_FULL_REPLY_ACTION(string);
  ADD_FULL_REPLY_ACTION(Too);

}



// Destructor
ApplicationInit::~ApplicationInit ()
{
SET_DTOR_TRACE;
  // -----------------
  // -----------------
map<string, BasicCallPrepareReply*>::iterator pos_replies;

  for (pos_replies = ApplicationRun::map_replies_s.begin();
       pos_replies != ApplicationRun::map_replies_s.end();
       pos_replies++
      )
  {
    delete pos_replies->second;
  }
  ApplicationRun::map_replies_s.clear();


  // -----------------
  // -----------------
map<string, BasicCallPrepareSubReply*>::iterator pos_subreplies;

#define  DELETE_SINGLE_REPLY_ACTION(t) \
  for (pos_subreplies = CallPrepareReply<t>::map_subreplies_s.begin(); \
       pos_subreplies != CallPrepareReply<t>::map_subreplies_s.end(); \
       pos_subreplies++ \
      )  \
  { \
    delete pos_subreplies->second; \
  } \
  CallPrepareReply<t>::map_subreplies_s.clear()

  DELETE_SINGLE_REPLY_ACTION (int);
  DELETE_SINGLE_REPLY_ACTION (string);
  DELETE_SINGLE_REPLY_ACTION (Too);



  // -----------------
  // -----------------
map<string, BasicCallAction*>::iterator pos_action;
  for (pos_action = BasicPartner::call_action_s.begin();
       pos_action != BasicPartner::call_action_s.end();
       pos_action++
      )
  {
    delete pos_action->second;
  }
  BasicPartner::call_action_s.clear();


  // -----------------
  // -----------------
  // -----------------

  close_screen_log();

  close_milestone_log();

#ifdef TRACE_LOG
#if (TRACE_LOG)
  trace_inst.show_trace ("BYE", "", "", __LINE__);
#endif
#endif
  close_trace_log();

  // -----------------

ostringstream oss1, oss2, oss3;
  oss1 << "Screen logfile    : " << screen_log_name_;
  oss2 << "Milestone logfile : " << milestone_log_name_;
  oss3 << "Trace logfile     : " << trace_log_name_;

size_t col_size = 0;
  col_size = MAX_VALUE (col_size, oss1.str().size());
  col_size = MAX_VALUE (col_size, oss2.str().size());
  col_size = MAX_VALUE (col_size, oss3.str().size());

  cout << "\t" << string (col_size, '/') << endl;

  if (!screen_log_name_.empty())
  {
    cout << "\t" << oss1.str() << endl;
  }

  if (!milestone_log_name_.empty())
  {
    cout << "\t" << oss2.str() << endl;
  }

  if (!trace_log_name_.empty())
  {
    cout << "\t" << oss3.str() << endl;
  }

  cout << "\t" << string (col_size, '/') << endl;

}

// ---------------------
void ApplicationInit::show_logo () const
{
const string pref1 (string (3, ' '));

  sout << pref1 << string (string(product_name).size(), '#') << endl;
  sout << pref1 << product_name << endl;
  sout << pref1 << demo_app_name << endl;
  sout << pref1 << sw_version << endl;
  sout << pref1 << string (string(product_name).size(), '#') << endl;
  sout << endl;
  sout << endl;
  sout << endl;

}


// ---------------------
void ApplicationInit::Set_Log_Name (string& file_o, const string& name_i)
{
  assert (file_o.empty());
  file_o = name_i;
}

// ---------------------
void ApplicationInit::Open_Log (ofstream& fout_o, const string& name_i)
{
  assert (!name_i.empty());
  assert (fout_o);

  fout_o.open (name_i.c_str());

  if ((!fout_o) || (fout_o && !fout_o.is_open()))
  {
    cerr << endl;
    cerr << "\t--- FATAL ERROR! Unable to open logfile "
         << name_i
         << " ---"
         << endl;
    cerr << endl;

    exit(1);
  }
  assert (fout_o);
  assert (fout_o.is_open());

}

// ---------------------
void ApplicationInit::Close_Log (ofstream& fout_o)
{
  if (fout_o && fout_o.is_open()) fout_o.close();

  assert (!fout_o || (fout_o && !fout_o.is_open()));

}

// ---------------------
void ApplicationInit::Flush_Log (ofstream& fout_o, ostringstream& oss_io)
{
  fout_o << oss_io.str();
  oss_io.str(string());
  assert (oss_io.str().empty());
}


// ---------------------
void ApplicationInit::set_screen_log_name(const string& name_i)
{
  assert (!name_i.empty());
#if (SCREEN_LOG)
  Set_Log_Name (screen_log_name_, name_i);
#endif
}


// ---------------------
void ApplicationInit::open_screen_log()
{
#if (SCREEN_LOG)
  Open_Log (screen_log_, screen_log_name_);

  save_sbuf_cout_ = cout.rdbuf();
  assert (save_sbuf_cout_);
  cout.rdbuf(screen_log_.rdbuf());
#endif

 cout << sout.str();
}


// ---------------------
void ApplicationInit::close_screen_log()
{
#if (SCREEN_LOG)
  cout.rdbuf(save_sbuf_cout_);
  Close_Log (screen_log_);
#endif
}


// ---------------------
// ---------------------
void ApplicationInit::set_milestone_log_name(const string& name_i)
{
  assert (!name_i.empty());
#if (MILESTONE_LOG)
  Set_Log_Name (milestone_log_name_, name_i);
#endif
}


// ---------------------
void ApplicationInit::open_milestone_log()
{
#if (MILESTONE_LOG)
  Open_Log (milestone_log_, milestone_log_name_);
#endif
}


// ---------------------
void ApplicationInit::close_milestone_log()
{
#if (MILESTONE_LOG)
  flush_milestone_log();
  Close_Log (milestone_log_);
#endif
}

// ---------------------
void ApplicationInit::flush_milestone_log()
{
#if (MILESTONE_LOG)
  Flush_Log (milestone_log_, mout);
#endif
}


// ---------------------
// ---------------------
void ApplicationInit::set_trace_log_name(const string& name_i)
{
  assert (!name_i.empty());
#if (TRACE_LOG)
  Set_Log_Name (trace_log_name_, name_i);
#endif
}


// ---------------------
void ApplicationInit::open_trace_log()
{
#if (TRACE_LOG)
  Open_Log (trace_log_, trace_log_name_);
#endif
}


// ---------------------
void ApplicationInit::close_trace_log()
{
#if (TRACE_LOG)
  flush_trace_log();
  Close_Log (trace_log_);
#endif
}

// ---------------------
void ApplicationInit::flush_trace_log()
{
#if (TRACE_LOG)
  Flush_Log (trace_log_, tout);
#endif
}


// ---------------------
void ApplicationInit::remove_old_logs (bool is_client_i) const
{
  if (is_client_i)
  {
    remove (string (CLIENT_SCREEN_LOG_NAME).c_str());
    remove (string (CLIENT_MILESTONE_LOG_NAME).c_str());
    remove (string (CLIENT_TRACE_LOG_NAME).c_str());
  }
  else
  {
    remove (string (SERVER_SCREEN_LOG_NAME).c_str());
    remove (string (SERVER_MILESTONE_LOG_NAME).c_str());
    remove (string (SERVER_TRACE_LOG_NAME).c_str());
  }

}




// ---------------------
// ---------------------
// ---------------------
// Constructor-1
ApplicationRun::ApplicationRun ()
        :
   map_replies_ (map_replies_s)

{
SET_CTOR_TRACE;

  // ------------------------------

  assert (!map_replies_.empty());

}


// ---------------------
// Destructor
ApplicationRun::~ApplicationRun()
{
SET_DTOR_TRACE;
  assert (BasicDataType::Get_Created_Instances() == BasicDataType::Get_Deleted_Instances());
}




// ---------------------
// ---------------------
bool ApplicationRun::demo1_run_client (
      const string& ip_server_address_i,
      int ip_port_no_i
      )
{
SET_TRACE;
bool ret_bool = true;

  try
  {
    SET_TRACE;
    ClientRun inst (ip_port_no_i, ip_server_address_i);
    inst.demo1();
  }
  catch (const SocketRunTimeException &e)
  {
    ret_bool = false;
    MOUT ("Creating client exception : " << e.what() << endl);
  }

  return ret_bool;
}



// ---------------------
bool ApplicationRun::demo1_run_server (int ip_port_no_i)
{
SET_TRACE;
bool ret_bool = true;

  try
  {
    SET_TRACE;
    ServerRun inst (ip_port_no_i);
    inst.demo1();
  }
  catch (const SocketRunTimeException &e)
  {
    ret_bool = false;
    MOUT ("Creating server exception : " << e.what() << endl);
  }

  return ret_bool;
}




// ---------------------
// ---------------------
template <>
PacketType<int>* ApplicationRun::demo2_prepare_typed_request (const vector<BasicDataType*>& replies_i)
{
SET_TRACE;
   // =========================
   // Demonstration sample only
   // =========================

#define FACTOR_int      1000
#define MAX_TEST_int_DATA_ITEMS  9

static size_t counter = 0;
  counter++;

const size_t no_of_items = rand()%MAX_TEST_int_DATA_ITEMS + 1;

vector<int>  data;

  for (size_t i = 0; i < no_of_items; i++)
  {
    data.push_back ((counter * FACTOR_int) + rand()%FACTOR_int);
  }
  assert (!data.empty());

vector<int> vect_int (get_subreply_data<int>(replies_i));
vector<Too> vect_Too (get_subreply_data<Too>(replies_i));

  data.push_back ((counter * FACTOR_int) + vect_int.size());
  if (!vect_int.empty())
  {
    data.push_back ((counter * FACTOR_int) + vect_int.front());
    data.push_back ((counter * FACTOR_int) + vect_int.back());
  }

  data.push_back ((counter * FACTOR_int) + vect_Too.size());
  if (!vect_Too.empty())
  {
    data.push_back ((counter * FACTOR_int) + vect_Too.front().get_var2());
    data.push_back ((counter * FACTOR_int) + vect_Too.back().get_var2());
  }

  assert (!data.empty());

  for (size_t i = 0; i < data.size(); i++)
  {
    ostringstream oss;
    oss << data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }


PacketType<int>* ret_ptr = new PacketType<int> (data, __FILE__, __LINE__);
  assert (ret_ptr);

  WARNING (ret_ptr->is_packet_allowed_len());

  return  ret_ptr;

} // <int> demo2_prepare_typed_request


// ---------------------
typedef char string_t15 [15];

// ---------------------
static const string_t15 ar_str[] = {"C++", "Java", "Cobol", "Algol60", "Algol68", "Fortran", "Lisp", "Ada", "Pascal", "Assembler"};
static const vector<string> vect_str (ar_str, ar_str + sizeof(ar_str)/sizeof(ar_str[0]));

template <>
PacketType<string>* ApplicationRun::demo2_prepare_typed_request (const vector<BasicDataType*>& replies_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

#define MAX_TEST_string_DATA_ITEMS  7

const size_t no_of_items = rand()%MAX_TEST_string_DATA_ITEMS + 1;

vector<string>  data;

  for (size_t i = 0; i < no_of_items; i++)
  {
    const size_t k = rand()%vect_str.size();
    assert (k < vect_str.size());

    data.push_back (vect_str[k]);
  }
  assert (!data.empty());

vector<Too> vect_Too (get_subreply_data<Too>(replies_i));

  if (!vect_Too.empty())
  {
    data.push_back (vect_Too.front().get_var1());
    data.push_back (vect_Too.front().get_var3());
    data.push_back (vect_Too.front().get_var4());
    data.push_back (vect_Too.front().get_var5());

    data.push_back (vect_Too.back().get_var1());
    data.push_back (vect_Too.back().get_var5());
  }
  else
  {
    data.push_back ("Nothing");
  }

  assert (!data.empty());

  for (size_t i = 0; i < data.size(); i++)
  {
    assert (String_Is_Graph (data[i]));

    // ---------------
    ostringstream oss;
    oss << data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }


PacketType<string>* ret_ptr = new PacketType<string> (data, __FILE__, __LINE__);
  assert (ret_ptr);

  WARNING (ret_ptr->is_packet_allowed_len());

  return  ret_ptr;

} // <string> demo2_prepare_typed_request


// ---------------------
static const string_t15 ar1[] = {"USA", "England", "France", "Russia", "Chine", "Canada", "Italy", "India", "Germany"};
static const vector<string> vect1 (ar1, ar1 + sizeof(ar1)/sizeof(ar1[0]));

static const string_t15 ar3[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static const vector<string> vect3 (ar3, ar3 + sizeof(ar3)/sizeof(ar3[0]));

static const string_t15 ar4[] = {"Intel", "IBM", "Microsoft", "Sun", "HP", "Apple", "Netscape", "Oracle"};
static const vector<string> vect4 (ar4, ar4 + sizeof(ar4)/sizeof(ar4[0]));

const string_t15 ar5[] = {"Huffman", "Turing", "Fibonacci", "Knuth", "Dijkstra", "Stroustrup"};
const vector<string> vect5 (ar5, ar5 + sizeof(ar5)/sizeof(ar5[0]));

template <>
PacketType<Too>* ApplicationRun::demo2_prepare_typed_request (const vector<BasicDataType*>& replies_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

#define FACTOR_var2     100

#define MAX_TEST_Too_DATA_ITEMS  5

static size_t counter = 0;
  counter++;

const size_t no_of_items = rand()%MAX_TEST_Too_DATA_ITEMS + 1;

vector<Too>  data;

  for (size_t i = 0; i < no_of_items; i++)
  {
    const size_t k1 = rand()%vect1.size();
    assert (k1 < vect1.size());

    const size_t k3 = rand()%vect3.size();
    assert (k3 < vect3.size());

    const size_t k4 = rand()%vect4.size();
    assert (k4 < vect4.size());

    const size_t k5 = rand()%vect5.size();
    assert (k5 < vect5.size());


    data.push_back (
         Too
         (
           vect1 [k1],
           (counter * FACTOR_var2) + rand()%FACTOR_var2,
           vect3 [k3],
           vect4 [k4],
           vect5 [k5]
         )

      );
  }
  assert (!data.empty());


vector<string> vect_string (get_subreply_data<string>(replies_i));

  if (!vect_string.empty())
  {
    string str1 ("What?-" + vect_string.front());
    string str3 ("Who?-" + vect_string.front());
    string str4 ("When?-" + vect_string.front());
    string str5 ("Where?-" + vect_string.back());

    const char some_char = '*';
    assert (some_char != Too_IO_DELIM);

    for (size_t i = 0; i < str1.size(); i++) if (str1[i] == Too_IO_DELIM) str1[i] = some_char;
    for (size_t i = 0; i < str3.size(); i++) if (str3[i] == Too_IO_DELIM) str3[i] = some_char;
    for (size_t i = 0; i < str4.size(); i++) if (str4[i] == Too_IO_DELIM) str4[i] = some_char;
    for (size_t i = 0; i < str5.size(); i++) if (str5[i] == Too_IO_DELIM) str5[i] = some_char;

    assert (str1.find (Too_IO_DELIM) == string::npos);
    assert (str3.find (Too_IO_DELIM) == string::npos);
    assert (str4.find (Too_IO_DELIM) == string::npos);
    assert (str5.find (Too_IO_DELIM) == string::npos);

    data.push_back (
        Too
        (
          str1,
          (counter * FACTOR_var2) + vect_string.size(),
          str3,
          str4,
          str5
        )
      );
  }
  else
  {
    data.push_back (
        Too
        (
          "Empty1",
          (counter * FACTOR_var2),
          "Empty3",
          "Empty4",
          "Empty5"
        )
      );
   }

  assert (!data.empty());

  for (size_t i = 0; i < data.size(); i++)
  {
    ostringstream oss;
    oss << data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }


PacketType<Too>* ret_ptr = new PacketType<Too> (data, __FILE__, __LINE__);

  assert (ret_ptr);

  WARNING (ret_ptr->is_packet_allowed_len());

  return  ret_ptr;

} // <Too> demo2_prepare_typed_request



// ---------------------
// ---------------------
BasicDataType* ApplicationRun::demo2_prepare_request (const vector<BasicDataType*>& replies_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

BasicDataType* ret_pointer = NULL;
  assert (ret_pointer == NULL);

  // ---------------
vector<int> subreply_int (get_subreply_data<int>(replies_i));
vector<string> subreply_string (get_subreply_data<string>(replies_i));
vector<Too> subreply_Too (get_subreply_data<Too>(replies_i));

  for (size_t i = 0; i < replies_i.size(); i++)
  {
    // replies_i[i]->show_packet ("SubReply", '*');  
  }

  // ---------------

#define TESTCASES 10
const size_t case_value = rand()%TESTCASES;
  switch (case_value)
  {
    case 0 :
    case 3 :
    case 4 :
      ret_pointer = demo2_prepare_typed_request<int> (replies_i);
      assert (ret_pointer != NULL);
      WARNING (ret_pointer->is_packet_allowed_len());
      break;

    case 7 :
      if (subreply_string.empty())
      {
        ret_pointer = demo2_prepare_typed_request<int> (replies_i);
        assert (ret_pointer != NULL);
        WARNING(ret_pointer->is_packet_allowed_len());
      }
      else
      {
        ret_pointer = demo2_prepare_typed_request<string> (replies_i);
        assert (ret_pointer != NULL);
        WARNING (ret_pointer->is_packet_allowed_len());
      }
      break;

    case 1 :
    case 5 :
    case 8 :
      ret_pointer = demo2_prepare_typed_request<string> (replies_i);
      assert (ret_pointer != NULL);
      WARNING (ret_pointer->is_packet_allowed_len());
      break;

    case 2 :
    case 6 :
    case 9 :
      ret_pointer = demo2_prepare_typed_request<Too> (replies_i);
      assert (ret_pointer != NULL);
      WARNING (ret_pointer->is_packet_allowed_len());
      break;

    default :
      assert (0);
      break; // unused
  }

  assert (ret_pointer != NULL);

  if (!(ret_pointer->is_packet_allowed_len()))
  {
    size_t original_request_size = ret_pointer->get_packet_transmission_len ();
    delete ret_pointer;
    ret_pointer = NULL;

    vector<string> new_data;
    ostringstream oss;

    new_data.push_back ("Original-request-was-very-long");

    oss << ""
        << "Contained-"
        << original_request_size
        << "-bytes";
    new_data.push_back (oss.str());

    ret_pointer   = Create_Emergency_Packet (new_data);

    assert (ret_pointer->is_packet_allowed_len());

  }

  assert (ret_pointer != NULL);

  assert (ret_pointer->is_packet_allowed_len());

  return ret_pointer;

} // demo2_prepare_request


// ---------------------
// ---------------------
template <>
vector<int> ApplicationRun::demo2_prepare_subreply (const vector<int>& request_data_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

vector<int> reply_data;

  for (size_t i = 0; i < request_data_i.size(); i++)
  {
    reply_data.push_back (10 * request_data_i[i]);
    reply_data.push_back (20 * request_data_i[i]);
  }

  assert (!reply_data.empty());

  for (size_t i = 0; i < reply_data.size(); i++)
  {
    ostringstream oss;
    oss << reply_data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }

  return reply_data;
}


// ---------------------
template <>
vector<string> ApplicationRun::demo2_prepare_subreply (const vector<int>& request_data_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

vector<string> reply_data;

  for (size_t i = 0; i < request_data_i.size(); i++)
  {
    ostringstream oss;
    oss << request_data_i[i];
    reply_data.push_back ("FirstOn-" + oss.str());
    reply_data.push_back ("SecondOn-" + oss.str());
  }

  assert (!reply_data.empty());

  for (size_t i = 0; i < reply_data.size(); i++)
  {
    assert (String_Is_Graph (reply_data[i]));

    // ---------------------------
    ostringstream oss;
    oss << reply_data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }

  return reply_data;
}


// ---------------------
template <>
vector<string> ApplicationRun::demo2_prepare_subreply (const vector<string>& request_data_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

vector<string> reply_data;
  for (size_t i = 0; i < request_data_i.size(); i++)
  {
    reply_data.push_back ("Reply1-On--" + request_data_i[i]);
    reply_data.push_back ("Reply2-On--" + request_data_i[i]);
    reply_data.push_back ("Reply3-On--" + request_data_i[i]);
  }

  assert (!reply_data.empty());

  for (size_t i = 0; i < reply_data.size(); i++)
  {
    assert (String_Is_Graph (reply_data[i]));

    // ------------------------
    ostringstream oss;
    oss << reply_data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }

  return reply_data;
}


// ---------------------
template <>
vector<Too> ApplicationRun::demo2_prepare_subreply (const vector<Too>& request_data_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

vector<Too> reply_data;
  for (size_t i = 0; i < request_data_i.size(); i++)
  {
    reply_data.push_back (
         Too
         (
           "FirstOnVar1==" + request_data_i[i].get_var1(),
           30 * request_data_i[i].get_var2(),
           "FirstOnVar3==" + request_data_i[i].get_var3(),
           "FirstOnVar4==" + request_data_i[i].get_var4(),
           "FirstOnVar5==" + request_data_i[i].get_var5()
         )
          );

    reply_data.push_back (
         Too
         (
           "SecondOnVar1==" + request_data_i[i].get_var1(),
           50 * request_data_i[i].get_var2(),
           "SecondOnVar3==" + request_data_i[i].get_var3(),
           "SecondOnVar4==" + request_data_i[i].get_var4(),
           "SecondOnVar5==" + request_data_i[i].get_var5()
         )
          );
  }


  assert (!reply_data.empty());

  for (size_t i = 0; i < reply_data.size(); i++)
  {
    ostringstream oss;
    oss << reply_data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }

  return reply_data;
}


// ---------------------
template <>
vector<int> ApplicationRun::demo2_prepare_subreply (const vector<Too>& request_data_i)
{
SET_TRACE;

   // =========================
   // Demonstration sample only
   // =========================

vector<int> reply_data;
  for (size_t i = 0; i < request_data_i.size(); i++)
  {
    reply_data.push_back (request_data_i[i].get_var1().size());
    reply_data.push_back (request_data_i[i].get_var2());
    reply_data.push_back (request_data_i[i].get_var3().size());
    reply_data.push_back (request_data_i[i].get_var4().size());
    reply_data.push_back (request_data_i[i].get_var5().size());
  }


  assert (!reply_data.empty());

  for (size_t i = 0; i < reply_data.size(); i++)
  {
    ostringstream oss;
    oss << reply_data[i];
    assert (oss.str().size() < BUFSIZE_DEFAULT);
  }


  return reply_data;
}

// ---------------------
// ---------------------
bool ApplicationRun::demo2_run_client (
      const string&  ip_server_address_i,
      int      ip_port_no_i,
      size_t      number_of_test_requests_i
      )
{
SET_TRACE;
bool ret_bool = true;

  set_screen_log_name (CLIENT_SCREEN_LOG_NAME);
  set_milestone_log_name (CLIENT_MILESTONE_LOG_NAME);
  set_trace_log_name (CLIENT_TRACE_LOG_NAME);

  remove_old_logs (true);

  open_screen_log();
  open_milestone_log();
  open_trace_log();

  // -----------------

  try
  {
    SET_TRACE;
    ClientRun client_ins (ip_port_no_i, ip_server_address_i);

    MOUT (  client_ins.get_partner_name()
         << " : Start Of Session"
         << endl
         );

    vector<BasicDataType*> replies;

    for (size_t request_no = 0;
                request_no < number_of_test_requests_i;
                request_no++)
    {
#ifdef SCREEN_LOG
#if (SCREEN_LOG)
      if (((request_no + 1)%INFO_PER_REQUESTS) == 0)
      {
        cerr << "\t"
             << client_ins.get_partner_name()
             << " : Request-"
             << (request_no + 1)
             << " Sent"
             << endl;
      }
#endif
#endif

      // ------------------
      flush_milestone_log();
      flush_trace_log();
      // ------------------

      bool big_break_flag = false;

      const BasicDataType* const_ptr_request = demo2_prepare_request(replies);
      assert (!(const_ptr_request == NULL));

      MOUT (  client_ins.get_partner_name()
           << " : REQUEST TRANSMISSION LEN to be sent =  "
           << const_ptr_request->get_packet_transmission_len()
           << endl
           );

      assert (const_ptr_request->is_packet_allowed_len());

      client_ins.set_request_id (request_no + 1);

      if (!client_ins.send_relevant_packet (const_ptr_request))
      {

        ostringstream oss1, oss2;

        oss1 << client_ins.get_partner_name()
             << " : There is a problem with client's outcoming packet";

        oss2 << "ClientRequestId = "
             << client_ins.get_request_id ()
             << ", Packet Typename = "
             << GetTypeName (const_ptr_request->get_typeid_data_type());

        cout << endl;
        cout << "\t" << string (oss1.str().size(), '#') << endl;
        cout << "\t" << oss1.str() << endl;
        cout << "\t" << string (9, ' ') << oss2.str() << endl;
        cout << "\t" << string (oss1.str().size(), '#') << endl;
        cout << endl;


        MOUT (  oss1.str()
             << " ("
             << oss2.str()
             << ")"
             << endl
             );

        continue;
      }

      assert (!(const_ptr_request == NULL));
      delete (const_ptr_request);
      const_ptr_request = NULL;


      // ------------------------
      assert ((request_no + 1) == client_ins.get_total_sent_packets());

      const size_t number_of_subreplies = client_ins.read_size_from_stream();

      // ------------------------
      for (size_t i = 0; i < replies.size(); i++)
      {
        assert (replies[i] != NULL);
        delete replies[i];
      }
      replies.clear();

      for (size_t subreply_no = 0;
                  subreply_no < number_of_subreplies;
                  subreply_no++)
      {

        BasicDataType* ptr_subreply = NULL;

        if (!client_ins.recv_relevant_packet (ptr_subreply))
        {
          ostringstream oss1, oss2;

          oss1 << client_ins.get_partner_name()
               << " : There is a problem with client's incoming packet";

          oss2 << "Reply On ClientRequestId = "
               << client_ins.get_request_id ()
               << ", ServerSubReply#"
               << (subreply_no + 1);

          cout << endl;
          cout << "\t" << string (oss1.str().size(), '#') << endl;
          cout << "\t" << oss1.str() << endl;
          cout << "\t" << string (9, ' ') << oss2.str() << endl;
          cout << "\t" << string (oss1.str().size(), '#') << endl;
          cout << endl;


          MOUT (  oss1.str()
               << " ("
               << oss2.str()
               << ")"
               << endl
               );


          assert (ptr_subreply == NULL);
          // continue;
          big_break_flag = true;
          break;
        }

        replies.push_back (ptr_subreply);

      }  // for (size_t subreply_no = 0; true; subreply_no++)

      if (big_break_flag) break;

    } // for (size_t request_no = 0

    // ---------------------------
    for (size_t i = 0; i < replies.size(); i++)
    {
      assert (replies[i] != NULL);
      delete replies[i];
    }
    replies.clear();

    // ---------------------------
    ostringstream oss;
    oss << END_OF_SESSION_ID;
    client_ins.write_to_stream (oss.str(), "END_OF_SESSION_ID");

    MOUT (  client_ins.get_partner_name()
         << " : End Of Session"
         << endl
         );

  }
  catch (const SocketRunTimeException &e)
  {
    ret_bool = false;
    MOUT ( "Creating client exception : " << e.what() << endl);
  }


  // ---------------------------
  return ret_bool;

} // demo2_run_client


// ---------------------
// ---------------------
bool ApplicationRun::demo2_run_server (int ip_port_no_i)
{
SET_TRACE;
bool ret_bool = true;

  set_screen_log_name (SERVER_SCREEN_LOG_NAME);
  set_milestone_log_name (SERVER_MILESTONE_LOG_NAME);
  set_trace_log_name (SERVER_TRACE_LOG_NAME);

  remove_old_logs (false);

  open_screen_log();
  open_milestone_log();
  open_trace_log();

  // ------------------
  try
  {
    SET_TRACE;
    ServerRun server_ins (ip_port_no_i);

    MOUT (  server_ins.get_partner_name()
         << " : Start Of Session"
         << endl
         );

    for (size_t request_no = 0; true; request_no++)
    {
#ifdef SCREEN_LOG
#if (SCREEN_LOG)
      if (((request_no + 1)%INFO_PER_REQUESTS) == 0)
      {
        cerr << "\t"
             << server_ins.get_partner_name()
             << " : Request-"
             << (request_no + 1)
             << " Received"
             << endl;
      }
#endif
#endif
      // ------------------
      flush_milestone_log();
      flush_trace_log();
      // ------------------

      BasicDataType* ptr_request = NULL;

      if (!server_ins.recv_relevant_packet (ptr_request))
      {
        if (server_ins.is_end_of_session ())
        {
          MOUT ( server_ins.get_partner_name()
               << " : End Of Session"
               << endl
               );

        }
        else
        {
          ostringstream oss1, oss2;

          oss1 << server_ins.get_partner_name()
               << " : There is a problem with server's incoming packet";

          oss2 << "ClientRequestId = "
               << server_ins.get_request_id ();

          cout << endl;
          cout << "\t" << string (oss1.str().size(), '#') << endl;
          cout << "\t" << oss1.str() << endl;
          cout << "\t" << string (9, ' ') << oss2.str() << endl;
          cout << "\t" << string (oss1.str().size(), '#') << endl;
          cout << endl;


          MOUT (  oss1.str()
               << " ("
               << oss2.str()
               << ")"
               << endl
               );

   }

        assert (ptr_request == NULL);
        break;

      }


      assert ((request_no + 1) == server_ins.get_total_recv_packets ());

      const BasicDataType* const_ptr_request = ptr_request;
      assert (const_ptr_request == ptr_request);

      vector<BasicDataType*> replies (demo2_prepare_reply(const_ptr_request));
      assert (!replies.empty());

      assert (Is_Reply_Allowed_Len (replies));


      // ---------------
      // ---------------

      MOUT (  server_ins.get_partner_name()
           << " : REPLY TRANSMISSION LEN to be sent =  "
           << Get_Reply_Transmission_Len (replies)
           << endl
           );

      // ---------------
      // ---------------
      ostringstream oss;
      oss << replies.size();
      server_ins.write_to_stream (oss.str(), "[Number of SubReplies]");

      // ---------------
      // ---------------
      for (size_t subreply_no = 0;
                  subreply_no < replies.size();
                  subreply_no++
                  )
      {
        const BasicDataType* subreply = replies[subreply_no];

        if (!server_ins.send_relevant_packet (subreply))
        {
          ostringstream oss1, oss2, oss3;

          oss1 << server_ins.get_partner_name()
               << " : There is a problem with server's outcoming packet";

          oss2 << "On ClientRequestId = "
               << server_ins.get_request_id ()
               << ", ServerSubReply#"
               << (subreply_no + 1);

          oss3 << "Packet Typename = "
               << GetTypeName (subreply->get_typeid_data_type());


          cout << endl;
          cout << "\t" << string (oss1.str().size(), '#') << endl;
          cout << "\t" << oss1.str() << endl;
          cout << "\t" << string (9, ' ') << oss2.str() << endl;
          cout << "\t" << string (9, ' ') << oss3.str() << endl;
          cout << "\t" << string (oss1.str().size(), '#') << endl;
          cout << endl;


          MOUT (  oss1.str()
               << " "
               << oss2.str()
               << " ("
               << oss3.str()
               << ")"
               << endl
               );

          continue;
        }

      }  // for (size_t subreply_no = 0; 

      assert (ptr_request != NULL);
      delete (ptr_request);
      ptr_request = NULL;
      const_ptr_request = NULL;

      for (size_t i = 0; i < replies.size(); i++)
      {
        assert (replies[i] != NULL);
        delete replies[i];
      }
      replies.clear();


    } // for ... 
  }
  catch (const SocketRunTimeException &e)
  {
    ret_bool = false;
    MOUT ( "Creating server exception : " << e.what() << endl);
  }

  return ret_bool;

} // demo2_run_server


// ---------------------
vector<BasicDataType*> ApplicationRun::demo2_prepare_reply (const BasicDataType*& request_i)
{
SET_TRACE;

  assert (request_i != NULL);

const map<string, BasicCallPrepareReply*>::const_iterator find_iter = map_replies_.find (request_i->get_typeid_data_type());
  assert (find_iter != map_replies_.end());

vector<BasicDataType*> ret_vect (find_iter->second->demo2_call_prepare_reply(*this, request_i));

  WARNING (Is_Reply_Allowed_Len (ret_vect));

  if (!Is_Reply_Allowed_Len (ret_vect))
  {
    size_t original_reply_size = Get_Reply_Transmission_Len (ret_vect);
    for (size_t i = 0; i < ret_vect.size(); i++)
    {
      delete ret_vect[i];
    }
    ret_vect.clear();

    vector<string> new_data;
    ostringstream oss;

    new_data.push_back ("Original-reply-was-very-long");

    oss << ""
        << "Contained-"
        << original_reply_size
        << "-bytes";
    new_data.push_back (oss.str());

    ret_vect.push_back (Create_Emergency_Packet (new_data));

    assert (Is_Reply_Allowed_Len (ret_vect));
  }

  assert (!ret_vect.empty());
  assert (Is_Reply_Allowed_Len (ret_vect));

  return ret_vect;
}


// ---------------------
size_t ApplicationRun::Get_Reply_Transmission_Len (const vector<BasicDataType*>& reply_i)
{
SET_TRACE;
size_t ret_value = 0;

  for (size_t i = 0; i < reply_i.size(); i++)
  {
    ret_value += reply_i[i]->get_packet_transmission_len();
  }
  ret_value += BasicDataType::Get_PrePacket_Len ();

  return ret_value;
}


// ---------------------
bool ApplicationRun::Is_Reply_Allowed_Len (
         const vector<BasicDataType*>& replies_i,
         size_t            max_allowed_len_i
         )
{
SET_TRACE;
  return (Get_Reply_Transmission_Len(replies_i) < max_allowed_len_i);
}


// ---------------------
BasicDataType* ApplicationRun::Create_Emergency_Packet (const vector<string>& msg_i)
{
SET_TRACE;

vector<string> data;
  data.push_back ("Emergency-Packet");

  for (size_t i = 0; i < msg_i.size(); i++) data.push_back (msg_i[i]);

ostringstream oss;
  oss << "Max-Allowed-BUFSIZE-is-"
      << BUFSIZE_DEFAULT;
  data.push_back (oss.str());

  for (size_t i = 0; i < data.size(); i++)
  {
    assert (String_Is_Graph (data[i]));
  }

PacketType<string>* ret_ptr = new PacketType<string> (data, __FILE__, __LINE__);
  assert (ret_ptr != NULL);
  assert (ret_ptr->is_packet_allowed_len());

  return ret_ptr;
}




// ---------------------
bool ApplicationRun::String_Is_Graph (const string& str_i)
{
SET_TRACE;
  for (size_t i = 0; i < str_i.size(); i++)
  {
    if (!isgraph (str_i[i])) return false;
  }

  return true;
}