Question
Task#2 Your task is to use a queue as a buffer between a data transmission source and a data receiver. View the queue-diagram.pttx picture to
Task#2
Your task is to use a queue as a buffer between a data transmission source
and a data receiver.
View the queue-diagram.pttx picture to better understand the problem
description.
The data transmission source is implemented with the Sender class.
The data transmission source sends data at a rate of 500 characters per
second.
Once a Sender object is created, it will be an open data stream and will
attempt to send data at a
rate of 500 characters per second. When the Sender object is finished
sending all of its data, the data
stream will be closed. The Sender member function isStreamOpen() gives the
status of the data
stream (open or closed). For this assignment, the Sender object is
attempting to transmit 131 characters.
The Sender object member function int readFromStream(int arrayLength,
char rv[])
is how the data is acquired from the Sender object. If the Sender object
has data to transmit,
then the data will be inserted, in order, starting from array index 0 into
the rv[] array and
the number of characters sent is returned. If no characters were sent,
then the return value is
zero. The caller needs to provide the array rv[] and the array length
(arrayLength). The array
needs to be large enough to hold the maximum message length. For this
task, make the array 200 characters
in length.
The data receiver is implemented with the Receiver class. The data
receiver can receive data at
a rate of 200 characters per second. Once a Receiver object is created, it
is able to receive data.
The Receiver object member function int howManyCharToRx() indicates the
maximum number
of characters that Receiver object can receive at that time. You cannot
send more data than
that number. The Receiver object member function void sendChars(int
arrayLength, char x[])
sends the number of characters (specified by arrayLength) that are
contained in array x[] to the
Receiver object.
In the main() function, a Sender object (called tx), a Receiver object
(called rx) and a queue object
(called q) are created. The code should be added between the comments of
"add your code here".
The objective of the software is to transmit the data from the sender to
the receiver via a queue
in the fastest amount of time given the data rate constraints of the
Sender object and the Receiver
object. The Queue class is provided to you. In the main() function, you
should create
a polling loop. This polling loop should check the status of the Sender
object to see if the
stream is open and if there are any characters that need to be sent. If
characters are retrieved from the
Sender object, then they should be put on the queue. Next, the polling
loop should check the status of the
Receiver object to see if characters can be received. If characters can be
received and there are
characters on the queue to send, then take the number of allowed
characters off the queue and send
them to the Receiver object. The polling loop should be terminated when
the Sender class stream is closed
and the queue is empty. Implement your main polling loop in the indicated
space in the Main.cpp file.
The results of your data transfer will be contained in the Qresults.txt
file in the working directory.
Note, if you send chars to the Receiver object too fast, the chars will be
ignored and the transmission
will not be complete. You can only send up to the number of chars the
Receiver object is able to accept.
The files that are provided for this task are:
QMain.cpp
Sender.h
Sender.cpp
Receiver.h
Receiver.cpp
Queue.h
Queue.cpp
MyFileIO.h
MyFileIO.cpp
Only add code to the area in the Main.cpp that says "add your code here".
Do not change any interfaces or the code in the files that are provided.
____________________________________________________________
QMain.cpp
#include
#include
#include "Sender.h"
#include "Receiver.h"
#include "Queue.h"
#include "MyFileIO.h"
int main()
{
Sender tx;
Receiver rx;
Queue q;
// put your code here (below)
// put your code here (above)
std::string FILENAME = "Qresults.txt";
std::string outString;
char ch[10000]; // array large enough for the file output
int char_ptr = 0; // file index pointer
char_ptr = build_file_array(rx.getRxedMsg(), char_ptr, ch);
char_ptr = build_file_array(getCRLF(), char_ptr, ch);
char_ptr = build_file_array(getCode(char_ptr, ch), char_ptr, ch);
std::string max = "The maximum queue depth = ";
char_ptr = build_file_array(max + valueOf(q.getMaxSize()), char_ptr, ch);
char_ptr = build_file_array(getCRLF(), char_ptr, ch);
char_ptr = build_file_array(nowtoString(), char_ptr, ch);
writefile(FILENAME, ch, char_ptr);
return 0;
}
______________________________________________________
sender.h
#include
#include
#ifndef SENDER_H
#define SENDER_H
class Sender
{
public:
Sender();
~Sender();
bool isStreamOpen();
int readFromStream(int arrayLength, char rv[]);
private:
std::clock_t start;
int ptr;
const char *sendArray;
int charToSend;
int freq;
double timeBase;
};
#endif
________________________________________________________
reciever.h
#include
#include
#include
#ifndef RECEIVER_H
#define RECEIVER_H
class Receiver
{
public:
Receiver();
~Receiver();
int howManyCharToRx();
void sendChars(int arrayLength, char x[]);
std::string getRxedMsg();
private:
std::clock_t start;
char rxArray[10000]; // reserve enough room for this task
int freq;
double timeBase;
int ptr; // points to the rxed data array
int allowedChars; // how many chars can be sent at once
};
#endif
__________________________________________________________________________
queue.h
#ifndef QUEUE_H
#define QUEUE_H
const int QUEUE_CAPACITY = 1024;
typedef char QueueElement;
class Queue
{
public:
/***** Function Members *****/
/***** Constructor *****/
Queue();
/*-----------------------------------------------------------------------
Construct a Queue object.
Precondition: None.
Postcondition: An empty Queue object has been constructed; myFront
and myBack are initialized to -1 and myArray is an array with
QUEUE_CAPACITY elements of type QueueElement.
----------------------------------------------------------------------*/
bool empty() const;
/*-----------------------------------------------------------------------
Check if queue is empty.
Precondition: None.
Postcondition: True is returned if the queue is empty and false is
returned otherwise.
----------------------------------------------------------------------*/
void enqueue(const QueueElement & value);
/*-----------------------------------------------------------------------
Add a value to a queue.
Precondition: value is to be added to this queue.
Postcondition: value is added to back of queue provided there is space;
otherwise, a queue-full message is displayed and execution is
terminated.
-----------------------------------------------------------------------*/
void display(std::ostream & out) const;
/*-----------------------------------------------------------------------
Output the values stored in the queue.
Precondition: ostream out is open.
Postcondition: Queue's contents, from front to back, have been output
to out.
-----------------------------------------------------------------------*/
QueueElement front() const;
/*-----------------------------------------------------------------------
Retrieve value at front of queue (if any).
Precondition: Queue is nonempty.
Postcondition: Value at front of queue is returned, unless queue is
empty; in that case, an error message is displayed and a "garbage
value" is returned.
----------------------------------------------------------------------*/
void dequeue();
/*-----------------------------------------------------------------------
Remove value at front of queue (if any).
Precondition: Queue is nonempty.
Postcondition: Value at front of queue has been removed, unless queue
is empty; in that case, an error message is displayed and
execution is terminated.
----------------------------------------------------------------------*/
int getMaxSize() const;
private:
/***** Data Members *****/
int myFront, myBack;
int maxQueueSize;
int size;
QueueElement myArray[QUEUE_CAPACITY];
}; // end of class declaration
#endif
______________________________________________
/*-- Queue.cpp-----------------------------------------------------------
This file implements Queue member functions.
-------------------------------------------------------------------------*/
#include
#include "Queue.h"
//--- Definition of Queue constructor
Queue::Queue()
: myFront(0), myBack(0), maxQueueSize(0), size(0)
{}
//--- Definition of empty()
bool Queue::empty() const
{
return (myFront == myBack);
}
//--- Definition of enqueue()
void Queue::enqueue(const QueueElement & value)
{
int newBack = (myBack + 1) % QUEUE_CAPACITY;
if (newBack != myFront) // queue isn't full
{
myArray[myBack] = value;
myBack = newBack;
size++;
if (size > maxQueueSize)
{
maxQueueSize = size;
}
}
else
{
std::cerr << "*** Queue full -- can't add new value *** "
"Must increase value of QUEUE_CAPACITY in Queue.h ";
exit(1);
}
}
//--- Definition of display()
void Queue::display(std::ostream & out) const
{
for (int i = myFront; i != myBack; i = (i + 1) % QUEUE_CAPACITY)
out << myArray[i] << " ";
std::cout << std::endl;
}
//--- Definition of front()
QueueElement Queue::front() const
{
if (!empty())
return (myArray[myFront]);
else
{
std::cerr << "*** Queue is empty -- returning garbage value *** ";
QueueElement garbage[1];
return garbage[0];
}
}
//--- Definition of dequeue()
void Queue::dequeue()
{
if (!empty())
{
myFront = (myFront + 1) % QUEUE_CAPACITY;
size--;
}
else
{
std::cerr << "*** Queue is empty -- "
"can't remove a value *** ";
}
}
//--- Definition of getMaxSize()
int Queue::getMaxSize() const
{
return maxQueueSize;
}
________________________________________
//reciever.cpp----------------
#include
#include "Receiver.h"
Receiver::Receiver()
{
start = std::clock(); // capture the start time
freq = 2; // receive 2 char per 10 msec
ptr = 0; // points to the rxed data array
timeBase = .01; // in seconds (10 msec)
allowedChars = 0; // how many chars can be sent at once
}
int Receiver::howManyCharToRx()
{
int num = 0; // counts the chars for this request cycle
int count;
double duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
if (duration > timeBase)
{
start = std::clock();
count = (int)(duration / timeBase);
num = count * freq;
}
allowedChars = allowedChars + num;
return allowedChars;
}
void Receiver::sendChars(int arrayLength, char x[])
{
int count = arrayLength;
if (count > allowedChars)
{ // if requesting too many chars to send then
count = allowedChars;
}
for (int i = 0; i < count; i++)
{
rxArray[ptr+i] = x[i] - 1;
}
ptr = ptr + count;
allowedChars = allowedChars - count;
}
std::string Receiver::getRxedMsg()
{
std::string s(rxArray, ptr);
return s;
}
Receiver::~Receiver()
{
}
_______________________________________
//--sender.cpp
#include
#include "Sender.h"
Sender::Sender()
{
start = std::clock();
sendArray = "Dpohsbuvmbujpot-!Zpv!ibwf!tvddfttgvmmz!vtfe!b!rvfvf!bt!b!cvggfs!cfuxffo!bo!btzodispopvt!usbotnjuujoh!tpvsdf!boe!b!sfdfjwjoh!tpvsdf/";
charToSend = strlen(sendArray);
freq = 5; // char per 10 msec
timeBase = .01; // in seconds (10 msec)
ptr = 0; // index pointer to send data
}
bool Sender::isStreamOpen()
{
bool rv = true;
if (charToSend == 0)
rv = false;
return rv;
}
int Sender::readFromStream(int arrayLength, char rv[])
{
int count;
int num = 0;
double duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
if (duration > timeBase)
{
start = std::clock();
count = (int)(duration / timeBase);
num = count * freq;
if (num > arrayLength)
{
num = arrayLength;
}
if (num > charToSend)
{
num = charToSend;
}
for (int i = 0; i < num; i++)
{
rv[i] = sendArray[ptr+i];
}
ptr = ptr + num;
charToSend = charToSend - num;
}
return num;
}
Sender::~Sender()
{
}
_________________________________________
//---myfileIO.h--------------
#ifndef MYFILEIO_H #define MYFILEIO_H
#include
bool fileExists(std::string st); bool writefile(std::string filename, char *ptr, int length); std::string nowtoString(); void getChars(int beginst, int endst, char data[], int ptr, std::string st); int build_file_array(std::string st, int ptr, char data[]); std::string valueOf(int num); std::string getCRLF(); std::string getCode(int ptr, char data[]);
#endif
_________________________________________________
//--MyfileIO.cpp--------
#include
#include
#include
#include
#include
#include
#include "MyFileIO.h"
bool fileExists(std::string st)
{
bool result;
std::ifstream infile(st.c_str());
result = infile.good();
if (infile.is_open() == true)
{
infile.close();
}
return (result);
}
bool writefile(std::string filename, char *ptr, int length)
{
bool result = false;
std::ofstream outfile(filename.c_str(), std::ios::out | std::ios::binary);
if (outfile.is_open() == true)
{
outfile.write(ptr, length);
outfile.close();
result = true;
}
return(result);
}
std::string nowtoString()
{
time_t now = time(0);
tm tstruct;
char buf[80];
localtime_s(&tstruct, &now);
strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
std::string st(buf);
return st;
}
int build_file_array(std::string st, int ptr, char data[])
{
getChars(0, st.length(), data, ptr, st);
return (ptr + st.length());
}
void getChars(int beginst, int endst, char data[], int ptr, std::string st)
{
int i;
for (i = 0; i < (endst - beginst); i++)
{
data[i + ptr] = st[beginst + i];
}
}
std::string valueOf(int num)
{
std::stringstream ss;
ss << num;
return(ss.str());
}
std::string getCRLF()
{
std::string CRLF = "\x0D\x0A";
return CRLF;
}
std::string getCode(int ptr, char data[])
{
int code = 0;
for (int i = 0; i < ptr; i++)
{
code = code + (int)data[i];
}
return (valueOf(code) + getCRLF());
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started