/* Copyright 2012. Bloomberg Finance L.P.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: The above
* copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
// blpapi_session.h -*-C++-*-
#ifndef INCLUDED_BLPAPI_SESSION
#define INCLUDED_BLPAPI_SESSION
//@PURPOSE: Provide consumer session to get Bloomberg Service.
//
//@CLASSES:
// blpapi::Session: A consumer session for consuming service
//
//@DESCRIPTION: This component implements a consumer session for getting
// services.
#ifndef INCLUDED_BLPAPI_ABSTRACTSESSION
#include <blpapi_abstractsession.h>
#endif
#ifndef INCLUDED_BLPAPI_CORRELATIONID
#include <blpapi_correlationid.h>
#endif
#ifndef INCLUDED_BLPAPI_DEFS
#include <blpapi_defs.h>
#endif
#ifndef INCLUDED_BLPAPI_EVENT
#include <blpapi_event.h>
#endif
#ifndef INCLUDED_BLPAPI_EVENTDISPATCHER
#include <blpapi_eventdispatcher.h>
#endif
#ifndef INCLUDED_BLPAPI_IDENTITY
#include <blpapi_identity.h>
#endif
#ifndef INCLUDED_BLPAPI_REQUEST
#include <blpapi_request.h>
#endif
#ifndef INCLUDED_BLPAPI_SERVICE
#include <blpapi_service.h>
#endif
#ifndef INCLUDED_BLPAPI_SESSIONOPTIONS
#include <blpapi_sessionoptions.h>
#endif
#ifndef INCLUDED_BLPAPI_SUBSCRIPTIONLIST
#include <blpapi_subscriptionlist.h>
#endif
#ifndef INCLUDED_BLPAPI_TYPES
#include <blpapi_types.h>
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void(*blpapi_EventHandler_t)(blpapi_Event_t* event,
blpapi_Session_t* session,
void *userData);
BLPAPI_EXPORT
blpapi_Session_t* blpapi_Session_create(
blpapi_SessionOptions_t *parameters,
blpapi_EventHandler_t handler,
blpapi_EventDispatcher_t* dispatcher,
void *userData);
BLPAPI_EXPORT
void blpapi_Session_destroy(
blpapi_Session_t *session);
BLPAPI_EXPORT
int blpapi_Session_start(
blpapi_Session_t *session);
BLPAPI_EXPORT
int blpapi_Session_startAsync(
blpapi_Session_t *session);
BLPAPI_EXPORT
int blpapi_Session_stop(
blpapi_Session_t* session);
BLPAPI_EXPORT
int blpapi_Session_stopAsync(
blpapi_Session_t* session);
BLPAPI_EXPORT
int blpapi_Session_nextEvent(
blpapi_Session_t* session,
blpapi_Event_t **eventPointer,
unsigned int timeoutInMilliseconds);
BLPAPI_EXPORT
int blpapi_Session_tryNextEvent(
blpapi_Session_t* session,
blpapi_Event_t **eventPointer);
BLPAPI_EXPORT
int blpapi_Session_subscribe(
blpapi_Session_t *session,
const blpapi_SubscriptionList_t *subscriptionList,
const blpapi_Identity_t* handle,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_resubscribe(
blpapi_Session_t *session,
const blpapi_SubscriptionList_t *resubscriptionList,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_resubscribeWithId(
blpapi_Session_t *session,
const blpapi_SubscriptionList_t *resubscriptionList,
int resubscriptionId,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_unsubscribe(
blpapi_Session_t *session,
const blpapi_SubscriptionList_t *unsubscriptionList,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_cancel(
blpapi_Session_t *session,
const blpapi_CorrelationId_t *correlationIds,
size_t numCorrelationIds,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_setStatusCorrelationId(
blpapi_Session_t *session,
const blpapi_Service_t *service,
const blpapi_Identity_t *identity,
const blpapi_CorrelationId_t *correlationId);
BLPAPI_EXPORT
int blpapi_Session_sendRequest(
blpapi_Session_t *session,
const blpapi_Request_t *request,
blpapi_CorrelationId_t *correlationId,
blpapi_Identity_t *identity,
blpapi_EventQueue_t *eventQueue,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_sendAuthorizationRequest(
blpapi_Session_t *session,
const blpapi_Request_t *request,
blpapi_Identity_t *identity,
blpapi_CorrelationId_t *correlationId,
blpapi_EventQueue_t *eventQueue,
const char *requestLabel,
int requestLabelLen);
BLPAPI_EXPORT
int blpapi_Session_openService(
blpapi_Session_t *session,
const char* serviceName);
BLPAPI_EXPORT
int blpapi_Session_openServiceAsync(
blpapi_Session_t *session,
const char* serviceName,
blpapi_CorrelationId_t *correlationId);
BLPAPI_EXPORT
int blpapi_Session_generateToken(
blpapi_Session_t *session,
blpapi_CorrelationId_t *correlationId,
blpapi_EventQueue_t *eventQueue);
BLPAPI_EXPORT
int blpapi_Session_getService(
blpapi_Session_t *session,
blpapi_Service_t **service,
const char* serviceName);
// Deprecated: Use blpapi_Session_createIdentity instead
BLPAPI_EXPORT
blpapi_UserHandle_t* blpapi_Session_createUserHandle(
blpapi_Session_t *session);
BLPAPI_EXPORT
blpapi_Identity_t* blpapi_Session_createIdentity(
blpapi_Session_t *session);
BLPAPI_EXPORT
blpapi_AbstractSession_t* blpapi_Session_getAbstractSession(
blpapi_Session_t* session);
BLPAPI_EXPORT
blpapi_SubscriptionIterator_t* blpapi_SubscriptionItr_create(
blpapi_Session_t *session);
BLPAPI_EXPORT
void blpapi_SubscriptionItr_destroy(
blpapi_SubscriptionIterator_t *iterator);
BLPAPI_EXPORT
int blpapi_SubscriptionItr_next(
blpapi_SubscriptionIterator_t *iterator,
const char** subscriptionString,
blpapi_CorrelationId_t *correlationId,
int *status);
BLPAPI_EXPORT
int blpapi_SubscriptionItr_isValid(
const blpapi_SubscriptionIterator_t *iterator);
#ifdef __cplusplus
}
#ifndef INCLUDED_CSTRING
#include <cstring> // for std::memset
#define INCLUDED_CSTRING
#endif
namespace BloombergLP {
namespace blpapi {
class Session;
// ==================
// class EventHandler
// ==================
class EventHandler {
// Defines the callback supplied by the application to process
// Events.
//
// Applications which use event driven programming supply
// instances of their own subclass of this class to the Session to
// receive callbacks when an Event is available.
public:
virtual ~EventHandler() = 0;
virtual bool processEvent(
const Event& event,
Session *session) = 0;
// An implementation of processEvent should process the specified
// 'event' which originates from the specified 'session' and
// return true to indicate events should continue to be delivered
// or false to terminate dispatching of events.
//
// If the application wishes to process the event further
// after returning from the processEvents() call it must make
// a copy of the Event to ensure the underlying data is not
// freed.
};
extern "C" void eventHandlerAdapter(blpapi_Event_t *event,
blpapi_Session_t *,
void *userData);
// Adapter 'blpapi_EventHandler_t' implementation that dispatches the
// specified 'event' to a 'blpapi::Session' pointed by 'userData'.
// =============
// class Session
// =============
class Session : public AbstractSession {
// This class provides a consumer session for making requests for Bloomberg
// services.
//
// Sessions manage access to services either by requests and
// responses or subscriptions. A Session can dispatch events and
// replies in either a synchronous or asynchronous mode. The mode
// of a Session is determined when it is constructed and cannot be
// changed subsequently.
//
// A Session is asynchronous if an EventHandler object is
// supplied when it is constructed. The setEventHandler() method
// may be called to adjust the way events are handled subsequently
// and the nextEvent() method may not be called. All incoming
// events are delivered to the EventHandler(s) supplied on
// construction or subsequently using setEventHandler().
//
// A Session is synchronous if an EventHandler object is not
// supplied when it is constructed. The nextEvent() method must be
// called to read incoming events and the setEventHandler() method
// may not be called.
//
// Several methods in Session take a CorrelationId parameter. The
// application may choose to supply its own CorrelationId values
// or allow the Session to create values. If the application
// supplies its own CorrelationId values it must manage their
// lifetime such that the same value is not reused for more than
// one operation at a time. The lifetime of a CorrelationId begins
// when it is supplied in a method invoked on a Session and ends
// either when it is explicitly cancelled using cancel() or
// unsubscribe(), when a RESPONSE Event (not a PARTIAL_RESPONSE)
// containing it is received or when a SUBSCRIPTION_STATUS Event
// which indicates that the subscription it refers to has been
// terminated is received.
//
// When using an asynchronous Session the application must be
// aware that because the callbacks are generated from another
// thread they may be processed before the call which generates
// them has returned. For example, the SESSION_STATUS Event
// generated by a startAsync() may be processed before
// startAsync() has returned (even though startAsync() itself will
// not block).
//
// This becomes more significant when Session generated
// CorrelationIds are in use. For example, if a call to
// subscribe() which returns a Session generated CorrelationId has
// not completed before the first Events which contain that
// CorrelationId arrive the application may not be able to
// interpret those events correctly. For this reason, it is
// preferable to use user generated CorrelationIds when using
// asynchronous Sessions. This issue does not arise when using a
// synchronous Session as long as the calls to subscribe() etc are
// made on the same thread as the calls to nextEvent().
blpapi_Session_t *d_handle_p;
EventHandler *d_eventHandler_p;
private:
// NOT IMPLEMENTED
Session(const Session&);
Session& operator=(const Session&);
friend void eventHandlerAdapter(blpapi_Event_t *event,
blpapi_Session_t *,
void *userData);
public:
// The possible statuses a subscription may be in.
enum SubscriptionStatus {
UNSUBSCRIBED = BLPAPI_SUBSCRIPTIONSTATUS_UNSUBSCRIBED,
// No longer active, terminated by API.
SUBSCRIBING = BLPAPI_SUBSCRIPTIONSTATUS_SUBSCRIBING,
// Initiated but no updates received.
SUBSCRIBED = BLPAPI_SUBSCRIPTIONSTATUS_SUBSCRIBED,
// Updates are flowing.
CANCELLED = BLPAPI_SUBSCRIPTIONSTATUS_CANCELLED,
// No longer active, terminated by Application.
PENDING_CANCELLATION = BLPAPI_SUBSCRIPTIONSTATUS_PENDING_CANCELLATION
};
Session(const SessionOptions& options = SessionOptions(),
EventHandler* eventHandler=0,
EventDispatcher* eventDispatcher=0);
// Construct a Session using the optionally specified
// 'options', the optionally specified 'eventHandler' and the
// optionally specified 'eventDispatcher'.
//
// See the SessionOptions documentation for details on what
// can be specified in the 'options'.
//
// If 'eventHandler' is not 0 then this Session will operation
// in asynchronous mode, otherwise the Session will operate in
// synchronous mode.
//
// If 'eventDispatcher' is 0 then the Session will create a
// default EventDispatcher for this Session which will use a
// single thread for dispatching events. For more control over
// event dispatching a specific instance of EventDispatcher
// can be supplied. This can be used to share a single
// EventDispatcher amongst multiple Session objects.
//
// If an 'eventDispatcher' is supplied which uses more than
// one thread the Session will ensure that events which should
// be ordered are passed to callbacks in a correct order. For
// example, partial response to a request or updates to a
// single subscription.
//
// If 'eventHandler' is 0 and the 'eventDispatcher' is not
// 0 an exception is thrown.
//
// Each EventDispatcher uses its own thread or pool of
// threads so if you want to ensure that a session which
// receives very large messages and takes a long time to
// process them does not delay a session that receives small
// messages and processes each one very quickly then give each
// one a separate EventDispatcher.
explicit Session(blpapi_Session_t *handle);
virtual ~Session();
// Destructor.
// MANIPULATORS
virtual bool start();
// Attempt to start this Session and blocks until the Session
// has started or failed to start. If the Session is started
// successfully 'true' is returned, otherwise 'false' is
// returned. Before start() returns a SESSION_STATUS Event is
// generated. If this is an asynchronous Session then the
// SESSION_STATUS may be processed by the registered
// EventHandler before start() has returned. A Session may
// only be started once.
virtual bool startAsync();
// Attempt to begin the process to start this Session and
// return 'true' if successful, otherwise return 'false'. The
// application must monitor events for a SESSION_STATUS Event
// which will be generated once the Session has started or if
// it fails to start. If this is an asynchronous Session then
// the SESSION_STATUS Event may be processed by the registered
// EventHandler before startAsync() has returned. A Session may
// only be started once.
virtual void stop();
// Stop operation of this session and block until all callbacks to
// EventHandler objects relating to this Session which are currently in
// progress have completed (including the callback to handle the
// SESSION_STATUS Event with SessionTerminated message this call
// generates). Once this returns no further callbacks to EventHandlers
// will occur. If stop() is called from within an EventHandler callback
// the behavior is undefined and may result in a deadlock. Once a
// Session has been stopped it can only be destroyed.
virtual void stopAsync();
// Begin the process to stop this Session and return immediately. The
// application must monitor events for a SESSION_STATUS Event with
// SessionTerminated message which will be generated once the
// Session has been stopped. After this SESSION_STATUS Event no further
// callbacks to EventHandlers will occur. This method can be called
// from within an EventHandler callback to stop Sessions using
// non-default (external) EventDispatcher. Once a Session has been
// stopped it can only be destroyed.
virtual Event nextEvent(int timeout=0);
// Returns the next available Event for this session. If there
// is no event available this will block for up to the
// specified 'timeoutMillis' milliseconds for an Event to
// arrive. A value of 0 for 'timeoutMillis' (the default)
// indicates nextEvent() should not timeout and will not
// return until the next Event is available.
//
// If nextEvent() returns due to a timeout it will return an
// event of type 'EventType::TIMEOUT'.
//
// If this is invoked on a Session which was created in
// asynchronous mode an InvalidStateException is thrown.
virtual int tryNextEvent(Event *event);
// If there are Events available for the session, load the next Event
// into event and return 0 indicating success. If there is no event
// available for the session, return a non-zero value with no effect
// on event. This method never blocks.
void subscribe(
const SubscriptionList& subscriptionList,
const Identity& identity,
const char *requestLabel = 0,
int requestLabelLen = 0);
// Begin subscriptions for each entry in the specified
// 'subscriptionList' using the specified 'identity' for
// authorization. If the optional 'requestLabel' and
// 'requestLabelLen' are provided they define a string which
// will be recorded along with any diagnostics for this
// operation. There must be at least 'requestLabelLen'
// printable characters at the location 'requestLabel'.
//
// A SUBSCRIPTION_STATUS Event will be generated for each
// entry in the 'subscriptionList'.
void subscribe(
const SubscriptionList& subscriptionList,
const char *requestLabel = 0,
int requestLabelLen = 0);
// Begin subscriptions for each entry in the specified
// 'subscriptionList' using the default authorization
// information. If the optional 'requestLabel' and
// 'requestLabelLen' are provided they define a string which
// will be recorded along with any diagnostics for this
// operation. There must be at least 'requestLabelLen'
// printable characters at the location 'requestLabel'.
//
// A SUBSCRIPTION_STATUS Event will be generated for each
// entry in the 'subscriptionList'.
void unsubscribe(const SubscriptionList& subscriptionList);
// Cancel each of the current subscriptions identified by the
// specified 'subscriptionList'. If the correlation ID of any
// entry in the 'subscriptionList' does not identify a current
// subscription then that entry is ignored. All entries which
// have valid correlation IDs will be cancelled.
//
// Once this call returns the correlation ids in the
// 'subscriptionList' will not be seen in any subsequent
// Message obtained from a MessageIterator by calling
// next(). However, any Message currently pointed to by a
// MessageIterator when unsubscribe() is called is not
// affected even if it has one of the correlation IDs in the
// 'subscriptionList'. Also any Message where a reference has
// been retained by the application may still contain a
// correlation ID from the 'subscriptionList'. For these
// reasons, although technically an application is free to
// re-use the correlation IDs as soon as this method returns
// it is preferable not to aggressively re-use correlation
// IDs, particularly with an asynchronous Session.
void resubscribe(const SubscriptionList& subscriptions);
// Modify each subscription in the specified
// 'subscriptionList' to reflect the modified options
// specified for it.
//
// For each entry in the 'subscriptionList' which has a
// correlation ID which identifies a current subscription the
// modified options replace the current options for the
// subscription and a SUBSCRIPTION_STATUS event will be
// generated in the event stream before the first update based
// on the new options. If the correlation ID of an entry in
// the 'subscriptionList' does not identify a current
// subscription then an exception is thrown.
void resubscribe(
const SubscriptionList& subscriptions,
const char *requestLabel,
int requestLabelLen);
// Modify each subscription in the specified
// 'subscriptionList' to reflect the modified options
// specified for it. The specified 'requestLabel' and
// 'requestLabelLen' define a string which
// will be recorded along with any diagnostics for this
// operation. There must be at least 'requestLabelLen'
// printable characters at the location 'requestLabel'.
//
// For each entry in the 'subscriptionList' which has a
// correlation ID which identifies a current subscription the
// modified options replace the current options for the
// subscription and a SUBSCRIPTION_STATUS event will be
// generated in the event stream before the first update based
// on the new options. If the correlation ID of an entry in
// the 'subscriptionList' does not identify a current
// subscription then an exception is thrown.
void resubscribe(
const SubscriptionList& subscriptions,
int resubscriptionId);
// Modify each subscription in the specified
// 'subscriptionList' to reflect the modified options
// specified for it.
//
// For each entry in the 'subscriptionList' which has a
// correlation ID which identifies a current subscription the
// modified options replace the current options for the
// subscription and a SUBSCRIPTION_STATUS event containing the
// specified 'resubscriptionId' will be generated in the event
// stream before the first update based on the new options. If
// the correlation ID of an entry in the 'subscriptionList'
// does not identify a current subscription then an exception
// is thrown.
void resubscribe(
const SubscriptionList& subscriptions,
int resubscriptionId,
const char *requestLabel,
int requestLabelLen);
// Modify each subscription in the specified
// 'subscriptionList' to reflect the modified options
// specified for it. The specified 'requestLabel' and
// 'requestLabelLen' define a string which
// will be recorded along with any diagnostics for this
// operation. There must be at least 'requestLabelLen'
// printable characters at the location 'requestLabel'.
//
// For each entry in the 'subscriptionList' which has a
// correlation ID which identifies a current subscription the
// modified options replace the current options for the
// subscription and a SUBSCRIPTION_STATUS event containing the
// specified 'resubscriptionId' will be generated in the event
// stream before the first update based on the new options. If
// the correlation ID of an entry in the 'subscriptionList'
// does not identify a current subscription then an exception
// is thrown.
void setStatusCorrelationId(
const Service& service,
const CorrelationId& correlationID);
void setStatusCorrelationId(
const Service& service,
const Identity& identity,
const CorrelationId& correlationID);
// Set the CorrelationID on which service status messages will be
// received.
// Note: No service status messages are received prior to this call
CorrelationId sendRequest(
const Request& request,
const CorrelationId& correlationId=CorrelationId(),
EventQueue *eventQueue=0,
const char *requestLabel = 0,
int requestLabelLen = 0);
// Send the specified 'request'. If the optionally specified
// 'correlationId' is supplied use it otherwise create a
// CorrelationId. The actual CorrelationId used is
// returned. If the optionally specified 'eventQueue' is
// supplied all events relating to this Request will arrive on
// that EventQueue. If the optional 'requestLabel' and
// 'requestLabelLen' are provided they define a string which
// will be recorded along with any diagnostics for this
// operation. There must be at least 'requestLabelLen'
// printable characters at the location 'requestLabel'.
//
// A successful request will generate zero or more
// PARTIAL_RESPONSE Messages followed by exactly one RESPONSE
// Message. Once the final RESPONSE Message has been received
// the correlation ID associated with this request may be
// re-used. If the request fails at any stage a REQUEST_STATUS
// will be generated after which the correlation ID associated
// with the request may be re-used.
CorrelationId sendRequest(
const Request& request,
const Identity& user,
const CorrelationId& correlationId=CorrelationId(),
EventQueue *eventQueue=0,
const char *requestLabel = 0,
int requestLabelLen = 0);
// Send the specified 'request' using the specified
// 'identity' for authorization. If the optionally specified
// 'correlationId' is supplied use it otherwise create a
// CorrelationId. The actual CorrelationId used is
// returned. If the optionally specified 'eventQueue' is
// supplied all events relating to this Request will arrive on
// that EventQueue. If the optional 'requestLabel' and
// 'requestLabelLen' are provided they define a string which
// will be recorded along with any diagnostics for this
// operation. There must be at least 'requestLabelLen'
// printable characters at the location 'requestLabel'.
//
// A successful request will generate zero or more
// PARTIAL_RESPONSE Messages followed by exactly one RESPONSE
// Message. Once the final RESPONSE Message has been received
// the CorrelationId associated with this request may be
// re-used. If the request fails at any stage a REQUEST_STATUS
// will be generated after which the CorrelationId associated
// with the request may be re-used.
// ACCESSORS
blpapi_Session_t* handle() const;
};
// ==========================
// class SubscriptionIterator
// ==========================
class SubscriptionIterator {
// An iterator which steps through all the subscriptions in a Session.
//
// The SubscriptionIterator can be used to iterate over all the
// active subscriptions for a Session. However, with an
// asynchronous Session it is possible for the set of active
// subscriptions to change whilst the SubscriptionIterator is
// being used. The SubscriptionIterator is guaranteed to never
// return the same subscription twice. However, the subscription
// the iterator points to may no longer be active. In this case
// the result of subscriptionStatus() will be UNSUBSCRIBED or
// CANCELLED.
blpapi_SubscriptionIterator_t *d_handle_p;
const char *d_subscriptionString;
CorrelationId d_correlationId;
int d_status;
bool d_isValid;
private:
// NOT IMPLEMENTED
SubscriptionIterator(const SubscriptionIterator&);
SubscriptionIterator& operator=(const SubscriptionIterator&);
public:
SubscriptionIterator(Session *session);
// Construct a forward iterator to iterate over the
// subscriptions of the specified 'session'. The
// SubscriptionIterator is created in a state where next()
// must be called to advance it to the first item.
~SubscriptionIterator();
// Destructor.
// MANIPULATORS
bool next();
// Attempt to advance this iterator to the next subscription
// record. Returns 'true' on success and 'false' if there are
// no more subscriptions. After next() returns true isValid()
// is guaranteed to return true until the next call to
// next(). After next() returns false isValid() will return
// false.
// ACCESSORS
bool isValid() const;
// Returns true if this iterator is currently positioned on a
// valid subscription. Returns false otherwise.
const char* subscriptionString() const;
// Returns a pointer to a null-terminated string which
// contains the subscription string for this subscription. The
// pointer returned remains valid until this
// SubscriptionIterator is destroyed or the underlying
// Session is destroyed or next() is called.
const CorrelationId& correlationId() const;
// Returns the CorrelationId for this subscription.
Session::SubscriptionStatus subscriptionStatus() const;
// Returns the status of this subscription.
blpapi_SubscriptionIterator_t* handle() const;
};
// ============================================================================
// INLINE FUNCTION DEFINITIONS
// ============================================================================
// ------------------
// class EventHandler
// ------------------
inline
EventHandler::~EventHandler()
{
}
// FREE FUNCTIONS
extern "C"
inline void eventHandlerAdapter(blpapi_Event_t *event,
blpapi_Session_t *,
void *userData)
{
Session *session = reinterpret_cast<Session*>(userData);
session->d_eventHandler_p->processEvent(Event(event), session);
}
// -------------
// class Session
// -------------
inline
Session::Session(const SessionOptions& parameters,
EventHandler* handler,
EventDispatcher* dispatcher)
: d_eventHandler_p(handler)
{
d_handle_p = blpapi_Session_create(
parameters.handle(),
handler ? &eventHandlerAdapter : 0,
dispatcher ? dispatcher->impl() : 0,
this);
initAbstractSessionHandle(blpapi_Session_getAbstractSession(d_handle_p));
}
inline
Session::Session(blpapi_Session_t *newHandle)
: d_handle_p(newHandle)
{
initAbstractSessionHandle(blpapi_Session_getAbstractSession(d_handle_p));
}
inline
Session::~Session()
{
blpapi_Session_destroy(d_handle_p);
}
inline
bool Session::start()
{
return blpapi_Session_start(d_handle_p) ? false : true;
}
inline
bool Session::startAsync()
{
return blpapi_Session_startAsync(d_handle_p) ? false : true;
}
inline
void Session::stop()
{
blpapi_Session_stop(d_handle_p);
}
inline
void Session::stopAsync()
{
blpapi_Session_stopAsync(d_handle_p);
}
inline
Event Session::nextEvent(int timeout)
{
blpapi_Event_t *event;
ExceptionUtil::throwOnError(
blpapi_Session_nextEvent(d_handle_p, &event, timeout));
return Event(event);
}
inline
int Session::tryNextEvent(Event *event)
{
blpapi_Event_t *impl;
int ret = blpapi_Session_tryNextEvent(d_handle_p, &impl);
if (0 == ret) {
*event = Event(impl);
}
return ret;
}
inline
void Session::subscribe(const SubscriptionList& subscriptions,
const char *requestLabel,
int requestLabelLen)
{
ExceptionUtil::throwOnError(
blpapi_Session_subscribe(d_handle_p, subscriptions.impl(),
0, requestLabel, requestLabelLen)
);
}
inline
void Session::subscribe(const SubscriptionList& subscriptions,
const Identity& identity,
const char *requestLabel,
int requestLabelLen)
{
ExceptionUtil::throwOnError(
blpapi_Session_subscribe(d_handle_p, subscriptions.impl(),
identity.handle(), requestLabel, requestLabelLen)
);
}
inline
void Session::resubscribe(const SubscriptionList& subscriptions)
{
ExceptionUtil::throwOnError(
blpapi_Session_resubscribe(d_handle_p, subscriptions.impl(),
0, 0)
);
}
inline
void Session::resubscribe(const SubscriptionList& subscriptions,
const char *requestLabel,
int requestLabelLen)
{
ExceptionUtil::throwOnError(
blpapi_Session_resubscribe(d_handle_p, subscriptions.impl(),
requestLabel, requestLabelLen)
);
}
inline
void Session::resubscribe(const SubscriptionList& subscriptions,
int resubscriptionId)
{
ExceptionUtil::throwOnError(
BLPAPI_CALL_SESSION_RESUBSCRIBEWITHID(d_handle_p, subscriptions.impl(),
resubscriptionId, 0, 0)
);
}
inline
void Session::resubscribe(const SubscriptionList& subscriptions,
int resubscriptionId,
const char *requestLabel,
int requestLabelLen)
{
ExceptionUtil::throwOnError(
BLPAPI_CALL_SESSION_RESUBSCRIBEWITHID(d_handle_p, subscriptions.impl(),
resubscriptionId, requestLabel, requestLabelLen)
);
}
inline
void Session::unsubscribe(const SubscriptionList& list)
{
ExceptionUtil::throwOnError(
blpapi_Session_unsubscribe(d_handle_p, list.impl(), 0, 0)
);
}
inline
void Session::setStatusCorrelationId(
const Service& service,
const CorrelationId& correlationID)
{
ExceptionUtil::throwOnError(
blpapi_Session_setStatusCorrelationId(
d_handle_p,
service.handle(),
0,
&correlationID.impl()));
}
inline
void Session::setStatusCorrelationId(
const Service& service,
const Identity& identity,
const CorrelationId& correlationID)
{
ExceptionUtil::throwOnError(
blpapi_Session_setStatusCorrelationId(
d_handle_p,
service.handle(),
identity.handle(),
&correlationID.impl()));
}
inline
CorrelationId Session::sendRequest(
const Request& request,
const Identity& identity,
const CorrelationId& correlationId,
EventQueue *eventQueue,
const char *requestLabel,
int requestLabelLen)
{
CorrelationId retCorrelationId(correlationId);
ExceptionUtil::throwOnError(blpapi_Session_sendRequest(
d_handle_p,
request.handle(),
const_cast<blpapi_CorrelationId_t *>(&retCorrelationId.impl()),
identity.handle(),
eventQueue ? eventQueue->handle() : 0,
requestLabel,
requestLabelLen));
return retCorrelationId;
}
inline
CorrelationId Session::sendRequest(
const Request& request,
const CorrelationId& correlationId,
EventQueue *eventQueue,
const char *requestLabel,
int requestLabelLen)
{
CorrelationId retCorrelationId(correlationId);
ExceptionUtil::throwOnError(blpapi_Session_sendRequest(
d_handle_p,
request.handle(),
const_cast<blpapi_CorrelationId_t *>(&retCorrelationId.impl()),
0,
eventQueue ? eventQueue->handle() : 0,
requestLabel,
requestLabelLen));
return retCorrelationId;
}
inline
blpapi_Session_t* Session::handle() const
{
return d_handle_p;
}
// --------------------------
// class SubscriptionIterator
// --------------------------
inline
SubscriptionIterator::SubscriptionIterator(Session *session)
: d_isValid(false)
{
d_handle_p = blpapi_SubscriptionItr_create(session->handle());
}
inline
SubscriptionIterator::~SubscriptionIterator()
{
blpapi_SubscriptionItr_destroy(d_handle_p);
}
inline
bool SubscriptionIterator::next()
{
blpapi_CorrelationId_t nextCorrelationIdImpl;
d_isValid = !blpapi_SubscriptionItr_next(d_handle_p,
&d_subscriptionString,
&nextCorrelationIdImpl,
&d_status);
d_correlationId = d_isValid
? CorrelationId(nextCorrelationIdImpl)
: CorrelationId();
return d_isValid;
}
inline
bool SubscriptionIterator::isValid() const
{
return d_isValid;
}
inline
blpapi_SubscriptionIterator_t* SubscriptionIterator::handle() const
{
return d_handle_p;
}
inline
const char* SubscriptionIterator::subscriptionString() const
{
if (!isValid()) {
ExceptionUtil::throwOnError(BLPAPI_ERROR_ILLEGAL_STATE);
}
return d_subscriptionString;
}
inline
const CorrelationId& SubscriptionIterator::correlationId() const
{
if (!isValid()) {
ExceptionUtil::throwOnError(BLPAPI_ERROR_ILLEGAL_STATE);
}
return d_correlationId;
}
inline
Session::SubscriptionStatus SubscriptionIterator::subscriptionStatus() const
{
if (!isValid()) {
ExceptionUtil::throwOnError(BLPAPI_ERROR_ILLEGAL_STATE);
}
return static_cast<Session::SubscriptionStatus>(d_status);
}
} // close namespace blpapi
} // close namespace BloombergLP
#endif // ifdef __cplusplus
#endif // INCLUDED_BLPAPI_SESSION