[Positioning] InputMedium::get_next_request() non-virtual

Refactor some code of Input{CSV,UDPSocket}::get_next_request() into
InputMedium::get_next_request().
The medium-specific code must now be implemented in
fill_current_request().
This commit is contained in:
Matteo Cypriani 2011-08-01 12:03:41 +02:00
parent 2886d87ab6
commit a71dcfdcfe
6 changed files with 95 additions and 87 deletions

View File

@ -17,24 +17,18 @@ using std::tr1::unordered_map ;
/**
* This function reads the next Request in the CSV input file. Blank
* lines and lines containing only spaces are skipped.
* This function fills the current Request from the CSV input file.
* Blank lines and lines containing only spaces are skipped until a line
* containing a request is found.
*
* #file should be opened before proceeding requests; otherwise,
* #current_request is \link Request::clear() cleared\endlink and a
* blank Request is returned. The file must be valid,
* semicolon-separated (\em not comma-separated).
*
* @return The read Request, or a blank Request in case of error (file
* not opened, end of file, invalid field or wrong number of fields in
* the line).
* @returns \em true if #current_request was correctly filled.
* @returns \em false in case of error (file not opened, end of file,
* invalid field or wrong number of fields in the line).
*/
const Request& InputCSV::get_next_request()
bool InputCSV::fill_current_request()
{
clear_current_request() ;
if (! file.next_line()) // End of file or error
return *current_request ;
return false ;
++current_line_nb ;
// Read Mobile MAC field
@ -43,13 +37,13 @@ const Request& InputCSV::get_next_request()
{
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read mac_mobile.\n" ;
return *current_request ;
return false ;
}
PosUtil::to_upper(mac_mobile) ;
if (! Configuration::bool_value("positioning.accept-new-mobiles") &&
! Stock::mobile_exists(mac_mobile))
return *current_request ;
return false ;
const Mobile &mobile = Stock::find_create_mobile(mac_mobile) ;
current_request->set_mobile(&mobile) ;
@ -59,11 +53,10 @@ const Request& InputCSV::get_next_request()
uint16_t type_r ;
if (! file.read_field(type_r))
{
// Wrong number of fields: blank current request
current_request->clear() ;
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read type.\n" ;
return *current_request ;
return false ;
}
type = type_r ;
current_request->set_type(type) ;
@ -72,11 +65,10 @@ const Request& InputCSV::get_next_request()
Timestamp timestamp ;
if (! file.read_timestamp(timestamp))
{
// Wrong number of fields: blank current request
current_request->clear() ;
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read timestamp.\n" ;
return *current_request ;
return false ;
}
current_request->set_time_sent(timestamp) ;
@ -84,11 +76,10 @@ const Request& InputCSV::get_next_request()
Point3D position ;
if (! file.read_point3d(position))
{
// Wrong number of fields: blank current request
current_request->clear() ;
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read coordinates.\n" ;
return *current_request ;
return false ;
}
// Read direction field
@ -96,11 +87,10 @@ const Request& InputCSV::get_next_request()
int direction_int ;
if (! file.read_field(direction_int))
{
// Wrong number of fields: blank current request
current_request->clear() ;
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read direction.\n" ;
return *current_request ;
return false ;
}
if (direction_int != 0)
direction = direction_int ;
@ -114,11 +104,10 @@ const Request& InputCSV::get_next_request()
int ss ;
if (! file.read_field(ss))
{
// Wrong number of fields: blank current request
current_request->clear() ;
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read mac_ap.\n" ;
return *current_request ;
return false ;
}
PosUtil::to_upper(mac_ap) ;
@ -131,10 +120,7 @@ const Request& InputCSV::get_next_request()
measurements[mac_ap].add_ss(ss) ;
}
if (measurements.empty())
{
current_request->clear() ;
return *current_request ;
}
return false ;
current_request->set_measurements(measurements) ;
// Calibration request?
@ -152,5 +138,5 @@ const Request& InputCSV::get_next_request()
else if (position)
current_request->set_real_position(position) ;
return *current_request ;
return true ;
}

View File

@ -16,6 +16,12 @@ class InputCSV: public InputMedium
protected:
CSVFileReader file ;
/** @name Operations */
//@{
/// Reads data & fills the current request
bool fill_current_request(void) ;
//@}
public:
InputCSV(const std::string &filename):
file(filename) {}
@ -28,12 +34,6 @@ public:
bool eof(void) const ;
//@}
/** @name Operations */
//@{
/// Reads the next request
const Request& get_next_request(void) ;
//@}
/** @name Operators */
//@{
operator bool(void) const ;

View File

@ -23,6 +23,45 @@ InputMedium::~InputMedium()
/* *** Operations *** */
/**
* Reads a Request, increments current_line_nb, updates #current_request
* and returns it.
*
* The input medium should be ready to be read before precessing
* requests; otherwise, #current_request is \link Request::clear()
* cleared\endlink and a blank Request is returned.
*
* @return The Request read, or an empty Request in case of error or
* EOF (note that when casted in bool, an empty Request is \em false,
* see Request::operator bool()).
*/
const Request& InputMedium::get_next_request()
{
clear_current_request() ;
if (! fill_current_request())
{
clear_current_request() ;
return *current_request ;
}
return *current_request ;
}
void InputMedium::clear_current_request()
{
if (dynamic_cast<CalibrationRequest*>(current_request) == NULL)
current_request->clear() ;
else
{
delete current_request ;
current_request = NULL ;
current_request = new Request() ;
}
}
void InputMedium::
current_request_to_calibration_request(
const ReferencePoint *const reference_point,
@ -47,16 +86,3 @@ current_request_to_calibration_request(
direction, request_type) ;
delete tmp ;
}
void InputMedium::clear_current_request()
{
if (dynamic_cast<CalibrationRequest*>(current_request) == NULL)
current_request->clear() ;
else
{
delete current_request ;
current_request = NULL ;
current_request = new Request() ;
}
}

View File

@ -18,6 +18,12 @@ protected:
/// Number of the current line proceeded
unsigned long current_line_nb ;
/** @name Operations */
//@{
/// Reads data & fills the current request
virtual bool fill_current_request(void) = 0 ;
//@}
public:
InputMedium(void) ;
@ -43,14 +49,7 @@ public:
//@{
/// Reads the next request
/**
* Reads a Request, increments current_line_nb, updates #current_request
* and returns it.
* @return The Request read, or an empty Request in case of error or
* EOF (note that when casted in bool, an empty Request is \em false,
* see Request::operator bool()).
*/
virtual const Request& get_next_request(void) = 0 ;
const Request& get_next_request(void) ;
/// Converts #current_request into a CalibrationRequest
void current_request_to_calibration_request(

View File

@ -72,22 +72,16 @@ bool InputUDPSocket::close_socket()
/**
* This function reads the next Request in the UDP input socket.
* It cannot read calibration requests.
* This function fills the current Request from the UDP input socket.
*
* #sockfd should be opened before processing requests; otherwise,
* #current_request is \link Request::clear() cleared\endlink and a
* blank Request is returned.
*
* @return The read Request, or a blank Request in case of error (socket
* not opened, bad packet format).
* @returns \em true if #current_request was correctly filled.
* @returns \em false in case of error (socket not opened, bad packet
* format).
*/
const Request& InputUDPSocket::get_next_request()
bool InputUDPSocket::fill_current_request()
{
clear_current_request() ;
if (eof())
return *current_request ;
return false ;
struct sockaddr_in client; // UDP client structure
socklen_t client_len = sizeof(client) ; // Size of clients
@ -98,8 +92,8 @@ const Request& InputUDPSocket::get_next_request()
(struct sockaddr *) &client, &client_len) ;
if (nread <= 0)
{
cerr << "No request received!" << endl ;
return *current_request ;
cerr << "InputUDPSocket: No request received!" << endl ;
return false ;
}
// Endianess conversions
@ -113,7 +107,7 @@ const Request& InputUDPSocket::get_next_request()
if (! Configuration::bool_value("positioning.accept-new-mobiles") &&
! Stock::mobile_exists(mac_mobile))
return *current_request ;
return false ;
const Mobile &mobile = Stock::find_create_mobile(mac_mobile) ;
current_request->set_mobile(&mobile) ;
@ -139,8 +133,7 @@ const Request& InputUDPSocket::get_next_request()
if (nread <= 0)
{
cerr << "No request info received!" << endl ;
current_request->clear() ;
return *current_request ;
return false ;
}
string mac_ap(
owl_mac_bytes_to_string(request_info.ap_mac_addr_bytes)) ;
@ -156,10 +149,7 @@ const Request& InputUDPSocket::get_next_request()
(request_info.antenna_signal_dbm)) ;
}
if (measurements.empty())
{
current_request->clear() ;
return *current_request ;
}
return false ;
current_request->set_measurements(measurements) ;
// Calibration request?
@ -198,5 +188,5 @@ const Request& InputUDPSocket::get_next_request()
else if (position)
current_request->set_real_position(position) ;
return *current_request ;
return true ;
}

View File

@ -14,6 +14,15 @@ protected:
//@{
/// Initialises the socket
bool init_socket(void) ;
/// Reads data & fills the current request
/**
* This function fills the current Request from the data read from
* the input medium.
*
* @returns \em true if #current_request was correctly filled.
* @returns \em false in case of error.
*/
bool fill_current_request(void) ;
//@}
public:
@ -29,8 +38,6 @@ public:
/** @name Operations */
//@{
/// Reads the next request
const Request& get_next_request(void) ;
/// Closes the socket
bool close_socket(void) ;
//@}