1 /* 2 Copyright (C) 2008-2017, Millistream Market Data <support@millistream.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 18 19 #ifndef MDF_H 20 #define MDF_H 1 21 22 #ifndef _STDINT_H 23 # if _MSC_VER < 1600 && _MSC_VER > 0 24 # define uint32_t unsigned __int32 25 # define uint64_t unsigned __int64 26 # else 27 # include <stdint.h> 28 # endif 29 #endif 30 31 #if defined _WIN32 || defined _WIN64 32 # ifdef DLL_EXPORT 33 # define LIBSPEC __declspec(dllexport) 34 # else 35 # define LIBSPEC __declspec(dllimport) 36 # endif 37 #else 38 # define LIBSPEC 39 #endif 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 typedef enum { 46 MDF_OPT_FD, 47 MDF_OPT_ERROR, 48 MDF_OPT_RCV_BYTES, 49 MDF_OPT_SENT_BYTES, 50 MDF_OPT_DATA_CALLBACK_FUNCTION, 51 MDF_OPT_DATA_CALLBACK_USERDATA, 52 MDF_OPT_STATUS_CALLBACK_FUNCTION, 53 MDF_OPT_STATUS_CALLBACK_USERDATA, 54 MDF_OPT_CONNECT_TIMEOUT, 55 MDF_OPT_HEARTBEAT_INTERVAL, 56 MDF_OPT_HEARTBEAT_MAX_MISSED, 57 MDF_OPT_TCP_NODELAY, 58 MDF_OPT_NO_ENCRYPTION, 59 MDF_OPT_TIME_DIFFERENCE 60 } MDF_OPTION; 61 62 typedef enum { 63 MDF_ERR_NO_ERROR, 64 MDF_ERR_NO_MEM, 65 MDF_ERR_MSG_OOB, 66 MDF_ERR_TEMPLATE_OOB, 67 MDF_ERR_UNKNOWN_TEMPLATE, 68 MDF_ERR_ARGUMENT, 69 MDF_ERR_CONNECTED, 70 MDF_ERR_NOT_CONNECTED, 71 MDF_ERR_CONNECT, 72 MDF_ERR_MSG_TO_LARGE, 73 MDF_ERR_CONNECTION_IDLE, 74 MDF_ERR_DISCONNECTED, 75 MDF_ERR_AUTHFAIL 76 } MDF_ERROR; 77 78 typedef enum { 79 MDF_STATUS_LOOKUP = 0, 80 MDF_STATUS_CONNECTING, 81 MDF_STATUS_CONNECTED, 82 MDF_STATUS_DISCONNECTED, 83 MDF_STATUS_READYTOLOGON 84 } MDF_CONN_STATUS; 85 86 /* The opaque API handle */ 87 typedef struct mdf_s *mdf_t; 88 89 /* Create a new API handle, this should be the first function 90 * to call in your application. The handle is not thread-safe 91 * but different threads can access different handles simultaneously. 92 * 93 * Please also note SIGPIPE will be disabled by this function, and 94 * it will NOT be restored in mdf_destroy(). So if your application 95 * depends upon SIGPIPE you will have to re set the signal after the 96 * call to mdf_create(). */ 97 LIBSPEC mdf_t mdf_create (); 98 99 /* Destroy the API handle, open connections will be automatically closed 100 * and any remaining message chains will also be destroyed */ 101 LIBSPEC void mdf_destroy (mdf_t handle); 102 103 /* Return the message reference, class and instrument reference of the 104 * current message in the stream. Also proceeds the internal position 105 * to the next message in the stream. 106 * 107 * Returns true (1) if there was a message to return or false (0) 108 * if there is no more messages in the stream. */ 109 LIBSPEC int mdf_get_next_message (mdf_t handle, int *message_reference, int *message_class, uint64_t *instrument_reference); 110 111 /* Return the tag and value of the current field in the message and 112 * proceed the internal position to the next field in the message. 113 * 114 * Returns true (1) if there was a field to return or false (0) 115 * if there is no more fields in the message. */ 116 LIBSPEC int mdf_get_next_field (mdf_t handle, uint32_t *tag, char **value); 117 118 /* Return the value of the specified option. The data value points to 119 * will be filled in accordingly and can be relied upon only if the 120 * function returns true (1) */ 121 LIBSPEC int mdf_get_property (mdf_t handle, MDF_OPTION option, ...); 122 123 /* Sets the specified option to the specified value. value can be set 124 * to NULL in order to unset the option. */ 125 LIBSPEC int mdf_set_property (mdf_t handle, MDF_OPTION option, void *value); 126 127 /* If a callback function has been set, it will be called 128 * whenever there is messages to consume */ 129 typedef void (*mdf_data_callback)(void *userdata, mdf_t handle); 130 131 /* If a status callback function has been set, it will be called 132 * whenever the status of the connection changes */ 133 typedef void (*mdf_status_callback)(void *userdata, MDF_CONN_STATUS status, const char *host, const char *ip); 134 135 /* Connects to the first server in the servers string which can be a 136 * comma separated list of "server:port" where server can be a host name or 137 * a raw ip address (IPv6 must be enclosed in brackets "[address]", if the 138 * first server does not respond in time, the next will be tried and so on 139 * until there is no more servers in the list. 140 * 141 * Returns true (1) if a connection with a server was possible and false (0) 142 * if connection failed with every server on the list */ 143 LIBSPEC int mdf_connect (mdf_t handle, const char *servers); 144 145 /* Disconnects a connected handle. Safe to call even if the connection 146 * is already down. */ 147 LIBSPEC void mdf_disconnect (mdf_t handle); 148 149 /* Consumes any bytes from the server (if any), if a complete transaction 150 * has been received, any defined callback function will be called. 151 * timeout is the time in seconds to wait for data from the server, if 152 * zero the function will return immediately if there is no data to consume. 153 * 154 * Returns 1 if there is messages to decode and no callback function 155 * was defined, 0 if the function timeouts and -1 if there was an 156 * error. 157 */ 158 LIBSPEC int mdf_consume (mdf_t handle, const int timeout); 159 160 161 /* Message Chains - Functions to send data into the Millistream system. */ 162 163 /* Opaque handler to the message chain */ 164 typedef struct mdf_message_s *mdf_message_t; 165 166 /* Create a new message chain */ 167 LIBSPEC mdf_message_t mdf_message_create (); 168 169 /* Adds a new message to the message chain, if there is an empty message in the chain 170 * that message will be reused and no memory will be allocated. 171 * Use message_reference to define which message to send. 172 * 173 * Returns true (1) if a new message was added (or an old was reused) and 174 * false (0) if there was an error. */ 175 LIBSPEC int mdf_message_add (mdf_message_t message, const uint64_t instrument_reference, const int message_reference); 176 177 /* remove the current message from the message chain, i.e mark it to be reused. 178 * The current message pointer will change to the previous message in the chain 179 * if there is any, so repeated calls will reset the whole chain. 180 * 181 * Returns true (1) if there are more messages in the chain or false (0) 182 * if the message chain is empty. */ 183 LIBSPEC int mdf_message_del (mdf_message_t message); 184 185 /* Resets the message chain so it can be reused. The same as 186 * calling mdf_message_del() until it returns false (0). */ 187 LIBSPEC void mdf_message_reset (mdf_message_t message); 188 189 /* Serialise the message chain to a base64 encoded string and store the result in *result 190 * it's the responsibility of the caller to free *result once the value is used. 191 * 192 * Returns true (1) if the serialization was successfull or false (0) if not */ 193 LIBSPEC int mdf_message_serialize (const mdf_message_t message, char **result); 194 195 /* Deserialize the message chain from the base64 encoded string and store the result 196 * in message. 197 * 198 * Returns true(1) if the deserialization was successfull of false (0) if not */ 199 LIBSPEC int mdf_message_deserialize (const mdf_message_t message, const char * const data); 200 201 /* Destroys the message chain and frees all memory */ 202 LIBSPEC void mdf_message_destroy (mdf_message_t message); 203 204 /* Adds a space separated list of unsigned integers to the current message */ 205 LIBSPEC int mdf_message_add_list (mdf_message_t message, const uint32_t tag, const char *value); 206 207 /* Adds a numeric field to the current message */ 208 LIBSPEC int mdf_message_add_numeric (mdf_message_t message, const uint32_t tag, const char *value); 209 210 /* Adds a scaled unsigned integer numeric field to the current message */ 211 LIBSPEC int mdf_message_add_uint (mdf_message_t message, const uint32_t tag, uint64_t value, int decimals); 212 213 /* Adds a scaled signed integer numeric field to the current message */ 214 LIBSPEC int mdf_message_add_int (mdf_message_t message, const uint32_t tag, int64_t value, int decimals); 215 216 /* Adds a string field to the current message */ 217 LIBSPEC int mdf_message_add_string (mdf_message_t message, const uint32_t tag, const char * value); 218 219 /* Adds a date field to the current message */ 220 LIBSPEC int mdf_message_add_date (mdf_message_t message, const uint32_t tag, const char *value); 221 222 /* Adds a date field to the current message */ 223 LIBSPEC int mdf_message_add_date2 (mdf_message_t message, const uint32_t tag, const int year, const int mon, const int day); 224 225 /* Adds a time field to the current message */ 226 LIBSPEC int mdf_message_add_time (mdf_message_t message, const uint32_t tag, const char *value); 227 228 /* Adds a time field to the current message */ 229 LIBSPEC int mdf_message_add_time2 (mdf_message_t message, const uint32_t tag, const int hour, const int min, const int sec, int msec); 230 231 /* Adds a time field to the current message */ 232 LIBSPEC int mdf_message_add_time3 (mdf_message_t message, const uint32_t tag, const int hour, const int min, const int sec, int nsec); 233 234 /* Return the total number of messages in the chain */ 235 LIBSPEC int mdf_message_get_num (mdf_message_t message); 236 237 /* Return the number of active messages in the chain */ 238 LIBSPEC int mdf_message_get_num_active (mdf_message_t message); 239 240 /* Change insref from insref_src to insref_dst, also move the messages from message_src to message_dst if they point to different messages */ 241 LIBSPEC int mdf_message_move (const mdf_message_t message_src, const mdf_message_t message_dst, const uint64_t insref_src, const uint64_t insref_dst); 242 243 /* Send the message chain to the server */ 244 LIBSPEC int mdf_message_send (mdf_t handle, mdf_message_t message); 245 246 #ifdef __cplusplus 247 } 248 #endif 249 250 #endif 251