25 #ifndef __AMPS_MESSAGE_HPP__ 26 #define __AMPS_MESSAGE_HPP__ 27 #include "amps/util.hpp" 28 #include "amps/constants.hpp" 29 #include "amps/amps_generated.h" 35 #define AMPS_UNSET_SEQUENCE (amps_uint64_t)-1 44 #define AMPS_OPTIONS_NONE "" 45 #define AMPS_OPTIONS_LIVE "live," 46 #define AMPS_OPTIONS_OOF "oof," 47 #define AMPS_OPTIONS_REPLACE "replace," 48 #define AMPS_OPTIONS_NOEMPTIES "no_empties," 49 #define AMPS_OPTIONS_SENDKEYS "send_keys," 50 #define AMPS_OPTIONS_TIMESTAMP "timestamp," 51 #define AMPS_OPTIONS_NOSOWKEY "no_sowkey," 52 #define AMPS_OPTIONS_CANCEL "cancel," 53 #define AMPS_OPTIONS_RESUME "resume," 54 #define AMPS_OPTIONS_PAUSE "pause," 55 #define AMPS_OPTIONS_FULLY_DURABLE "fully_durable," 56 #define AMPS_OPTIONS_EXPIRE "expire," 57 #define AMPS_OPTIONS_TOPN(x) "top_n=##x," 58 #define AMPS_OPTIONS_MAXBACKLOG(x) "max_backlog=##x," 59 #define AMPS_OPTIONS_RATE(x) "rate=##x," 61 extern AMPSDLL
volatile amps_uint64_t _AMPS_NEXT_ID;
65 typedef void* amps_subscription_handle;
79 mutable bool _isIgnoreAutoAck;
80 size_t _bookmarkSeqNo;
81 amps_subscription_handle _subscription;
82 ClientImpl* _clientImpl;
96 bool ignoreAutoAck_ =
false,
size_t bookmarkSeqNo_ = 0,
97 amps_subscription_handle subscription_ = NULL,
98 ClientImpl* clientImpl_ = NULL)
99 : _message(message_), _owner(owner_), _isIgnoreAutoAck(ignoreAutoAck_)
100 , _bookmarkSeqNo(bookmarkSeqNo_)
101 , _subscription(subscription_), _clientImpl(clientImpl_)
109 : _message(NULL), _owner(true), _isIgnoreAutoAck(false), _bookmarkSeqNo(0), _subscription(NULL), _clientImpl(NULL)
117 if (_owner && _message)
126 return new MessageImpl(copy,
true, _isIgnoreAutoAck, _bookmarkSeqNo,
127 _subscription, _clientImpl);
132 if (_owner && _message)
138 _bookmarkSeqNo = rhs_._bookmarkSeqNo;
139 _subscription = rhs_._subscription;
140 _isIgnoreAutoAck = rhs_._isIgnoreAutoAck;
141 _clientImpl = rhs_._clientImpl;
144 void setClientImpl(ClientImpl* clientImpl_)
146 _clientImpl = clientImpl_;
149 ClientImpl* clientImpl(
void)
const 166 _subscription = NULL;
167 _isIgnoreAutoAck =
false;
179 if (_message == message_)
183 if (_owner && _message)
190 _subscription = NULL;
191 _isIgnoreAutoAck =
false;
200 static unsigned long newId()
202 return (
unsigned long)(AMPS_FETCH_ADD_VOLATILE(&_AMPS_NEXT_ID, 1));
205 void setBookmarkSeqNo(
size_t val_)
207 _bookmarkSeqNo = val_;
210 size_t getBookmarkSeqNo(
void)
const 212 return _bookmarkSeqNo;
215 void setSubscriptionHandle(amps_subscription_handle subscription_)
217 _subscription = subscription_;
220 amps_subscription_handle getSubscriptionHandle(
void)
const 222 return _subscription;
225 void setIgnoreAutoAck()
const 227 _isIgnoreAutoAck =
true;
230 bool getIgnoreAutoAck()
const 232 return _isIgnoreAutoAck;
242 #ifdef DOXYGEN_PREPROCESSOR 244 #define DOX_COMMENTHEAD(s) / ## ** ## s ## * ## / 245 #define DOX_GROUPNAME(s) DOX_COMMENTHEAD(@name s Functions) 246 #define DOX_OPENGROUP(s) DOX_COMMENTHEAD(@{) \ 248 #define DOX_CLOSEGROUP() DOX_COMMENTHEAD(@}) 249 #define DOX_MAKEGETCOMMENT(x) DOX_COMMENTHEAD( Retrieves the value of the x header of the Message as a Field which references the underlying buffer managed by this Message. Notice that not all headers are present on all messages returned by AMPS. See the AMPS %Command Reference for details on which fields will be present in response to a specific command. ) 250 #define DOX_MAKEGETRAWCOMMENT(x) DOX_COMMENTHEAD( Modifies the passed in arguments to reference the value of the x header of self in the underlying buffer managed by this Message. Notice that not all headers are present on all messages returned by AMPS. See the AMPS %Command Reference for details on which fields will be present in response to a specific command. ) 251 #define DOX_MAKESETCOMMENT(x) DOX_COMMENTHEAD( Sets the value of the x header for this Message. Not all headers are processed by AMPS for all commands. See the AMPS %Command Reference for which headers are used by AMPS for a specific command. ) 252 #define DOX_MAKEASSIGNCOMMENT(x) DOX_COMMENTHEAD( Assigns the value of the x header for this Message without copying. Not all headers are processed by AMPS for all commands. See the AMPS %Command Reference for which headers are used by AMPS for a specific command. ) 253 #define DOX_MAKEASSIGNOWNCOMMENT(x) DOX_COMMENTHEAD( Assigns the value of the x header for this Message without copying and makes this Message responsible for deleting the value. Not all headers are processed by AMPS for all commands. See the AMPS %Command Reference for which headers are used by AMPS for a specific command. ) 254 #define DOX_MAKENEWCOMMENT(x) DOX_COMMENTHEAD(Creates and sets a new sequential value for the x header for this Message. This function is most useful for headers such as %CommandId and %SubId.) 258 #define DOX_COMMENTHEAD(s) 259 #define DOX_GROUPNAME(s) 260 #define DOX_OPENGROUP(x) 261 #define DOX_CLOSEGROUP() 262 #define DOX_MAKEGETCOMMENT(x) 263 #define DOX_MAKEGETRAWCOMMENT(x) 264 #define DOX_MAKESETCOMMENT(x) 265 #define DOX_MAKEASSIGNCOMMENT(x) 266 #define DOX_MAKEASSIGNOWNCOMMENT(x) 267 #define DOX_MAKENEWCOMMENT(x) 275 #define AMPS_FIELD(x) \ 277 DOX_MAKEGETCOMMENT(x) \ 278 Field get##x() const {\ 282 amps_message_get_field_value(_body.get().getMessage(),\ 283 AMPS_##x, &ptr, &sz);\ 284 returnValue.assign(ptr, sz);\ 287 DOX_MAKEGETRAWCOMMENT(x) \ 288 void getRaw##x(const char** dataptr, size_t* sizeptr) const {\ 289 amps_message_get_field_value(_body.get().getMessage(),\ 290 AMPS_##x, dataptr, sizeptr);\ 293 DOX_MAKESETCOMMENT(x) \ 294 Message& set##x(const std::string& v) {\ 295 amps_message_set_field_value(_body.get().getMessage(),\ 296 AMPS_##x, v.c_str(), v.length());\ 299 DOX_MAKESETCOMMENT(x) \ 300 Message& set##x(amps_uint64_t v) {\ 302 AMPS_snprintf_amps_uint64_t(buf,22,v);\ 303 amps_message_set_field_value_nts(_body.get().getMessage(),\ 307 DOX_MAKEASSIGNCOMMENT(x) \ 308 Message& assign##x(const std::string& v) {\ 309 amps_message_assign_field_value(_body.get().getMessage(),\ 310 AMPS_##x, v.c_str(), v.length());\ 313 DOX_MAKEASSIGNCOMMENT(x) \ 314 Message& assign##x(const char* data, size_t len) {\ 315 amps_message_assign_field_value(_body.get().getMessage(),\ 316 AMPS_##x, data, len);\ 319 DOX_MAKEASSIGNOWNCOMMENT(x) \ 320 Message& assignOwnership##x(const Field& f) {\ 321 amps_message_assign_field_value_ownership(_body.get().getMessage(),\ 322 AMPS_##x, f.data(), f.len());\ 325 DOX_MAKESETCOMMENT(x) \ 326 Message& set##x(const char* str) {\ 327 amps_message_set_field_value_nts(_body.get().getMessage(),\ 331 DOX_MAKESETCOMMENT(x) \ 332 Message& set##x(const char* str,size_t len) {\ 333 amps_message_set_field_value(_body.get().getMessage(),\ 337 DOX_MAKENEWCOMMENT(x) \ 339 char buf[Message::IdentifierLength+1];\ 340 buf[Message::IdentifierLength] = 0;\ 341 AMPS_snprintf(buf, Message::IdentifierLength+1, "auto%lu" , (unsigned long)(_body.get().newId()));\ 342 amps_message_set_field_value_nts(_body.get().getMessage(),\ 348 #define AMPS_FIELD_ALIAS(x,y) \ 350 DOX_MAKEGETCOMMENT(y) \ 351 Field get##y() const {\ 355 amps_message_get_field_value(_body.get().getMessage(),\ 356 AMPS_##y, &ptr, &sz);\ 357 returnValue.assign(ptr, sz);\ 360 DOX_MAKEGETRAWCOMMENT(y) \ 361 void getRaw##y(const char** dataptr, size_t* sizeptr) const {\ 362 amps_message_get_field_value(_body.get().getMessage(),\ 363 AMPS_##y, dataptr, sizeptr);\ 366 DOX_MAKESETCOMMENT(y) \ 367 Message& set##y(const std::string& v) {\ 368 amps_message_set_field_value(_body.get().getMessage(),\ 369 AMPS_##y, v.c_str(), v.length());\ 372 DOX_MAKESETCOMMENT(y) \ 373 Message& set##y(amps_uint64_t v) {\ 375 AMPS_snprintf_amps_uint64_t(buf,22,v);\ 376 amps_message_set_field_value_nts(_body.get().getMessage(),\ 380 DOX_MAKEASSIGNCOMMENT(y) \ 381 Message& assign##y(const std::string& v) {\ 382 amps_message_assign_field_value(_body.get().getMessage(),\ 383 AMPS_##y, v.c_str(), v.length());\ 386 DOX_MAKEASSIGNCOMMENT(y) \ 387 Message& assign##y(const char* data, size_t len) {\ 388 amps_message_assign_field_value(_body.get().getMessage(),\ 389 AMPS_##y, data, len);\ 392 DOX_MAKESETCOMMENT(y) \ 393 Message& set##y(const char* str) {\ 394 amps_message_set_field_value_nts(_body.get().getMessage(),\ 398 DOX_MAKESETCOMMENT(y) \ 399 Message& set##y(const char* str,size_t len) {\ 400 amps_message_set_field_value(_body.get().getMessage(),\ 404 DOX_MAKENEWCOMMENT(y) \ 406 char buf[Message::IdentifierLength+1];\ 407 buf[Message::IdentifierLength] = 0;\ 408 AMPS_snprintf(buf, Message::IdentifierLength+1, "auto%lux" , (unsigned long)(_body.get().newId()));\ 409 amps_message_set_field_value_nts(_body.get().getMessage(),\ 413 DOX_MAKEGETCOMMENT(y) \ 414 Field get##x() const {\ 418 amps_message_get_field_value(_body.get().getMessage(),\ 419 AMPS_##y, &ptr, &sz);\ 420 returnValue.assign(ptr, sz);\ 423 DOX_MAKEGETRAWCOMMENT(y) \ 424 void getRaw##x(const char** dataptr, size_t* sizeptr) const {\ 425 amps_message_get_field_value(_body.get().getMessage(),\ 426 AMPS_##y, dataptr, sizeptr);\ 429 DOX_MAKESETCOMMENT(y) \ 430 Message& set##x(const std::string& v) {\ 431 amps_message_set_field_value(_body.get().getMessage(),\ 432 AMPS_##y, v.c_str(), v.length());\ 435 DOX_MAKESETCOMMENT(y) \ 436 Message& set##x(amps_uint64_t v) {\ 438 AMPS_snprintf_amps_uint64_t(buf,22,v);\ 439 amps_message_set_field_value_nts(_body.get().getMessage(),\ 443 DOX_MAKEASSIGNCOMMENT(y) \ 444 Message& assign##x(const std::string& v) {\ 445 amps_message_assign_field_value(_body.get().getMessage(),\ 446 AMPS_##y, v.c_str(), v.length());\ 449 DOX_MAKEASSIGNCOMMENT(y) \ 450 Message& assign##x(const char* data, size_t len) {\ 451 amps_message_assign_field_value(_body.get().getMessage(),\ 452 AMPS_##y, data, len);\ 455 DOX_MAKESETCOMMENT(y) \ 456 Message& set##x(const char* str) {\ 457 amps_message_set_field_value_nts(_body.get().getMessage(),\ 461 DOX_MAKESETCOMMENT(y) \ 462 Message& set##x(const char* str,size_t len) {\ 463 amps_message_set_field_value(_body.get().getMessage(),\ 467 DOX_MAKENEWCOMMENT(y) \ 469 char buf[Message::IdentifierLength+1];\ 470 buf[Message::IdentifierLength] = 0;\ 471 AMPS_snprintf(buf, Message::IdentifierLength+1, "auto%lux" , (unsigned long)(_body.get().newId()));\ 472 amps_message_set_field_value_nts(_body.get().getMessage(),\ 521 RefHandle<MessageImpl> _body;
530 static const unsigned int IdentifierLength = 32;
534 static const size_t BOOKMARK_NONE = AMPS_UNSET_INDEX;
569 return Message(_body.get().copy());
576 _body.get().copy(rhs_._body.get());
592 static const char* None(
void)
594 return AMPS_OPTIONS_NONE;
596 static const char* Live(
void)
598 return AMPS_OPTIONS_LIVE;
600 static const char* OOF(
void)
602 return AMPS_OPTIONS_OOF;
604 static const char* Replace(
void)
606 return AMPS_OPTIONS_REPLACE;
608 static const char* NoEmpties(
void)
610 return AMPS_OPTIONS_NOEMPTIES;
612 static const char* SendKeys(
void)
614 return AMPS_OPTIONS_SENDKEYS;
616 static const char* Timestamp(
void)
618 return AMPS_OPTIONS_TIMESTAMP;
620 static const char* NoSowKey(
void)
622 return AMPS_OPTIONS_NOSOWKEY;
624 static const char* Cancel(
void)
626 return AMPS_OPTIONS_CANCEL;
628 static const char* Resume(
void)
630 return AMPS_OPTIONS_RESUME;
632 static const char* Pause(
void)
634 return AMPS_OPTIONS_PAUSE;
636 static const char* FullyDurable(
void)
638 return AMPS_OPTIONS_FULLY_DURABLE;
640 static const char* Expire(
void)
642 return AMPS_OPTIONS_EXPIRE;
644 static std::string Conflation(
const char* conflation_)
647 AMPS_snprintf(buf,
sizeof(buf),
"conflation=%s,", conflation_);
650 static std::string ConflationKey(
const char* conflationKey_)
652 std::string option(
"conflation_key=");
653 option.append(conflationKey_).append(
",");
656 static std::string TopN(
int topN_)
659 AMPS_snprintf(buf,
sizeof(buf),
"top_n=%d,", topN_);
662 static std::string MaxBacklog(
int maxBacklog_)
665 AMPS_snprintf(buf,
sizeof(buf),
"max_backlog=%d,", maxBacklog_);
668 static std::string Rate(
const char* rate_)
671 AMPS_snprintf(buf,
sizeof(buf),
"rate=%s,", rate_);
674 static std::string RateMaxGap(
const char* rateMaxGap_)
677 AMPS_snprintf(buf,
sizeof(buf),
"rate_max_gap=%s,", rateMaxGap_);
680 static std::string SkipN(
int skipN_)
683 AMPS_snprintf(buf,
sizeof(buf),
"skip_n=%d,", skipN_);
687 static std::string Projection(
const std::string& projection_)
689 return "projection=[" + projection_ +
"],";
692 template<
class Iterator>
693 static std::string Projection(Iterator begin_, Iterator end_)
695 std::string projection =
"projection=[";
696 for (Iterator i = begin_; i != end_; ++i)
701 projection.insert(projection.length() - 1,
"]");
705 static std::string Grouping(
const std::string& grouping_)
707 return "grouping=[" + grouping_ +
"],";
710 template<
class Iterator>
711 static std::string Grouping(Iterator begin_, Iterator end_)
713 std::string grouping =
"grouping=[";
714 for (Iterator i = begin_; i != end_; ++i)
719 grouping.insert(grouping.length() - 1,
"]");
723 static std::string Select(
const std::string& select_)
725 return "select=[" + select_ +
"],";
728 template<
class Iterator>
729 static std::string Select(Iterator begin_, Iterator end_)
731 std::string select =
"select=[";
732 for (Iterator i = begin_; i != end_; ++i)
737 select.insert(select.length() - 1,
"]");
741 static std::string AckConflationInterval(
const std::string& interval_)
743 return "ack_conflation=" + interval_ +
",";
746 static std::string AckConflationInterval(
const char* interval_)
748 static const std::string start(
"ack_conflation=");
749 return start + interval_ +
",";
752 static std::string BookmarkNotFound(
const char* action_)
754 static const std::string start(
"bookmark_not_found=");
755 return start + action_ +
",";
758 static std::string BookmarkNotFoundNow()
760 return BookmarkNotFound(
"now");
763 static std::string BookmarkNotFoundEpoch()
765 return BookmarkNotFound(
"epoch");
768 static std::string BookmarkNotFoundFail()
770 return BookmarkNotFound(
"fail");
776 : _optionStr(options_)
782 int getMaxBacklog(
void)
const 786 std::string getConflation(
void)
const 790 std::string getConflationKey(
void)
const 792 return _conflationKey;
794 int getTopN(
void)
const 798 std::string getRate(
void)
const 802 std::string getRateMaxGap(
void)
const 826 _optionStr += AMPS_OPTIONS_LIVE;
835 _optionStr += AMPS_OPTIONS_OOF;
844 _optionStr += AMPS_OPTIONS_REPLACE;
852 _optionStr += AMPS_OPTIONS_NOEMPTIES;
860 _optionStr += AMPS_OPTIONS_SENDKEYS;
869 _optionStr += AMPS_OPTIONS_TIMESTAMP;
877 _optionStr += AMPS_OPTIONS_NOSOWKEY;
885 _optionStr += AMPS_OPTIONS_CANCEL;
896 _optionStr += AMPS_OPTIONS_RESUME;
911 _optionStr += AMPS_OPTIONS_PAUSE;
922 _optionStr += AMPS_OPTIONS_FULLY_DURABLE;
938 AMPS_snprintf(buf,
sizeof(buf),
"max_backlog=%d,", maxBacklog_);
940 _maxBacklog = maxBacklog_;
951 AMPS_snprintf(buf,
sizeof(buf),
"conflation=%s,", conflation_);
953 _conflation = conflation_;
968 AMPS_snprintf(buf,
sizeof(buf),
"conflation_key=%s,", conflationKey_);
970 _conflationKey = conflationKey_;
981 AMPS_snprintf(buf,
sizeof(buf),
"top_n=%d,", topN_);
995 AMPS_snprintf(buf,
sizeof(buf),
"rate=%s,", rate_);
1017 AMPS_snprintf(buf,
sizeof(buf),
"rate_max_gap=%s,", rateMaxGap_);
1019 _rateMaxGap = rateMaxGap_;
1030 AMPS_snprintf(buf,
sizeof(buf),
"skip_n=%d,", skipN_);
1041 _projection =
"projection=[" + projection_ +
"],";
1042 _optionStr += _projection;
1051 template<
class Iterator>
1054 _projection =
"projection=[";
1055 for (Iterator i = begin_; i != end_; ++i)
1060 _projection.insert(_projection.length() - 1,
"]");
1061 _optionStr += _projection;
1070 _grouping =
"grouping=[" + grouping_ +
"],";
1071 _optionStr += _grouping;
1080 template<
class Iterator>
1083 _grouping =
"grouping=[";
1084 for (Iterator i = begin_; i != end_; ++i)
1089 _grouping.insert(_grouping.length() - 1,
"]");
1090 _optionStr += _grouping;
1099 _optionStr += BookmarkNotFound(action_);
1107 _optionStr += BookmarkNotFoundNow();
1115 _optionStr += BookmarkNotFoundEpoch();
1123 _optionStr += BookmarkNotFoundFail();
1129 operator std::string()
1131 return _optionStr.substr(0, _optionStr.length() - 1);
1138 return (_optionStr.empty() ? 0 : _optionStr.length() - 1);
1147 return (_optionStr.empty() ? 0 : _optionStr.data());
1151 std::string _optionStr;
1153 std::string _conflation;
1154 std::string _conflationKey;
1157 std::string _rateMaxGap;
1159 std::string _projection;
1160 std::string _grouping;
1167 typedef enum :
unsigned 1169 None = 0, Received = 1, Parsed = 2, Processed = 4, Persisted = 8, Completed = 16, Stats = 32
1175 static inline
AckType::Type decodeSingleAckType(const
char* begin, const
char* end)
1177 switch (end - begin)
1180 return AckType::Stats;
1182 return AckType::Parsed;
1184 return AckType::Received;
1188 case 'e':
return AckType::Persisted;
1189 case 'r':
return AckType::Processed;
1190 case 'o':
return AckType::Completed;
1197 return AckType::None;
1204 unsigned result = AckType::None;
1205 const char* data = NULL;
size_t len = 0;
1207 const char* mark = data;
1208 for (
const char* end = data + len; data != end; ++data)
1212 result |= decodeSingleAckType(mark, data);
1218 result |= decodeSingleAckType(mark, data);
1227 if (ackType_ < AckTypeConstants<0>::Entries)
1230 AckTypeConstants<0>::Values[ackType_], AckTypeConstants<0>::Lengths[ackType_]);
1235 AMPS_FIELD(BatchSize)
1236 AMPS_FIELD(Bookmark)
1255 SOWAndSubscribe = 256,
1256 DeltaSubscribe = 512,
1257 SOWAndDeltaSubscribe = 1024,
1265 NoDataCommands = Publish | Unsubscribe | Heartbeat | SOWDelete | DeltaPublish
1266 | Logon | StartTimer | StopTimer | Flush
1272 const char* data = NULL;
size_t len = 0;
1276 case 1:
return Command::Publish;
1280 case 's':
return Command::SOW;
1281 case 'o':
return Command::OOF;
1282 case 'a':
return Command::Ack;
1288 case 'l':
return Command::Logon;
1289 case 'f':
return Command::Flush;
1293 return Command::Publish;
1298 case 's':
return Command::Subscribe;
1299 case 'h':
return Command::Heartbeat;
1300 case 'g':
return Command::GroupEnd;
1306 case 'o':
return Command::SOWDelete;
1307 case 't':
return Command::StopTimer;
1313 case 'g':
return Command::GroupBegin;
1314 case 'u':
return Command::Unsubscribe;
1318 return Command::DeltaPublish;
1320 return Command::DeltaSubscribe;
1322 return Command::SOWAndSubscribe;
1324 return Command::SOWAndDeltaSubscribe;
1326 return Command::Unknown;
1333 unsigned command = command_;
1340 CommandConstants<0>::Values[bits], CommandConstants<0>::Lengths[bits]);
1344 AMPS_FIELD(CommandId)
1345 AMPS_FIELD(ClientName)
1346 AMPS_FIELD(CorrelationId)
1347 AMPS_FIELD(Expiration)
1349 AMPS_FIELD(GroupSequenceNumber)
1350 AMPS_FIELD(Heartbeat)
1351 AMPS_FIELD(LeasePeriod)
1353 AMPS_FIELD(MessageLength)
1354 AMPS_FIELD(MessageType)
1358 Field getOptions()
const 1364 AMPS_Options, &ptr, &sz);
1365 if (sz && ptr[sz - 1] ==
',')
1369 returnValue.assign(ptr, sz);
1373 DOX_MAKEGETRAWCOMMENT(
Options)
1374 void getRawOptions(const
char** dataptr,
size_t* sizeptr)
const 1377 AMPS_Options, dataptr, sizeptr);
1378 if (*sizeptr && *dataptr && (*dataptr)[*sizeptr - 1] ==
',')
1388 size_t sz = v.length();
1389 if (sz && v[sz - 1] ==
',')
1394 AMPS_Options, v.c_str(), sz);
1398 DOX_MAKEASSIGNCOMMENT(
Options)
1401 size_t sz = v.length();
1402 if (sz && v[sz - 1] ==
',')
1407 AMPS_Options, v.c_str(), sz);
1411 DOX_MAKEASSIGNCOMMENT(
Options)
1412 Message& assignOptions(const
char* data,
size_t len)
1414 if (len && data[len - 1] ==
',')
1419 AMPS_Options, data, len);
1428 size_t sz = strlen(str);
1429 if (sz && str[sz - 1] ==
',')
1434 AMPS_Options, str, sz);
1439 AMPS_Options, str, 0);
1447 if (len && str[len - 1] ==
',')
1452 AMPS_Options, str, len);
1458 AMPS_FIELD(Password)
1459 AMPS_FIELD_ALIAS(QueryId, QueryID)
1461 AMPS_FIELD(RecordsInserted)
1462 AMPS_FIELD(RecordsReturned)
1463 AMPS_FIELD(RecordsUpdated)
1464 AMPS_FIELD(Sequence)
1465 AMPS_FIELD(SowDelete)
1469 AMPS_FIELD_ALIAS(SubId, SubscriptionId)
1470 AMPS_FIELD(SubscriptionIds)
1471 AMPS_FIELD(TimeoutInterval)
1472 AMPS_FIELD(Timestamp)
1479 return getTimestamp();
1488 getRawTimestamp(dataptr, sizeptr);
1492 AMPS_FIELD(TopicMatches)
1493 AMPS_FIELD(TopNRecordsReturned)
1508 returnValue.assign(ptr, sz);
1512 void getRawData(
const char** data,
size_t* sz)
const 1523 Message& assignData(
const std::string& v_)
1537 Message& assignData(
const char* data_,
size_t length_)
1550 Message& assignData(
const char* data_)
1557 return _body.get().getMessage();
1561 _body.get().replace(message, owner);
1565 _body.get().disown();
1571 bool isValid(
void)
const 1573 return _body.isValid();
1577 _body.get().reset();
1581 void setBookmarkSeqNo(
size_t val)
1583 _body.get().setBookmarkSeqNo(val);
1586 size_t getBookmarkSeqNo()
const 1588 return _body.get().getBookmarkSeqNo();
1593 _body.get().setSubscriptionHandle(val);
1598 return _body.get().getSubscriptionHandle();
1601 void ack(
const char* options_ = NULL)
const;
1603 void setClientImpl(ClientImpl* pClientImpl)
1605 _body.get().setClientImpl(pClientImpl);
1608 void setIgnoreAutoAck()
const 1610 _body.get().setIgnoreAutoAck();
1613 bool getIgnoreAutoAck()
const 1615 return _body.get().getIgnoreAutoAck();
1620 void throwFor(
const T& ,
const std::string& ackReason_)
const 1622 switch (ackReason_[0])
1625 throw AuthenticationException(
"Logon failed for user \"" +
1626 (std::string)getUserId() +
"\"");
1629 switch (ackReason_.length())
1632 throw BadFilterException(
"bad filter '" +
1633 (std::string)getFilter() +
1637 if (getSowKeys().len())
1639 throw BadSowKeyException(
"bad sow key '" +
1640 (std::string)getSowKeys() +
1645 throw BadSowKeyException(
"bad sow key '" +
1646 (std::string)getSowKey() +
1651 throw BadRegexTopicException(
"bad regex topic '" +
1652 (std::string)getTopic() +
1660 if (ackReason_.length() == 23)
1662 throw DuplicateLogonException(
"Client '" +
1663 (std::string)getClientName() +
1665 (std::string)getUserId() +
1666 "' duplicate logon attempt");
1670 if (ackReason_.length() >= 9)
1672 switch (ackReason_[8])
1675 throw InvalidBookmarkException(
"invalid bookmark '" +
1676 (std::string)getBookmark() +
1680 throw CommandException(std::string(
"invalid message type '") +
1681 (std::string)getMessageType() +
1685 if (ackReason_[9] ==
'p')
1687 throw InvalidOptionsException(
"invalid options '" +
1688 (std::string)getOptions() +
1691 else if (ackReason_[9] ==
'r')
1693 throw InvalidOrderByException(
"invalid order by '" +
1694 (std::string)getOrderBy() +
1699 throw InvalidSubIdException(
"invalid subid '" +
1700 (std::string)getSubscriptionId() +
1704 if (ackReason_.length() == 13)
1706 throw InvalidTopicException(
"invalid topic '" +
1707 (std::string)getTopic() +
1710 else if (ackReason_.length() == 23)
1712 throw InvalidTopicException(
"invalid topic or filter. Topic '" +
1713 (std::string)getTopic() +
1715 (std::string)getFilter() +
1725 if (ackReason_.length() == 14)
1727 throw LogonRequiredException(
"logon required before command");
1731 switch (ackReason_[4])
1734 throw NameInUseException(
"name in use '" +
1735 (std::string)getClientName() +
1739 throw NotEntitledException(
"User \"" +
1740 (std::string)getUserId() +
1741 "\" not entitled to topic \"" +
1742 (std::string)getTopic() +
1746 throw MissingFieldsException(
"command sent with no filter or bookmark.");
1749 throw MissingFieldsException(
"command sent with no client name.");
1752 throw MissingFieldsException(
"command sent with no topic or filter.");
1755 throw CommandException(
"operation on topic '" +
1756 (std::string)getTopic() +
1757 "' with options '" +
1758 (std::string)getOptions() +
1759 "' not supported.");
1766 switch (ackReason_.length())
1769 throw MissingFieldsException(
"orderby required");
1772 throw CommandException(
"orderby too large '" +
1773 (std::string)getOrderBy() +
1779 throw CommandException(
"projection clause too large in options '" +
1780 (std::string)getOptions() +
1784 switch (ackReason_[2])
1787 throw BadRegexTopicException(
"'regex topic not supported '" +
1788 (std::string)getTopic() +
1796 switch (ackReason_[5])
1799 throw SubidInUseException(
"subid in use '" +
1800 (std::string)getSubscriptionId() +
1804 throw CommandException(
"sow_delete command only supports one of: filter '" +
1805 (std::string)getFilter() +
1807 (std::string)getSowKeys() +
1809 (std::string)getBookmark() +
1811 (std::string)getData() +
1815 throw PublishException(
"sow store failed.");
1822 switch (ackReason_[2])
1825 throw PublishException(
"tx store failure.");
1828 throw ReplayFailedException(
"txn replay failed for '" 1829 + (std::string)getSubId()
1837 throw CommandException(
"Error from server while processing this command: '" +
1845 return lhs + std::string(rhs);
1848 inline std::basic_ostream<char>&
1849 operator<<(std::basic_ostream<char>& os,
const Message::Field& rhs)
1851 os.write(rhs.
data(), (std::streamsize)rhs.
len());
1855 AMPS::Field::operator<(
const AMPS::Field& rhs)
const 1859 return rhs.
data() != NULL;
1865 return std::lexicographical_compare(data(), data() + len(), rhs.
data(), rhs.
data() + rhs.
len());
void setFullyDurable(void)
Set the option to only provide messages that have been persisted to all replication destinations that...
Definition: Message.hpp:920
Class to hold string versions of failure reasons.
Definition: ampsplusplus.hpp:151
Message & setData(const std::string &v_)
Sets the data portion of self.
Definition: Message.hpp:1518
AMPSDLL amps_handle amps_message_create(amps_handle client)
Functions for creation and manipulation of AMPS messages.
void setRateMaxGap(const char *rateMaxGap_)
Set the option for the maximum amount of time that a bookmark replay with a specified rate will allow...
Definition: Message.hpp:1014
Command::Type getCommandEnum() const
Decode self's "command" field and return one of the values from Command.
Definition: Message.hpp:1270
AMPSDLL amps_handle amps_message_copy(amps_handle message)
Creates and returns a handle to a new AMPS message object that is a deep copy of the message passed i...
void setBookmarkNotFoundNow()
Set the option for the action to take if the requested bookmark to start the subscription is not foun...
Definition: Message.hpp:1105
void setNoEmpties(void)
Set the option to not send empty messages on a delta subscription.
Definition: Message.hpp:850
Message deepCopy(void) const
Returns a deep copy of self.
Definition: Message.hpp:567
void setOOF(void)
Set the option to receive out of focus (OOF) messages on a subscription, where applicable.
Definition: Message.hpp:833
Message encapsulates a single message sent to or received from an AMPS server, and provides methods f...
Definition: Message.hpp:519
Message & setAckTypeEnum(unsigned ackType_)
Encode self's "ack type" field from a bitmask of values from AckType.
Definition: Message.hpp:1225
void setNoSowKey(void)
Set the option to not set the SowKey header on messages.
Definition: Message.hpp:875
MessageImpl(amps_handle message_, bool owner_=false, bool ignoreAutoAck_=false, size_t bookmarkSeqNo_=0, amps_subscription_handle subscription_=NULL, ClientImpl *clientImpl_=NULL)
Constructs a messageImpl from an existing AMPS message.
Definition: Message.hpp:95
AMPSDLL void amps_message_set_field_value(amps_handle message, FieldId field, const amps_char *value, size_t length)
Sets the value of a header field in an AMPS message.
Message & setCommandEnum(Command::Type command_)
Set self's "command" field from one of the values in Command.
Definition: Message.hpp:1330
void setSendKeys(void)
Set the option to send key fields with a delta subscription.
Definition: Message.hpp:858
void * amps_handle
Opaque handle type used to refer to objects in the AMPS api.
Definition: amps.h:211
Class for constructing the options string to pass to AMPS in a Message.
Definition: Message.hpp:589
AMPSDLL void amps_message_assign_data(amps_handle message, const amps_char *value, size_t length)
Assigns the data component of an AMPS message, without copying the value.
const char * data() const
Returns the (non-null-terminated) data underlying this field.
Definition: Field.hpp:279
void setPause(void)
Set the option to pause a bookmark subscription.
Definition: Message.hpp:909
void setReplace(void)
Set the option to replace a current subscription with this one.
Definition: Message.hpp:842
Valid values for setCommandEnum() and getCommandEnum().
Definition: Message.hpp:1242
Message & setData(const char *data_)
Sets the data portion of self from a null-terminated string.
Definition: Message.hpp:1545
void setGrouping(Iterator begin_, Iterator end_)
Set the option for grouping the results of an aggregated query or subscription.
Definition: Message.hpp:1081
Message(CtorFlag)
Constructs a new empty, invalid Message.
Definition: Message.hpp:543
AMPSDLL void amps_message_set_data_nts(amps_handle message, const amps_char *value)
Sets the data component of an AMPS message.
AMPSDLL void amps_message_reset(amps_handle message)
Clears all fields and data in a message.
void setTimestamp(void)
Set the option to send a timestamp that the message was processed on a subscription or query...
Definition: Message.hpp:867
amps_handle getMessage() const
Returns the underling AMPS message object from the C layer.
Definition: Message.hpp:156
Defines the AMPS::Field class, which represents the value of a field in a message.
size_t len() const
Returns the length of the data underlying this field.
Definition: Field.hpp:286
void setResume(void)
Set the option to resume a subscription.
Definition: Message.hpp:894
AMPSDLL void amps_message_get_field_value(amps_handle message, FieldId field, const amps_char **value_ptr, size_t *length_ptr)
Retrieves the value of a header field in an AMPS message.
void setConflation(const char *conflation_)
Set the options for conflation on a subscription.
Definition: Message.hpp:948
void replace(amps_handle message_, bool owner_=false)
Causes self to refer to a new AMPS message, freeing any current message owned by self along the way...
Definition: Message.hpp:176
AMPSDLL void amps_message_get_data(amps_handle message, amps_char **value_ptr, size_t *length_ptr)
Gets the data component of an AMPS message.
AMPSDLL void amps_message_destroy(amps_handle message)
Destroys and frees the memory associated with an AMPS message object.
Options(std::string options_="")
ctor - default to None
Definition: Message.hpp:775
size_t getLength() const
Return the length of this Options object as a string.
Definition: Message.hpp:1136
AMPSDLL void amps_message_assign_field_value(amps_handle message, FieldId field, const amps_char *value, size_t length)
Assigns the value of a header field in an AMPS message, without copying the value.
void setRate(const char *rate_)
Set the option for the maximum rate at which messages are provided to the subscription.
Definition: Message.hpp:992
Valid values for the setAckTypeEnum() and getAckTypeEnum() methods.
Definition: Message.hpp:1165
void setGrouping(const std::string &grouping_)
Set the option for grouping the results of an aggregated query or subscription.
Definition: Message.hpp:1068
void setBookmarkNotFoundEpoch()
Set the option for the action to take if the requested bookmark to start the subscription is not foun...
Definition: Message.hpp:1113
void setTopN(int topN_)
Set the top N option, which specifies the maximum number of messages to return for this command...
Definition: Message.hpp:978
AMPSDLL void amps_message_set_data(amps_handle message, const amps_char *value, size_t length)
Sets the data component of an AMPS message.
void setMaxBacklog(int maxBacklog_)
Set the option for maximum backlog this subscription is willing to accept.
Definition: Message.hpp:935
void setBookmarkNotFoundFail()
Set the option for the action to take if the requested bookmark to start the subscription is not foun...
Definition: Message.hpp:1121
void getRawTransmissionTime(const char **dataptr, size_t *sizeptr) const
Definition: Message.hpp:1486
void deepCopy(const Message &rhs_)
Makes self a deep copy of rhs_.
Definition: Message.hpp:574
MessageImpl()
Constructs a MessageImpl with a new, empty AMPS message.
Definition: Message.hpp:108
Field represents the value of a single field in a Message.
Definition: Field.hpp:87
void setBookmarkNotFound(const char *action_)
Set the option for the action to take if the requested bookmark to start the subscription is ot found...
Definition: Message.hpp:1097
void setConflationKey(const char *conflationKey_)
Set the options for the conflation key, the identifiers for the field or fields used by AMPS to deter...
Definition: Message.hpp:965
void setProjection(const std::string &projection_)
Set the option for projecting the results of an aggregated query or subscription. ...
Definition: Message.hpp:1039
void setSkipN(int skipN_)
Set the option for skip N, the number of messages in the result set to skip before returning messages...
Definition: Message.hpp:1027
Message(amps_handle message_, bool owner_=false)
Constructs a new Message to wrap message.
Definition: Message.hpp:553
CtorFlag
A flag to indicate not to create a body.
Definition: Message.hpp:539
void setNone(void)
Clear any previously set options and set the options to an empty string (AMPS_OPTIONS_NONE).
Definition: Message.hpp:810
Implementation class for a Message.
Definition: Message.hpp:73
void setProjection(Iterator begin_, Iterator end_)
Set the option for projecting the results of an aggregated query or subscription. ...
Definition: Message.hpp:1052
unsigned getAckTypeEnum() const
Decode self's "ack type" field and return the corresponding bitmask of values from AckType...
Definition: Message.hpp:1202
Message & setData(const char *data_, size_t length_)
Sets the data portion of self from a char array.
Definition: Message.hpp:1532
Definition: AMPSException.hpp:32
void setCancel(void)
Set the cancel option, used on a sow_delete command to return a message to the queue.
Definition: Message.hpp:883
const char * getStr() const
Return this Options object as a non-NULL-terminated string.
Definition: Message.hpp:1145
Message()
Construct a new, empty Message.
Definition: Message.hpp:561
void setLive(void)
Set the live option for a bookmark subscription, which requests that the subscription receives messag...
Definition: Message.hpp:824