BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_timetableloader

Detailed Description

Outline

Purpose

Provide a protocol (or pure interface) for loading timetables.

Classes

See also
bdlt_timetablecache, bdlt_timetable

Description

This component provides a protocol, bdlt::TimetableLoader, for loading timetables from a specific source. Each repository of timetable information can be supported by a distinct implementation of the TimetableLoader protocol. The protocol's primary method, load, loads a timetable into a bdlt::Timetable object. The timetable to load is identified by name, which is specified by a null-terminated C-style string (i.e., const char *).

Thread Safety

Unless otherwise documented, a single timetable loader object is not safe for concurrent access by multiple threads. Classes derived from bdlt::TimetableLoader that are specifically designed for concurrent access must be documented as such. Unless specifically documented otherwise, separate objects of classes derived from bdlt::TimetableLoader may safely be used in separate threads.

Usage

This section illustrates intended use of this component.

Example 1: Implementing the bdlt::TimetableLoader Protocol

This example demonstrates an elided concrete implementation of the bdlt::TimetableLoader protocol that interprets timetable information contained in ASCII strings that are formatted using JSON. Note that, in general, an implementation of bdlt::TimetableLoader must obtain timetable information from some data source. Our elided implementation leaves it unspecified as to where the JSON strings are obtained (i.e., whether from a file system, a database, a local or remote service, etc.).

First, we show the JSON format that our timetable loader accepts:

{
"firstDate": "YYYY-MM-DD",
"lastDate": "YYYY-MM-DD",
"initialTransitionCode": code,
"transitions":
[
{
"datetime": "YYYY-MM-DDThh:mm:ss",
"code": code
}
]
}

Note that "YYYY-MM-DD" is an ISO 8601 representation for the value of a bdlt::Date object, "YYYY-MM-DDThh:mm:ss" is an ISO 8601 representation for the value of a bdlt::Datetime object, and code is an integer greater than or equal to -1 (with -1 used to specify bdlt::Timetable::k_UNSET_TRANSITION_CODE). We assume that the four JSON attributes, "firstDate", "lastDate", "initialTransitionCode", and "transitions", must occur in the JSON string in the order in which they appear in the above display, but only "firstDate" and "lastDate" are required attributes.

Then, we define the interface of our implementation:

/// This class provides a concrete implementation of the
/// `bdlt::TimetableLoader` protocol (an abstract interface) for loading
/// a timetable. This elided implementation obtains timetable
/// information from ASCII strings formatted using JSON. The source of
/// the strings is unspecified.
class MyTimetableLoader : public bdlt::TimetableLoader {
public:
// CREATORS
/// Create a `MyTimetableLoader` object.
MyTimetableLoader();
/// Destroy this object.
virtual ~MyTimetableLoader();
// MANIPULATORS
/// Load, into the specified `result`, the timetable identified by
/// the specified `timetableName`. Return 0 on success, and a
/// non-zero value otherwise. If the timetable corresponding to
/// `timetableName` is not found, 1 is returned with no effect on
/// `*result`. If a non-zero value other than 1 is returned
/// (indicating a different error), `*result` is valid, but its
/// value is undefined.
virtual int load(bdlt::Timetable *result, const char *timetableName);
};
Definition bdlt_timetableloader.h:340
virtual int load(Timetable *result, const char *timetableName)=0
Definition bdlt_timetable.h:667

Next, we implement the creators, trivially, as MyTimetableLoader does not contain any instance data members:

// CREATORS
inline
MyTimetableLoader::MyTimetableLoader()
{
}
inline
MyTimetableLoader::~MyTimetableLoader()
{
}

Then, we implement the load function:

// MANIPULATORS
int MyTimetableLoader::load(bdlt::Timetable *result,
const char *timetableName)
{

Next, we look up the timetable identified by timetableName and load the corresponding text into a bsl::string object, json (as stated earlier, we do not specify in this example from where the timetable information is obtained):

// Obtain the information for the timetable identified by
// 'timetableName' from an unspecified data source and load it into the
// 'json' string.
// Since a JSON parser is not available to 'bdlt', this example assumes
// that 'json' is populated with the following specific data:
//..
// {
// "firstDate": "2018-01-01",
// "lastDate": "2018-12-31",
// "initialTransitionCode": 1,
// "transitions":
// [
// {
// "datetime": "2018-05-28T09:00:00",
// "code": 2
// },
// {
// "datetime": "2018-05-28T18:00:00",
// "code": 3
// }
// ]
// }
//..
// Similarly, we hard-wire the value of a status flag, 'rc', to
// indicate that this string was successfully retrieved from the data
// source.
int rc = 0; // success obtaining timetable information
if (rc != 0) {
return 1; // RETURN
}
Definition bslstl_string.h:1281

Note that the non-zero value 1 is returned only in the case where the timetable information corresponding to timetableName cannot be found (per the contract for the load method).

Then, we parse the "firstDate" and "lastDate" attributes from the json string, loading the results into like-named variables:

// Parse the "firstDate" and "lastDate" JSON attributes and load the
// results into 'firstDate' and 'lastDate', respectively. It is an
// error if either of the "firstDate" or "lastDate" attributes are
// missing, or if they are out of order.
bdlt::Date firstDate;
bdlt::Date lastDate;
// For the purposes of this Usage, we hard-wire the first and last
// dates that are hypothetically parsed from the 'json' string, and
// set the 'rc' status flag indicating that parsing succeeded.
firstDate.setYearMonthDay(2018, 1, 1);
lastDate.setYearMonthDay( 2018, 12, 31);
rc = 0; // success parsing "firstDate" and "lastDate" attributes
if (rc != 0 || firstDate > lastDate) {
return 2; // RETURN
}
result->reset();
result->setValidRange(firstDate, lastDate);
Definition bdlt_date.h:294
void setYearMonthDay(int year, int month, int day)
Definition bdlt_date.h:871
void setValidRange(const Date &firstDate, const Date &lastDate)
void reset()
Definition bdlt_timetable.h:1498

Next, we parse the "initialTransitionCode" attribute from json:

// For the purposes of this Usage, we hard-wire a boolean flag
// indicating that the "initialTransitionCode" attribute was
// hypothetically detected in the 'json' string.
bool isInitialTransitionCodePresent = true;
if (isInitialTransitionCodePresent) {
// For the purposes of this Usage, we hard-wire the initial
// transition code that is hypothetically parsed from the 'json'
// string, and set the 'rc' status flag indicating that parsing
// succeeded.
int code = 1;
rc = 0; // success parsing "initialTransitionCode" attribute
if (rc != 0) {
return 3; // RETURN
}
result->setInitialTransitionCode(code);
}
void setInitialTransitionCode(int code)

Now, we parse the "transitions" attribute from json and load the result into a bsl::vector<bsl::pair<bdlt::Datetime, int> > object, transitions:

// For the purposes of this Usage, we hard-wire a boolean flag
// indicating that the "transitions" attribute was hypothetically
// detected in the 'json' string.
bool isTransitionsPresent = true;
if (isTransitionsPresent) {
// Parse the "transitions" JSON attribute and load 'transitions'
// with the result.
// For the purposes of this Usage, we hard-wire the transitions
// that are hypothetically parsed from the 'json' string, and set
// the 'rc' status flag indicating that parsing succeeded.
bdlt::Datetime(2018, 5, 28, 9), 2));
bdlt::Datetime(2018, 5, 28, 18), 3));
rc = 0; // success parsing "transitions" attribute
if (rc != 0) {
return 4; // RETURN
}
transitions.begin();
while (it != transitions.end()) {
const bdlt::Date& date = it->first.date();
if (date < firstDate || date > lastDate || -1 > it->second) {
return 5; // RETURN
}
result->addTransition(
it->first,
it->second >= 0
? it->second
: bdlt::Timetable::k_UNSET_TRANSITION_CODE);
++it;
}
}
Definition bdlt_datetime.h:331
void addTransition(const Date &date, const Time &time, int code)
Definition bslstl_pair.h:1210
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2511
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2519
Definition bslstl_vector.h:1025
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:3760
Definition bbldc_basicisma30360.h:112

Our timetable loader imposes the requirement that the dates specified in the "transitions" JSON attribute must be within the range [firstDate .. lastDate] and the transition codes are non-negative or unset.

Finally, we return 0 indicating success:

return 0;
}