├── CMakeLists.txt ├── ReadMe.md ├── inc ├── Message.h ├── Subscription.h ├── SubscriptionMeta.h ├── Topic.h ├── TopicMeta.h ├── account.h ├── cmq_client.h ├── cmq_common.h ├── cmq_exception.h ├── cmq_http.h ├── cmq_tool.h ├── json │ ├── json-forwards.h │ └── json.h └── queue.h ├── sample ├── CMakeLists.txt ├── cmq_sample_queue.cpp └── cmq_sample_topic.cpp └── src ├── CMakeLists.txt ├── Message.cpp ├── Subscription.cpp ├── SubscriptionMeta.cpp ├── Topic.cpp ├── TopicMeta.cpp ├── account.cpp ├── cmq_client.cpp ├── cmq_exception.cpp ├── cmq_http.cpp ├── cmq_tool.cpp ├── jsoncpp.cpp └── queue.cpp /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(cmq) 2 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 3 | ADD_SUBDIRECTORY(src) 4 | ADD_SUBDIRECTORY(sample) 5 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # qcloud-cmq 2 | 3 | 腾讯云 CMQ 消息队列 c++ sdk, http 同步模式 4 | 5 | ## installation 6 | 7 | ``` 8 | git clone https://github.com/tencentyun/cmq-cpp-sdk 9 | ``` 10 | 11 | ## dependency 12 | 13 | - [libcurl](https://curl.haxx.se/libcurl/) 14 | 15 | you can get libcurl: 16 | 17 | ``` 18 | ubuntu 19 | apt-get install libcurl4-openssl-dev 20 | centos 21 | yum install libcurl-devel 22 | ``` 23 | - [openssl](https://www.openssl.org/) 24 | 25 | you can get openssl: 26 | ``` 27 | ubuntu 28 | apt-get install libssl-dev 29 | centos 30 | yum install openssl 31 | ``` 32 | 33 | ## build tool 34 | - [cmake](https://cmake.org/) 35 | 36 | you can get cmake : 37 | ``` 38 | ubuntu 39 | apt-get install cmake 40 | centos 41 | yum install cmake 42 | ``` 43 | 44 | ## Compile 45 | 46 | ``` 47 | cmake . 48 | make 49 | 50 | ``` 51 | -------------------------------------------------------------------------------- /inc/Message.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tencentyun/cmq-cpp-sdk/14c3e2fa849be32c0e6ddbc926f8b35f01aef4a5/inc/Message.h -------------------------------------------------------------------------------- /inc/Subscription.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_SUBSCRIPTION_H_ 2 | #define CMQ_SDK_INCLUDE_SUBSCRIPTION_H_ 3 | 4 | #include 5 | #include"cmq_client.h" 6 | #include"SubscriptionMeta.h" 7 | 8 | using std::string; 9 | 10 | namespace cmq 11 | { 12 | class Subscription 13 | { 14 | public: 15 | 16 | Subscription(const string & ,const string & ,const CMQClient &); 17 | ~Subscription(); 18 | void getSubscriptionAttributes(SubscriptionMeta & meta); 19 | void setSubscriptionAttributes(const SubscriptionMeta meta); 20 | void clearFilterTags(); 21 | protected: 22 | string m_topicName; 23 | string m_subscriptionName; 24 | CMQClient m_client; 25 | 26 | 27 | 28 | }; 29 | } 30 | #endif // 31 | 32 | 33 | -------------------------------------------------------------------------------- /inc/SubscriptionMeta.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_SUBSCRIPTIONMETA_H_ 2 | #define CMQ_SDK_INCLUDE_SUBSCRIPTIONMETA_H_ 3 | 4 | 5 | #include 6 | #include 7 | 8 | using std::string; 9 | using std::vector; 10 | namespace cmq 11 | { 12 | class SubscriptionMeta 13 | { 14 | public: 15 | SubscriptionMeta(); 16 | ~SubscriptionMeta(); 17 | string TopicOwner; 18 | string endpoint; 19 | string protocol; 20 | string notifyStrategy; 21 | string notifyContentFormat; 22 | vector filterTag; 23 | int CreateTime; 24 | int LastModifyTime; 25 | int msgCount; 26 | vector bindingKey; 27 | 28 | }; 29 | } 30 | #endif // !CMQ_SDK_INCLUDE_SUBSCRIPTIONMETA_H_ 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /inc/Topic.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_SRC_TOPIC_H__ 2 | #define CMQ_SDK_SRC_TOPIC_H__ 3 | 4 | #include 5 | #include 6 | #include"cmq_client.h" 7 | #include"TopicMeta.h" 8 | #include"Message.h" 9 | #include"Subscription.h" 10 | 11 | using std::string; 12 | using std::vector; 13 | using cmq::CMQClient; 14 | using cmq::TopicMeta; 15 | using cmq::Message; 16 | 17 | 18 | namespace cmq 19 | { 20 | class Topic 21 | { 22 | protected: 23 | string topicName; 24 | CMQClient client; 25 | public: 26 | 27 | Topic(const string &, const CMQClient &); 28 | ~Topic(); 29 | 30 | 31 | void SetTopicAttributes(const unsigned int maxMsgSize) ; 32 | void GetTopicAttributes(TopicMeta &); 33 | 34 | void PublishMessage(const string & msgBody , string & msgId ,const string & routingKey=""); 35 | void PublishMessage(const string & msgBody , string & msgId, const vector & vmsgTag, const string & routingKey =""); 36 | 37 | void BatchPublishMessage(const vector< string > &, vector< string > & vmsgId, const vector< string > & vmsgTag , const string & routingKey = ""); 38 | void BatchPublishMessage(const vector< string > &, vector< string > & vmsgId, const string & routingKey =""); 39 | 40 | /** 41 | * @brief 列出Topic的订阅列表 42 | * @param topicName 主题名称 43 | * @param totalCount 用户帐号下的订阅数 44 | * @param searchWord 查询关键字 45 | * @param offset 46 | * @param limit 47 | * #param vSubscriptionList 返回订阅列表 48 | **/ void listSubscription(int & totalCount,vector< vector > & , const string & searchWord="", const int offset = -1 , const int limit = -1 ); 49 | }; 50 | } 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /inc/TopicMeta.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_SRC_TOPICMETA__ 2 | #define CMQ_SDK_SRC_TOPICMETA__ 3 | namespace cmq 4 | { 5 | class TopicMeta 6 | { 7 | 8 | public: 9 | unsigned int m_msgCount; 10 | unsigned int m_maxMsgSize; 11 | unsigned int m_msgRetentionSeconds; 12 | unsigned int m_createTime; 13 | unsigned int m_lastModifyTime; 14 | unsigned int m_loggingEnabled; 15 | unsigned int m_filterType; 16 | 17 | public: 18 | TopicMeta(); 19 | 20 | ~TopicMeta(); 21 | 22 | }; 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /inc/account.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_ACCOUNT_H__ 2 | #define CMQ_SDK_INCLUDE_ACCOUNT_H__ 3 | 4 | 5 | 6 | #include "stdint.h" 7 | #include 8 | #include 9 | 10 | #include "cmq_client.h" 11 | #include "queue.h" 12 | #include "Topic.h" 13 | #include "Subscription.h" 14 | 15 | using std::string; 16 | using std::pair; 17 | 18 | namespace cmq 19 | { 20 | 21 | 22 | /*Account类对象非线程安全,如果多线程使用,需要每个线程单独初始化Account类对象*/ 23 | class Account 24 | { 25 | public: 26 | /** 27 | * @brief 28 | * @param secretId 从腾讯云官网查看云api的密钥ID 29 | * @param secretKey 从腾讯云官网查看云api的密钥 30 | * @param endpoint 消息服务api地址,例如:https://cmq-queue-gz.api.qcloud.com 31 | * @param method 请求方法,可使用GET或POST方法 32 | **/ 33 | Account(const string &endpoint,const string &secretId, const string &secretKey, const string &method="POST"); 34 | Account(const string &endpoint,const string &secretId, const string &secretKey, const string &path, const string &method); 35 | 36 | /** 37 | * @setSignMethod set the sign method and now we support sha1 and sha256 38 | * @ signMethod string only set "sha1" or "sha256" 39 | */ 40 | void setSignMethod(const string & signMethod = "sha1"){this->client.setSignMethod(signMethod);} 41 | /** 42 | * @brief 创建队列 43 | * @param queueName 队列名字 44 | * @param meta 队列属性参数 45 | **/ 46 | void createQueue(const string &queueName,const QueueMeta &meta); 47 | /** 48 | * @brief 删除队列 49 | * @param queueName 队列名字 50 | **/ 51 | void deleteQueue(const string &queueName); 52 | /** 53 | * @brief 列出Account的队列列表 54 | * @param totalCount 返回用户帐号下总队列数 55 | * @param vtQueue 返回队列列表 56 | * @param searchWord 查询关键字 57 | * @param offset 58 | * @param limit 59 | **/ 60 | void listQueue(int &totalCount,vector &vtQueue, const string &searchWord="", int offset=-1, int limit=-1); 61 | /** 62 | * @brief 获取Account的一个Queue对象 63 | * @param queueName Queue名称 64 | * @return 返回一个Queue对象 65 | **/ 66 | Queue getQueue(const string &queueName); 67 | 68 | /** 69 | * @brief 获取Account的一个Topic对象 70 | * @param topicName Topic名称 71 | * @return 返回一个Topic对象 72 | **/ 73 | Topic getTopic(const string &topicName); 74 | /** 75 | * @brief 创建主题 76 | * @param topicName 主题名字 77 | * @param maxMsgSize 队列消息最大长度 78 | * @param filterType 过滤选项, 0 不过滤, 1 标签过滤,2 routing key 过滤 79 | **/ 80 | void createTopic(const string & topicName, const int maxMsgSize = 654536 , const int filterType = 1 , const int LoggingEnabled = 0); 81 | /** 82 | * @brief 删除主题 83 | * @param topicName 主题名字 84 | **/ 85 | void deleteTopic(const string & topicName); 86 | /** 87 | * @brief 列出Account的主题列表 88 | * @param totalCount 返回用户帐号下的主题数 89 | * @param vtQueue 返回主题列表 90 | * @param searchWord 查询关键字 91 | * @param offset 92 | * @param limit 93 | **/ 94 | void listTopic(int & totalCount , vector< pair > &, const string & searchWord="", 95 | const int offset=-1, const int limit= -1); 96 | 97 | /** 98 | * @brief 创建订阅 99 | * @param topicName 主题名字 100 | * @param subscriptionName 订阅名称 101 | * @param endpoint 订阅终端 102 | * @param protocol 订阅协议 103 | * @param filterTag 过滤标签 104 | * @param bindingKey 105 | * @param notifyStrategy 推送失败重试策略 106 | * @param notifyContentFormat 推送格式 107 | **/ 108 | void createSubscribe(const string & topicName, const string & subscriptionName, const string & endpoint, 109 | const string & protocol, const vector & bindingKey , const vector & vFilterTag, 110 | const string & notifyStrategy="BACKOFF_RETRY", const string & notifyContentFormat="JSON"); 111 | 112 | /** 113 | * @brief 删除订阅 114 | * @param subscriptionName 订阅名称 115 | **/ 116 | void deleteSubscribe(const string & topicName, const string & subscriptionName); 117 | 118 | 119 | /** 120 | * @brief 获取Account的一个订阅对象 121 | * @param topicName 主题 122 | * @param subscriptionName 订阅名称 123 | * @return 返回一个Subscription对象 124 | **/ 125 | Subscription getSubscription(const string & , const string & ); 126 | 127 | 128 | protected: 129 | CMQClient client; 130 | }; 131 | 132 | 133 | 134 | 135 | 136 | } 137 | 138 | #endif 139 | 140 | -------------------------------------------------------------------------------- /inc/cmq_client.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_CLIENT_H__ 2 | #define CMQ_SDK_INCLUDE_CLIENT_H__ 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "cmq_exception.h" 12 | #include "cmq_http.h" 13 | 14 | using std::string; 15 | using std::map; 16 | 17 | namespace cmq 18 | { 19 | 20 | class CMQClient 21 | { 22 | protected: 23 | string endpoint; 24 | string path; 25 | string secretId; 26 | string secretKey; 27 | string method; 28 | string signMethod; 29 | 30 | CMQHttp http; 31 | 32 | public: 33 | CMQClient(); 34 | 35 | CMQClient(const string &endpoint, const string &path, const string &secretId, const string &secretKey, const string &method="POST"); 36 | 37 | CMQClient& operator=(const CMQClient &r) 38 | { 39 | if(this != &r) 40 | { 41 | this->endpoint = r.endpoint; 42 | this->path = r.path; 43 | this->secretId = r.secretId; 44 | this->secretKey = r.secretKey; 45 | this->method = r.method; 46 | this->signMethod =r.signMethod; 47 | } 48 | return *this; 49 | } 50 | 51 | CMQClient(const CMQClient &r) 52 | { 53 | this->endpoint = r.endpoint; 54 | this->path = r.path; 55 | this->secretId = r.secretId; 56 | this->secretKey = r.secretKey; 57 | this->method = r.method; 58 | this->signMethod =r.signMethod; 59 | } 60 | 61 | void setSignMethod (string method) 62 | { 63 | if (method != "sha1" && method != "sha256") 64 | { 65 | throw CMQClientException("Only support sha1 or sha256 now"); 66 | } 67 | else 68 | { 69 | this->signMethod = method ; 70 | } 71 | } 72 | void setEndpoint(string endpoint) 73 | { 74 | this->endpoint = endpoint; 75 | } 76 | void setPath(string path) 77 | { 78 | this->path = path; 79 | } 80 | 81 | void setSecretId(string secretId) 82 | { 83 | this->secretId = secretId; 84 | } 85 | 86 | void setSecretKey(string secretKey) 87 | { 88 | this->secretKey = secretKey; 89 | } 90 | 91 | void setMethod(string method) 92 | { 93 | this->method = method; 94 | } 95 | 96 | string call(const string &action, map ¶m); 97 | }; 98 | 99 | } 100 | 101 | #endif 102 | 103 | -------------------------------------------------------------------------------- /inc/cmq_common.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CMQ_SDK_INCLUDE_COMMON_H 3 | #define CMQ_SDK_INCLUDE_COMMON_H 4 | 5 | 6 | #include"account.h" 7 | #include"cmq_client.h" 8 | #include"cmq_exception.h" 9 | #include"cmq_http.h" 10 | #include"cmq_tool.h" 11 | #include"Message.h" 12 | #include"queue.h" 13 | #include"Subscription.h" 14 | #include"SubscriptionMeta.h" 15 | #include"Topic.h" 16 | #include"TopicMeta.h" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /inc/cmq_exception.h: -------------------------------------------------------------------------------- 1 | #ifndef __CMQ_SDK_INCLUDE_EXCEPTION_H__ 2 | #define __CMQ_SDK_INCLUDE_EXCEPTION_H__ 3 | 4 | #include 5 | #include 6 | 7 | 8 | using std::exception; 9 | using std::string; 10 | 11 | namespace cmq 12 | { 13 | 14 | class CMQClientException : public exception 15 | { 16 | public: 17 | CMQClientException(const string &msg) throw() 18 | { 19 | this->msg = msg; 20 | } 21 | 22 | virtual ~CMQClientException() throw(){} 23 | 24 | virtual const char* what() const throw(); 25 | 26 | string msg; 27 | }; 28 | 29 | class CMQServerNetworkException : public exception 30 | { 31 | public: 32 | CMQServerNetworkException(int status) throw() 33 | { 34 | this->status = status; 35 | } 36 | 37 | virtual ~CMQServerNetworkException() throw(){} 38 | 39 | int getStatus() const 40 | { 41 | return this->status; 42 | } 43 | 44 | //http status 45 | int status; 46 | }; 47 | 48 | class CMQServerException : public exception 49 | { 50 | public: 51 | CMQServerException(int code, const string &message, const string &requestId) throw() 52 | { 53 | this->code = code; 54 | this->message = message; 55 | this->requestId = requestId; 56 | } 57 | 58 | ~CMQServerException() throw(){} 59 | 60 | string getRequestId() const 61 | { 62 | return this->requestId; 63 | } 64 | int getCode() const 65 | { 66 | return this->code; 67 | } 68 | string getMessage() const 69 | { 70 | return this->message; 71 | } 72 | 73 | /** 74 | *常见错误类型: 75 | *: 4000 参数不合法 76 | *: 4100 鉴权失败:密钥不存在/失效 77 | *: 4300 账户欠费了 78 | *: 4400 消息大小超过队列属性设置的最大值 79 | *: 4410 已达到队列最大的消息堆积数 80 | *: 4420 qps限流 81 | *: 4430 删除消息的句柄不合法或者过期了 82 | *: 4440 队列不存在 83 | *: 4450 队列个数超过限制 84 | *: 4460 队列已经存在 85 | *: 6000 服务器内部错误 86 | *: 6010 批量删除消息失败(具体原因还要看每个消息删除失败的错误码) 87 | *: 7000 空消息,即队列当前没有可用消息 88 | **/ 89 | int code; 90 | //返回的详细错误信息 91 | string message; 92 | //服务器生成的请求Id,便于追踪问题 93 | string requestId; 94 | }; 95 | 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /inc/cmq_http.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_HTTP_H__ 2 | #define CMQ_SDK_INCLUDE_HTTP_H__ 3 | 4 | #include 5 | #include 6 | 7 | using std::string; 8 | 9 | namespace cmq 10 | { 11 | 12 | class CMQHttp 13 | { 14 | public: 15 | CMQHttp(int timout=10/*sec*/,bool isKeepAlive=true); 16 | ~CMQHttp(); 17 | 18 | void request(const string &method, const string &url, const string &req, string &rsp, const int timeout = 0); 19 | 20 | protected: 21 | CURL *curl; 22 | int timeout; 23 | bool isKeepAlive; 24 | }; 25 | 26 | } 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /inc/cmq_tool.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_TOOL_H__ 2 | #define CMQ_SDK_INCLUDE_TOOL_H__ 3 | 4 | #include 5 | 6 | using std::string; 7 | 8 | namespace cmq 9 | { 10 | typedef unsigned char byte; 11 | 12 | string int2str(int n); 13 | 14 | string url_encode(const string &src); 15 | 16 | string base64_encode(const byte *src, int length); 17 | 18 | 19 | string sign(const string &src, const string &key,const string & method ="sha1"); 20 | 21 | 22 | } 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /inc/json/json-forwards.h: -------------------------------------------------------------------------------- 1 | /// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/). 2 | /// It is intended to be used with #include "json/json-forwards.h" 3 | /// This header provides forward declaration for all JsonCpp types. 4 | 5 | // ////////////////////////////////////////////////////////////////////// 6 | // Beginning of content of file: LICENSE 7 | // ////////////////////////////////////////////////////////////////////// 8 | 9 | /* 10 | The JsonCpp library's source code, including accompanying documentation, 11 | tests and demonstration applications, are licensed under the following 12 | conditions... 13 | 14 | The author (Baptiste Lepilleur) explicitly disclaims copyright in all 15 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 16 | this software is released into the Public Domain. 17 | 18 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 19 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is 20 | released under the terms of the MIT License (see below). 21 | 22 | In jurisdictions which recognize Public Domain property, the user of this 23 | software may choose to accept it either as 1) Public Domain, 2) under the 24 | conditions of the MIT License (see below), or 3) under the terms of dual 25 | Public Domain/MIT License conditions described here, as they choose. 26 | 27 | The MIT License is about as close to Public Domain as a license can get, and is 28 | described in clear, concise terms at: 29 | 30 | http://en.wikipedia.org/wiki/MIT_License 31 | 32 | The full text of the MIT License follows: 33 | 34 | ======================================================================== 35 | Copyright (c) 2007-2010 Baptiste Lepilleur 36 | 37 | Permission is hereby granted, free of charge, to any person 38 | obtaining a copy of this software and associated documentation 39 | files (the "Software"), to deal in the Software without 40 | restriction, including without limitation the rights to use, copy, 41 | modify, merge, publish, distribute, sublicense, and/or sell copies 42 | of the Software, and to permit persons to whom the Software is 43 | furnished to do so, subject to the following conditions: 44 | 45 | The above copyright notice and this permission notice shall be 46 | included in all copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 49 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 50 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 51 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 52 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 53 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 54 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 55 | SOFTWARE. 56 | ======================================================================== 57 | (END LICENSE TEXT) 58 | 59 | The MIT license is compatible with both the GPL and commercial 60 | software, affording one all of the rights of Public Domain with the 61 | minor nuisance of being required to keep the above copyright notice 62 | and license text in the source code. Note also that by accepting the 63 | Public Domain "license" you can re-license your copy using whatever 64 | license you like. 65 | 66 | */ 67 | 68 | // ////////////////////////////////////////////////////////////////////// 69 | // End of content of file: LICENSE 70 | // ////////////////////////////////////////////////////////////////////// 71 | 72 | 73 | 74 | 75 | 76 | #ifndef JSON_FORWARD_AMALGATED_H_INCLUDED 77 | # define JSON_FORWARD_AMALGATED_H_INCLUDED 78 | /// If defined, indicates that the source file is amalgated 79 | /// to prevent private header inclusion. 80 | #define JSON_IS_AMALGAMATION 81 | 82 | // ////////////////////////////////////////////////////////////////////// 83 | // Beginning of content of file: include/json/config.h 84 | // ////////////////////////////////////////////////////////////////////// 85 | 86 | // Copyright 2007-2010 Baptiste Lepilleur 87 | // Distributed under MIT license, or public domain if desired and 88 | // recognized in your jurisdiction. 89 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 90 | 91 | #ifndef JSON_CONFIG_H_INCLUDED 92 | #define JSON_CONFIG_H_INCLUDED 93 | #include 94 | #include //typdef String 95 | 96 | /// If defined, indicates that json library is embedded in CppTL library. 97 | //# define JSON_IN_CPPTL 1 98 | 99 | /// If defined, indicates that json may leverage CppTL library 100 | //# define JSON_USE_CPPTL 1 101 | /// If defined, indicates that cpptl vector based map should be used instead of 102 | /// std::map 103 | /// as Value container. 104 | //# define JSON_USE_CPPTL_SMALLMAP 1 105 | 106 | // If non-zero, the library uses exceptions to report bad input instead of C 107 | // assertion macros. The default is to use exceptions. 108 | #ifndef JSON_USE_EXCEPTION 109 | #define JSON_USE_EXCEPTION 1 110 | #endif 111 | 112 | /// If defined, indicates that the source file is amalgated 113 | /// to prevent private header inclusion. 114 | /// Remarks: it is automatically defined in the generated amalgated header. 115 | // #define JSON_IS_AMALGAMATION 116 | 117 | #ifdef JSON_IN_CPPTL 118 | #include 119 | #ifndef JSON_USE_CPPTL 120 | #define JSON_USE_CPPTL 1 121 | #endif 122 | #endif 123 | 124 | #ifdef JSON_IN_CPPTL 125 | #define JSON_API CPPTL_API 126 | #elif defined(JSON_DLL_BUILD) 127 | #if defined(_MSC_VER) || defined(__MINGW32__) 128 | #define JSON_API __declspec(dllexport) 129 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 130 | #endif // if defined(_MSC_VER) 131 | #elif defined(JSON_DLL) 132 | #if defined(_MSC_VER) || defined(__MINGW32__) 133 | #define JSON_API __declspec(dllimport) 134 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 135 | #endif // if defined(_MSC_VER) 136 | #endif // ifdef JSON_IN_CPPTL 137 | #if !defined(JSON_API) 138 | #define JSON_API 139 | #endif 140 | 141 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 142 | // integer 143 | // Storages, and 64 bits integer support is disabled. 144 | // #define JSON_NO_INT64 1 145 | 146 | #if defined(_MSC_VER) // MSVC 147 | # if _MSC_VER <= 1200 // MSVC 6 148 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 149 | // (no conversion from unsigned __int64). 150 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 151 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 152 | // characters in the debug information) 153 | // All projects I've ever seen with VS6 were using this globally (not bothering 154 | // with pragma push/pop). 155 | # pragma warning(disable : 4786) 156 | # endif // MSVC 6 157 | 158 | # if _MSC_VER >= 1500 // MSVC 2008 159 | /// Indicates that the following function is deprecated. 160 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 161 | # endif 162 | 163 | #endif // defined(_MSC_VER) 164 | 165 | // In c++11 the override keyword allows you to explicity define that a function 166 | // is intended to override the base-class version. This makes the code more 167 | // managable and fixes a set of common hard-to-find bugs. 168 | #if __cplusplus >= 201103L 169 | # define JSONCPP_OVERRIDE override 170 | #elif defined(_MSC_VER) && _MSC_VER > 1600 171 | # define JSONCPP_OVERRIDE override 172 | #else 173 | # define JSONCPP_OVERRIDE 174 | #endif 175 | 176 | #ifndef JSON_HAS_RVALUE_REFERENCES 177 | 178 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 179 | #define JSON_HAS_RVALUE_REFERENCES 1 180 | #endif // MSVC >= 2010 181 | 182 | #ifdef __clang__ 183 | #if __has_feature(cxx_rvalue_references) 184 | #define JSON_HAS_RVALUE_REFERENCES 1 185 | #endif // has_feature 186 | 187 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 188 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) 189 | #define JSON_HAS_RVALUE_REFERENCES 1 190 | #endif // GXX_EXPERIMENTAL 191 | 192 | #endif // __clang__ || __GNUC__ 193 | 194 | #endif // not defined JSON_HAS_RVALUE_REFERENCES 195 | 196 | #ifndef JSON_HAS_RVALUE_REFERENCES 197 | #define JSON_HAS_RVALUE_REFERENCES 0 198 | #endif 199 | 200 | #ifdef __clang__ 201 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 202 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 203 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 204 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 205 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 206 | # endif // GNUC version 207 | #endif // __clang__ || __GNUC__ 208 | 209 | #if !defined(JSONCPP_DEPRECATED) 210 | #define JSONCPP_DEPRECATED(message) 211 | #endif // if !defined(JSONCPP_DEPRECATED) 212 | 213 | #if __GNUC__ >= 6 214 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 215 | #endif 216 | 217 | #if !defined(JSON_IS_AMALGAMATION) 218 | 219 | # include "version.h" 220 | 221 | # if JSONCPP_USING_SECURE_MEMORY 222 | # include "allocator.h" //typedef Allocator 223 | # endif 224 | 225 | #endif // if !defined(JSON_IS_AMALGAMATION) 226 | 227 | namespace Json { 228 | typedef int Int; 229 | typedef unsigned int UInt; 230 | #if defined(JSON_NO_INT64) 231 | typedef int LargestInt; 232 | typedef unsigned int LargestUInt; 233 | #undef JSON_HAS_INT64 234 | #else // if defined(JSON_NO_INT64) 235 | // For Microsoft Visual use specific types as long long is not supported 236 | #if defined(_MSC_VER) // Microsoft Visual Studio 237 | typedef __int64 Int64; 238 | typedef unsigned __int64 UInt64; 239 | #else // if defined(_MSC_VER) // Other platforms, use long long 240 | typedef long long int Int64; 241 | typedef unsigned long long int UInt64; 242 | #endif // if defined(_MSC_VER) 243 | typedef Int64 LargestInt; 244 | typedef UInt64 LargestUInt; 245 | #define JSON_HAS_INT64 246 | #endif // if defined(JSON_NO_INT64) 247 | #if JSONCPP_USING_SECURE_MEMORY 248 | #define JSONCPP_STRING std::basic_string, Json::SecureAllocator > 249 | #define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > 250 | #define JSONCPP_OSTREAM std::basic_ostream> 251 | #define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > 252 | #define JSONCPP_ISTREAM std::istream 253 | #else 254 | #define JSONCPP_STRING std::string 255 | #define JSONCPP_OSTRINGSTREAM std::ostringstream 256 | #define JSONCPP_OSTREAM std::ostream 257 | #define JSONCPP_ISTRINGSTREAM std::istringstream 258 | #define JSONCPP_ISTREAM std::istream 259 | #endif // if JSONCPP_USING_SECURE_MEMORY 260 | } // end namespace Json 261 | 262 | #endif // JSON_CONFIG_H_INCLUDED 263 | 264 | // ////////////////////////////////////////////////////////////////////// 265 | // End of content of file: include/json/config.h 266 | // ////////////////////////////////////////////////////////////////////// 267 | 268 | 269 | 270 | 271 | 272 | 273 | // ////////////////////////////////////////////////////////////////////// 274 | // Beginning of content of file: include/json/forwards.h 275 | // ////////////////////////////////////////////////////////////////////// 276 | 277 | // Copyright 2007-2010 Baptiste Lepilleur 278 | // Distributed under MIT license, or public domain if desired and 279 | // recognized in your jurisdiction. 280 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 281 | 282 | #ifndef JSON_FORWARDS_H_INCLUDED 283 | #define JSON_FORWARDS_H_INCLUDED 284 | 285 | #if !defined(JSON_IS_AMALGAMATION) 286 | #include "config.h" 287 | #endif // if !defined(JSON_IS_AMALGAMATION) 288 | 289 | namespace Json { 290 | 291 | // writer.h 292 | class FastWriter; 293 | class StyledWriter; 294 | 295 | // reader.h 296 | class Reader; 297 | 298 | // features.h 299 | class Features; 300 | 301 | // value.h 302 | typedef unsigned int ArrayIndex; 303 | class StaticString; 304 | class Path; 305 | class PathArgument; 306 | class Value; 307 | class ValueIteratorBase; 308 | class ValueIterator; 309 | class ValueConstIterator; 310 | 311 | } // namespace Json 312 | 313 | #endif // JSON_FORWARDS_H_INCLUDED 314 | 315 | // ////////////////////////////////////////////////////////////////////// 316 | // End of content of file: include/json/forwards.h 317 | // ////////////////////////////////////////////////////////////////////// 318 | 319 | 320 | 321 | 322 | 323 | #endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED 324 | -------------------------------------------------------------------------------- /inc/json/json.h: -------------------------------------------------------------------------------- 1 | /// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/). 2 | /// It is intended to be used with #include "json/json.h" 3 | 4 | // ////////////////////////////////////////////////////////////////////// 5 | // Beginning of content of file: LICENSE 6 | // ////////////////////////////////////////////////////////////////////// 7 | 8 | /* 9 | The JsonCpp library's source code, including accompanying documentation, 10 | tests and demonstration applications, are licensed under the following 11 | conditions... 12 | 13 | The author (Baptiste Lepilleur) explicitly disclaims copyright in all 14 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 15 | this software is released into the Public Domain. 16 | 17 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 18 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is 19 | released under the terms of the MIT License (see below). 20 | 21 | In jurisdictions which recognize Public Domain property, the user of this 22 | software may choose to accept it either as 1) Public Domain, 2) under the 23 | conditions of the MIT License (see below), or 3) under the terms of dual 24 | Public Domain/MIT License conditions described here, as they choose. 25 | 26 | The MIT License is about as close to Public Domain as a license can get, and is 27 | described in clear, concise terms at: 28 | 29 | http://en.wikipedia.org/wiki/MIT_License 30 | 31 | The full text of the MIT License follows: 32 | 33 | ======================================================================== 34 | Copyright (c) 2007-2010 Baptiste Lepilleur 35 | 36 | Permission is hereby granted, free of charge, to any person 37 | obtaining a copy of this software and associated documentation 38 | files (the "Software"), to deal in the Software without 39 | restriction, including without limitation the rights to use, copy, 40 | modify, merge, publish, distribute, sublicense, and/or sell copies 41 | of the Software, and to permit persons to whom the Software is 42 | furnished to do so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be 45 | included in all copies or substantial portions of the Software. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 48 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 49 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 50 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 51 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 52 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 53 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 54 | SOFTWARE. 55 | ======================================================================== 56 | (END LICENSE TEXT) 57 | 58 | The MIT license is compatible with both the GPL and commercial 59 | software, affording one all of the rights of Public Domain with the 60 | minor nuisance of being required to keep the above copyright notice 61 | and license text in the source code. Note also that by accepting the 62 | Public Domain "license" you can re-license your copy using whatever 63 | license you like. 64 | 65 | */ 66 | 67 | // ////////////////////////////////////////////////////////////////////// 68 | // End of content of file: LICENSE 69 | // ////////////////////////////////////////////////////////////////////// 70 | 71 | 72 | 73 | 74 | 75 | #ifndef JSON_AMALGATED_H_INCLUDED 76 | # define JSON_AMALGATED_H_INCLUDED 77 | /// If defined, indicates that the source file is amalgated 78 | /// to prevent private header inclusion. 79 | #define JSON_IS_AMALGAMATION 80 | 81 | // ////////////////////////////////////////////////////////////////////// 82 | // Beginning of content of file: include/json/version.h 83 | // ////////////////////////////////////////////////////////////////////// 84 | 85 | // DO NOT EDIT. This file (and "version") is generated by CMake. 86 | // Run CMake configure step to update it. 87 | #ifndef JSON_VERSION_H_INCLUDED 88 | # define JSON_VERSION_H_INCLUDED 89 | 90 | # define JSONCPP_VERSION_STRING "1.7.4" 91 | # define JSONCPP_VERSION_MAJOR 1 92 | # define JSONCPP_VERSION_MINOR 7 93 | # define JSONCPP_VERSION_PATCH 4 94 | # define JSONCPP_VERSION_QUALIFIER 95 | # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) 96 | 97 | #ifdef JSONCPP_USING_SECURE_MEMORY 98 | #undef JSONCPP_USING_SECURE_MEMORY 99 | #endif 100 | #define JSONCPP_USING_SECURE_MEMORY 0 101 | // If non-zero, the library zeroes any memory that it has allocated before 102 | // it frees its memory. 103 | 104 | #endif // JSON_VERSION_H_INCLUDED 105 | 106 | // ////////////////////////////////////////////////////////////////////// 107 | // End of content of file: include/json/version.h 108 | // ////////////////////////////////////////////////////////////////////// 109 | 110 | 111 | 112 | 113 | 114 | 115 | // ////////////////////////////////////////////////////////////////////// 116 | // Beginning of content of file: include/json/config.h 117 | // ////////////////////////////////////////////////////////////////////// 118 | 119 | // Copyright 2007-2010 Baptiste Lepilleur 120 | // Distributed under MIT license, or public domain if desired and 121 | // recognized in your jurisdiction. 122 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 123 | 124 | #ifndef JSON_CONFIG_H_INCLUDED 125 | #define JSON_CONFIG_H_INCLUDED 126 | #include 127 | #include //typdef String 128 | 129 | /// If defined, indicates that json library is embedded in CppTL library. 130 | //# define JSON_IN_CPPTL 1 131 | 132 | /// If defined, indicates that json may leverage CppTL library 133 | //# define JSON_USE_CPPTL 1 134 | /// If defined, indicates that cpptl vector based map should be used instead of 135 | /// std::map 136 | /// as Value container. 137 | //# define JSON_USE_CPPTL_SMALLMAP 1 138 | 139 | // If non-zero, the library uses exceptions to report bad input instead of C 140 | // assertion macros. The default is to use exceptions. 141 | #ifndef JSON_USE_EXCEPTION 142 | #define JSON_USE_EXCEPTION 1 143 | #endif 144 | 145 | /// If defined, indicates that the source file is amalgated 146 | /// to prevent private header inclusion. 147 | /// Remarks: it is automatically defined in the generated amalgated header. 148 | // #define JSON_IS_AMALGAMATION 149 | 150 | #ifdef JSON_IN_CPPTL 151 | #include 152 | #ifndef JSON_USE_CPPTL 153 | #define JSON_USE_CPPTL 1 154 | #endif 155 | #endif 156 | 157 | #ifdef JSON_IN_CPPTL 158 | #define JSON_API CPPTL_API 159 | #elif defined(JSON_DLL_BUILD) 160 | #if defined(_MSC_VER) || defined(__MINGW32__) 161 | #define JSON_API __declspec(dllexport) 162 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 163 | #endif // if defined(_MSC_VER) 164 | #elif defined(JSON_DLL) 165 | #if defined(_MSC_VER) || defined(__MINGW32__) 166 | #define JSON_API __declspec(dllimport) 167 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 168 | #endif // if defined(_MSC_VER) 169 | #endif // ifdef JSON_IN_CPPTL 170 | #if !defined(JSON_API) 171 | #define JSON_API 172 | #endif 173 | 174 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 175 | // integer 176 | // Storages, and 64 bits integer support is disabled. 177 | // #define JSON_NO_INT64 1 178 | 179 | #if defined(_MSC_VER) // MSVC 180 | # if _MSC_VER <= 1200 // MSVC 6 181 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 182 | // (no conversion from unsigned __int64). 183 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 184 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 185 | // characters in the debug information) 186 | // All projects I've ever seen with VS6 were using this globally (not bothering 187 | // with pragma push/pop). 188 | # pragma warning(disable : 4786) 189 | # endif // MSVC 6 190 | 191 | # if _MSC_VER >= 1500 // MSVC 2008 192 | /// Indicates that the following function is deprecated. 193 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 194 | # endif 195 | 196 | #endif // defined(_MSC_VER) 197 | 198 | // In c++11 the override keyword allows you to explicity define that a function 199 | // is intended to override the base-class version. This makes the code more 200 | // managable and fixes a set of common hard-to-find bugs. 201 | #if __cplusplus >= 201103L 202 | # define JSONCPP_OVERRIDE override 203 | #elif defined(_MSC_VER) && _MSC_VER > 1600 204 | # define JSONCPP_OVERRIDE override 205 | #else 206 | # define JSONCPP_OVERRIDE 207 | #endif 208 | 209 | #ifndef JSON_HAS_RVALUE_REFERENCES 210 | 211 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 212 | #define JSON_HAS_RVALUE_REFERENCES 1 213 | #endif // MSVC >= 2010 214 | 215 | #ifdef __clang__ 216 | #if __has_feature(cxx_rvalue_references) 217 | #define JSON_HAS_RVALUE_REFERENCES 1 218 | #endif // has_feature 219 | 220 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 221 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) 222 | #define JSON_HAS_RVALUE_REFERENCES 1 223 | #endif // GXX_EXPERIMENTAL 224 | 225 | #endif // __clang__ || __GNUC__ 226 | 227 | #endif // not defined JSON_HAS_RVALUE_REFERENCES 228 | 229 | #ifndef JSON_HAS_RVALUE_REFERENCES 230 | #define JSON_HAS_RVALUE_REFERENCES 0 231 | #endif 232 | 233 | #ifdef __clang__ 234 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 235 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 236 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 237 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 238 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 239 | # endif // GNUC version 240 | #endif // __clang__ || __GNUC__ 241 | 242 | #if !defined(JSONCPP_DEPRECATED) 243 | #define JSONCPP_DEPRECATED(message) 244 | #endif // if !defined(JSONCPP_DEPRECATED) 245 | 246 | #if __GNUC__ >= 6 247 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 248 | #endif 249 | 250 | #if !defined(JSON_IS_AMALGAMATION) 251 | 252 | # include "version.h" 253 | 254 | # if JSONCPP_USING_SECURE_MEMORY 255 | # include "allocator.h" //typedef Allocator 256 | # endif 257 | 258 | #endif // if !defined(JSON_IS_AMALGAMATION) 259 | 260 | namespace Json { 261 | typedef int Int; 262 | typedef unsigned int UInt; 263 | #if defined(JSON_NO_INT64) 264 | typedef int LargestInt; 265 | typedef unsigned int LargestUInt; 266 | #undef JSON_HAS_INT64 267 | #else // if defined(JSON_NO_INT64) 268 | // For Microsoft Visual use specific types as long long is not supported 269 | #if defined(_MSC_VER) // Microsoft Visual Studio 270 | typedef __int64 Int64; 271 | typedef unsigned __int64 UInt64; 272 | #else // if defined(_MSC_VER) // Other platforms, use long long 273 | typedef long long int Int64; 274 | typedef unsigned long long int UInt64; 275 | #endif // if defined(_MSC_VER) 276 | typedef Int64 LargestInt; 277 | typedef UInt64 LargestUInt; 278 | #define JSON_HAS_INT64 279 | #endif // if defined(JSON_NO_INT64) 280 | #if JSONCPP_USING_SECURE_MEMORY 281 | #define JSONCPP_STRING std::basic_string, Json::SecureAllocator > 282 | #define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > 283 | #define JSONCPP_OSTREAM std::basic_ostream> 284 | #define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > 285 | #define JSONCPP_ISTREAM std::istream 286 | #else 287 | #define JSONCPP_STRING std::string 288 | #define JSONCPP_OSTRINGSTREAM std::ostringstream 289 | #define JSONCPP_OSTREAM std::ostream 290 | #define JSONCPP_ISTRINGSTREAM std::istringstream 291 | #define JSONCPP_ISTREAM std::istream 292 | #endif // if JSONCPP_USING_SECURE_MEMORY 293 | } // end namespace Json 294 | 295 | #endif // JSON_CONFIG_H_INCLUDED 296 | 297 | // ////////////////////////////////////////////////////////////////////// 298 | // End of content of file: include/json/config.h 299 | // ////////////////////////////////////////////////////////////////////// 300 | 301 | 302 | 303 | 304 | 305 | 306 | // ////////////////////////////////////////////////////////////////////// 307 | // Beginning of content of file: include/json/forwards.h 308 | // ////////////////////////////////////////////////////////////////////// 309 | 310 | // Copyright 2007-2010 Baptiste Lepilleur 311 | // Distributed under MIT license, or public domain if desired and 312 | // recognized in your jurisdiction. 313 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 314 | 315 | #ifndef JSON_FORWARDS_H_INCLUDED 316 | #define JSON_FORWARDS_H_INCLUDED 317 | 318 | #if !defined(JSON_IS_AMALGAMATION) 319 | #include "config.h" 320 | #endif // if !defined(JSON_IS_AMALGAMATION) 321 | 322 | namespace Json { 323 | 324 | // writer.h 325 | class FastWriter; 326 | class StyledWriter; 327 | 328 | // reader.h 329 | class Reader; 330 | 331 | // features.h 332 | class Features; 333 | 334 | // value.h 335 | typedef unsigned int ArrayIndex; 336 | class StaticString; 337 | class Path; 338 | class PathArgument; 339 | class Value; 340 | class ValueIteratorBase; 341 | class ValueIterator; 342 | class ValueConstIterator; 343 | 344 | } // namespace Json 345 | 346 | #endif // JSON_FORWARDS_H_INCLUDED 347 | 348 | // ////////////////////////////////////////////////////////////////////// 349 | // End of content of file: include/json/forwards.h 350 | // ////////////////////////////////////////////////////////////////////// 351 | 352 | 353 | 354 | 355 | 356 | 357 | // ////////////////////////////////////////////////////////////////////// 358 | // Beginning of content of file: include/json/features.h 359 | // ////////////////////////////////////////////////////////////////////// 360 | 361 | // Copyright 2007-2010 Baptiste Lepilleur 362 | // Distributed under MIT license, or public domain if desired and 363 | // recognized in your jurisdiction. 364 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 365 | 366 | #ifndef CPPTL_JSON_FEATURES_H_INCLUDED 367 | #define CPPTL_JSON_FEATURES_H_INCLUDED 368 | 369 | #if !defined(JSON_IS_AMALGAMATION) 370 | #include "forwards.h" 371 | #endif // if !defined(JSON_IS_AMALGAMATION) 372 | 373 | namespace Json { 374 | 375 | /** \brief Configuration passed to reader and writer. 376 | * This configuration object can be used to force the Reader or Writer 377 | * to behave in a standard conforming way. 378 | */ 379 | class JSON_API Features { 380 | public: 381 | /** \brief A configuration that allows all features and assumes all strings 382 | * are UTF-8. 383 | * - C & C++ comments are allowed 384 | * - Root object can be any JSON value 385 | * - Assumes Value strings are encoded in UTF-8 386 | */ 387 | static Features all(); 388 | 389 | /** \brief A configuration that is strictly compatible with the JSON 390 | * specification. 391 | * - Comments are forbidden. 392 | * - Root object must be either an array or an object value. 393 | * - Assumes Value strings are encoded in UTF-8 394 | */ 395 | static Features strictMode(); 396 | 397 | /** \brief Initialize the configuration like JsonConfig::allFeatures; 398 | */ 399 | Features(); 400 | 401 | /// \c true if comments are allowed. Default: \c true. 402 | bool allowComments_; 403 | 404 | /// \c true if root must be either an array or an object value. Default: \c 405 | /// false. 406 | bool strictRoot_; 407 | 408 | /// \c true if dropped null placeholders are allowed. Default: \c false. 409 | bool allowDroppedNullPlaceholders_; 410 | 411 | /// \c true if numeric object key are allowed. Default: \c false. 412 | bool allowNumericKeys_; 413 | }; 414 | 415 | } // namespace Json 416 | 417 | #endif // CPPTL_JSON_FEATURES_H_INCLUDED 418 | 419 | // ////////////////////////////////////////////////////////////////////// 420 | // End of content of file: include/json/features.h 421 | // ////////////////////////////////////////////////////////////////////// 422 | 423 | 424 | 425 | 426 | 427 | 428 | // ////////////////////////////////////////////////////////////////////// 429 | // Beginning of content of file: include/json/value.h 430 | // ////////////////////////////////////////////////////////////////////// 431 | 432 | // Copyright 2007-2010 Baptiste Lepilleur 433 | // Distributed under MIT license, or public domain if desired and 434 | // recognized in your jurisdiction. 435 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 436 | 437 | #ifndef CPPTL_JSON_H_INCLUDED 438 | #define CPPTL_JSON_H_INCLUDED 439 | 440 | #if !defined(JSON_IS_AMALGAMATION) 441 | #include "forwards.h" 442 | #endif // if !defined(JSON_IS_AMALGAMATION) 443 | #include 444 | #include 445 | #include 446 | 447 | #ifndef JSON_USE_CPPTL_SMALLMAP 448 | #include 449 | #else 450 | #include 451 | #endif 452 | #ifdef JSON_USE_CPPTL 453 | #include 454 | #endif 455 | 456 | //Conditional NORETURN attribute on the throw functions would: 457 | // a) suppress false positives from static code analysis 458 | // b) possibly improve optimization opportunities. 459 | #if !defined(JSONCPP_NORETURN) 460 | # if defined(_MSC_VER) 461 | # define JSONCPP_NORETURN __declspec(noreturn) 462 | # elif defined(__GNUC__) 463 | # define JSONCPP_NORETURN __attribute__ ((__noreturn__)) 464 | # else 465 | # define JSONCPP_NORETURN 466 | # endif 467 | #endif 468 | 469 | // Disable warning C4251: : needs to have dll-interface to 470 | // be used by... 471 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 472 | #pragma warning(push) 473 | #pragma warning(disable : 4251) 474 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 475 | 476 | /** \brief JSON (JavaScript Object Notation). 477 | */ 478 | namespace Json { 479 | 480 | /** Base class for all exceptions we throw. 481 | * 482 | * We use nothing but these internally. Of course, STL can throw others. 483 | */ 484 | class JSON_API Exception : public std::exception { 485 | public: 486 | Exception(JSONCPP_STRING const& msg); 487 | ~Exception() throw() JSONCPP_OVERRIDE; 488 | char const* what() const throw() JSONCPP_OVERRIDE; 489 | protected: 490 | JSONCPP_STRING msg_; 491 | }; 492 | 493 | /** Exceptions which the user cannot easily avoid. 494 | * 495 | * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input 496 | * 497 | * \remark derived from Json::Exception 498 | */ 499 | class JSON_API RuntimeError : public Exception { 500 | public: 501 | RuntimeError(JSONCPP_STRING const& msg); 502 | }; 503 | 504 | /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. 505 | * 506 | * These are precondition-violations (user bugs) and internal errors (our bugs). 507 | * 508 | * \remark derived from Json::Exception 509 | */ 510 | class JSON_API LogicError : public Exception { 511 | public: 512 | LogicError(JSONCPP_STRING const& msg); 513 | }; 514 | 515 | /// used internally 516 | JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg); 517 | /// used internally 518 | JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg); 519 | 520 | /** \brief Type of the value held by a Value object. 521 | */ 522 | enum ValueType { 523 | nullValue = 0, ///< 'null' value 524 | intValue, ///< signed integer value 525 | uintValue, ///< unsigned integer value 526 | realValue, ///< double value 527 | stringValue, ///< UTF-8 string value 528 | booleanValue, ///< bool value 529 | arrayValue, ///< array value (ordered list) 530 | objectValue ///< object value (collection of name/value pairs). 531 | }; 532 | 533 | enum CommentPlacement { 534 | commentBefore = 0, ///< a comment placed on the line before a value 535 | commentAfterOnSameLine, ///< a comment just after a value on the same line 536 | commentAfter, ///< a comment on the line after a value (only make sense for 537 | /// root value) 538 | numberOfCommentPlacement 539 | }; 540 | 541 | //# ifdef JSON_USE_CPPTL 542 | // typedef CppTL::AnyEnumerator EnumMemberNames; 543 | // typedef CppTL::AnyEnumerator EnumValues; 544 | //# endif 545 | 546 | /** \brief Lightweight wrapper to tag static string. 547 | * 548 | * Value constructor and objectValue member assignement takes advantage of the 549 | * StaticString and avoid the cost of string duplication when storing the 550 | * string or the member name. 551 | * 552 | * Example of usage: 553 | * \code 554 | * Json::Value aValue( StaticString("some text") ); 555 | * Json::Value object; 556 | * static const StaticString code("code"); 557 | * object[code] = 1234; 558 | * \endcode 559 | */ 560 | class JSON_API StaticString { 561 | public: 562 | explicit StaticString(const char* czstring) : c_str_(czstring) {} 563 | 564 | operator const char*() const { return c_str_; } 565 | 566 | const char* c_str() const { return c_str_; } 567 | 568 | private: 569 | const char* c_str_; 570 | }; 571 | 572 | /** \brief Represents a JSON value. 573 | * 574 | * This class is a discriminated union wrapper that can represents a: 575 | * - signed integer [range: Value::minInt - Value::maxInt] 576 | * - unsigned integer (range: 0 - Value::maxUInt) 577 | * - double 578 | * - UTF-8 string 579 | * - boolean 580 | * - 'null' 581 | * - an ordered list of Value 582 | * - collection of name/value pairs (javascript object) 583 | * 584 | * The type of the held value is represented by a #ValueType and 585 | * can be obtained using type(). 586 | * 587 | * Values of an #objectValue or #arrayValue can be accessed using operator[]() 588 | * methods. 589 | * Non-const methods will automatically create the a #nullValue element 590 | * if it does not exist. 591 | * The sequence of an #arrayValue will be automatically resized and initialized 592 | * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. 593 | * 594 | * The get() methods can be used to obtain default value in the case the 595 | * required element does not exist. 596 | * 597 | * It is possible to iterate over the list of a #objectValue values using 598 | * the getMemberNames() method. 599 | * 600 | * \note #Value string-length fit in size_t, but keys must be < 2^30. 601 | * (The reason is an implementation detail.) A #CharReader will raise an 602 | * exception if a bound is exceeded to avoid security holes in your app, 603 | * but the Value API does *not* check bounds. That is the responsibility 604 | * of the caller. 605 | */ 606 | class JSON_API Value { 607 | friend class ValueIteratorBase; 608 | public: 609 | typedef std::vector Members; 610 | typedef ValueIterator iterator; 611 | typedef ValueConstIterator const_iterator; 612 | typedef Json::UInt UInt; 613 | typedef Json::Int Int; 614 | #if defined(JSON_HAS_INT64) 615 | typedef Json::UInt64 UInt64; 616 | typedef Json::Int64 Int64; 617 | #endif // defined(JSON_HAS_INT64) 618 | typedef Json::LargestInt LargestInt; 619 | typedef Json::LargestUInt LargestUInt; 620 | typedef Json::ArrayIndex ArrayIndex; 621 | 622 | static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). 623 | static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null 624 | static Value const& nullSingleton(); ///< Prefer this to null or nullRef. 625 | 626 | /// Minimum signed integer value that can be stored in a Json::Value. 627 | static const LargestInt minLargestInt; 628 | /// Maximum signed integer value that can be stored in a Json::Value. 629 | static const LargestInt maxLargestInt; 630 | /// Maximum unsigned integer value that can be stored in a Json::Value. 631 | static const LargestUInt maxLargestUInt; 632 | 633 | /// Minimum signed int value that can be stored in a Json::Value. 634 | static const Int minInt; 635 | /// Maximum signed int value that can be stored in a Json::Value. 636 | static const Int maxInt; 637 | /// Maximum unsigned int value that can be stored in a Json::Value. 638 | static const UInt maxUInt; 639 | 640 | #if defined(JSON_HAS_INT64) 641 | /// Minimum signed 64 bits int value that can be stored in a Json::Value. 642 | static const Int64 minInt64; 643 | /// Maximum signed 64 bits int value that can be stored in a Json::Value. 644 | static const Int64 maxInt64; 645 | /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. 646 | static const UInt64 maxUInt64; 647 | #endif // defined(JSON_HAS_INT64) 648 | 649 | private: 650 | #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 651 | class CZString { 652 | public: 653 | enum DuplicationPolicy { 654 | noDuplication = 0, 655 | duplicate, 656 | duplicateOnCopy 657 | }; 658 | CZString(ArrayIndex index); 659 | CZString(char const* str, unsigned length, DuplicationPolicy allocate); 660 | CZString(CZString const& other); 661 | #if JSON_HAS_RVALUE_REFERENCES 662 | CZString(CZString&& other); 663 | #endif 664 | ~CZString(); 665 | CZString& operator=(CZString other); 666 | bool operator<(CZString const& other) const; 667 | bool operator==(CZString const& other) const; 668 | ArrayIndex index() const; 669 | //const char* c_str() const; ///< \deprecated 670 | char const* data() const; 671 | unsigned length() const; 672 | bool isStaticString() const; 673 | 674 | private: 675 | void swap(CZString& other); 676 | 677 | struct StringStorage { 678 | unsigned policy_: 2; 679 | unsigned length_: 30; // 1GB max 680 | }; 681 | 682 | char const* cstr_; // actually, a prefixed string, unless policy is noDup 683 | union { 684 | ArrayIndex index_; 685 | StringStorage storage_; 686 | }; 687 | }; 688 | 689 | public: 690 | #ifndef JSON_USE_CPPTL_SMALLMAP 691 | typedef std::map ObjectValues; 692 | #else 693 | typedef CppTL::SmallMap ObjectValues; 694 | #endif // ifndef JSON_USE_CPPTL_SMALLMAP 695 | #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 696 | 697 | public: 698 | /** \brief Create a default Value of the given type. 699 | 700 | This is a very useful constructor. 701 | To create an empty array, pass arrayValue. 702 | To create an empty object, pass objectValue. 703 | Another Value can then be set to this one by assignment. 704 | This is useful since clear() and resize() will not alter types. 705 | 706 | Examples: 707 | \code 708 | Json::Value null_value; // null 709 | Json::Value arr_value(Json::arrayValue); // [] 710 | Json::Value obj_value(Json::objectValue); // {} 711 | \endcode 712 | */ 713 | Value(ValueType type = nullValue); 714 | Value(Int value); 715 | Value(UInt value); 716 | #if defined(JSON_HAS_INT64) 717 | Value(Int64 value); 718 | Value(UInt64 value); 719 | #endif // if defined(JSON_HAS_INT64) 720 | Value(double value); 721 | Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) 722 | Value(const char* begin, const char* end); ///< Copy all, incl zeroes. 723 | /** \brief Constructs a value from a static string. 724 | 725 | * Like other value string constructor but do not duplicate the string for 726 | * internal storage. The given string must remain alive after the call to this 727 | * constructor. 728 | * \note This works only for null-terminated strings. (We cannot change the 729 | * size of this class, so we have nowhere to store the length, 730 | * which might be computed later for various operations.) 731 | * 732 | * Example of usage: 733 | * \code 734 | * static StaticString foo("some text"); 735 | * Json::Value aValue(foo); 736 | * \endcode 737 | */ 738 | Value(const StaticString& value); 739 | Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too. 740 | #ifdef JSON_USE_CPPTL 741 | Value(const CppTL::ConstString& value); 742 | #endif 743 | Value(bool value); 744 | /// Deep copy. 745 | Value(const Value& other); 746 | #if JSON_HAS_RVALUE_REFERENCES 747 | /// Move constructor 748 | Value(Value&& other); 749 | #endif 750 | ~Value(); 751 | 752 | /// Deep copy, then swap(other). 753 | /// \note Over-write existing comments. To preserve comments, use #swapPayload(). 754 | Value& operator=(Value other); 755 | /// Swap everything. 756 | void swap(Value& other); 757 | /// Swap values but leave comments and source offsets in place. 758 | void swapPayload(Value& other); 759 | 760 | ValueType type() const; 761 | 762 | /// Compare payload only, not comments etc. 763 | bool operator<(const Value& other) const; 764 | bool operator<=(const Value& other) const; 765 | bool operator>=(const Value& other) const; 766 | bool operator>(const Value& other) const; 767 | bool operator==(const Value& other) const; 768 | bool operator!=(const Value& other) const; 769 | int compare(const Value& other) const; 770 | 771 | const char* asCString() const; ///< Embedded zeroes could cause you trouble! 772 | #if JSONCPP_USING_SECURE_MEMORY 773 | unsigned getCStringLength() const; //Allows you to understand the length of the CString 774 | #endif 775 | JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. 776 | /** Get raw char* of string-value. 777 | * \return false if !string. (Seg-fault if str or end are NULL.) 778 | */ 779 | bool getString( 780 | char const** begin, char const** end) const; 781 | #ifdef JSON_USE_CPPTL 782 | CppTL::ConstString asConstString() const; 783 | #endif 784 | Int asInt() const; 785 | UInt asUInt() const; 786 | #if defined(JSON_HAS_INT64) 787 | Int64 asInt64() const; 788 | UInt64 asUInt64() const; 789 | #endif // if defined(JSON_HAS_INT64) 790 | LargestInt asLargestInt() const; 791 | LargestUInt asLargestUInt() const; 792 | float asFloat() const; 793 | double asDouble() const; 794 | bool asBool() const; 795 | 796 | bool isNull() const; 797 | bool isBool() const; 798 | bool isInt() const; 799 | bool isInt64() const; 800 | bool isUInt() const; 801 | bool isUInt64() const; 802 | bool isIntegral() const; 803 | bool isDouble() const; 804 | bool isNumeric() const; 805 | bool isString() const; 806 | bool isArray() const; 807 | bool isObject() const; 808 | 809 | bool isConvertibleTo(ValueType other) const; 810 | 811 | /// Number of values in array or object 812 | ArrayIndex size() const; 813 | 814 | /// \brief Return true if empty array, empty object, or null; 815 | /// otherwise, false. 816 | bool empty() const; 817 | 818 | /// Return isNull() 819 | bool operator!() const; 820 | 821 | /// Remove all object members and array elements. 822 | /// \pre type() is arrayValue, objectValue, or nullValue 823 | /// \post type() is unchanged 824 | void clear(); 825 | 826 | /// Resize the array to size elements. 827 | /// New elements are initialized to null. 828 | /// May only be called on nullValue or arrayValue. 829 | /// \pre type() is arrayValue or nullValue 830 | /// \post type() is arrayValue 831 | void resize(ArrayIndex size); 832 | 833 | /// Access an array element (zero based index ). 834 | /// If the array contains less than index element, then null value are 835 | /// inserted 836 | /// in the array so that its size is index+1. 837 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 838 | /// this from the operator[] which takes a string.) 839 | Value& operator[](ArrayIndex index); 840 | 841 | /// Access an array element (zero based index ). 842 | /// If the array contains less than index element, then null value are 843 | /// inserted 844 | /// in the array so that its size is index+1. 845 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 846 | /// this from the operator[] which takes a string.) 847 | Value& operator[](int index); 848 | 849 | /// Access an array element (zero based index ) 850 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 851 | /// this from the operator[] which takes a string.) 852 | const Value& operator[](ArrayIndex index) const; 853 | 854 | /// Access an array element (zero based index ) 855 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 856 | /// this from the operator[] which takes a string.) 857 | const Value& operator[](int index) const; 858 | 859 | /// If the array contains at least index+1 elements, returns the element 860 | /// value, 861 | /// otherwise returns defaultValue. 862 | Value get(ArrayIndex index, const Value& defaultValue) const; 863 | /// Return true if index < size(). 864 | bool isValidIndex(ArrayIndex index) const; 865 | /// \brief Append value to array at the end. 866 | /// 867 | /// Equivalent to jsonvalue[jsonvalue.size()] = value; 868 | Value& append(const Value& value); 869 | 870 | /// Access an object value by name, create a null member if it does not exist. 871 | /// \note Because of our implementation, keys are limited to 2^30 -1 chars. 872 | /// Exceeding that will cause an exception. 873 | Value& operator[](const char* key); 874 | /// Access an object value by name, returns null if there is no member with 875 | /// that name. 876 | const Value& operator[](const char* key) const; 877 | /// Access an object value by name, create a null member if it does not exist. 878 | /// \param key may contain embedded nulls. 879 | Value& operator[](const JSONCPP_STRING& key); 880 | /// Access an object value by name, returns null if there is no member with 881 | /// that name. 882 | /// \param key may contain embedded nulls. 883 | const Value& operator[](const JSONCPP_STRING& key) const; 884 | /** \brief Access an object value by name, create a null member if it does not 885 | exist. 886 | 887 | * If the object has no entry for that name, then the member name used to store 888 | * the new entry is not duplicated. 889 | * Example of use: 890 | * \code 891 | * Json::Value object; 892 | * static const StaticString code("code"); 893 | * object[code] = 1234; 894 | * \endcode 895 | */ 896 | Value& operator[](const StaticString& key); 897 | #ifdef JSON_USE_CPPTL 898 | /// Access an object value by name, create a null member if it does not exist. 899 | Value& operator[](const CppTL::ConstString& key); 900 | /// Access an object value by name, returns null if there is no member with 901 | /// that name. 902 | const Value& operator[](const CppTL::ConstString& key) const; 903 | #endif 904 | /// Return the member named key if it exist, defaultValue otherwise. 905 | /// \note deep copy 906 | Value get(const char* key, const Value& defaultValue) const; 907 | /// Return the member named key if it exist, defaultValue otherwise. 908 | /// \note deep copy 909 | /// \note key may contain embedded nulls. 910 | Value get(const char* begin, const char* end, const Value& defaultValue) const; 911 | /// Return the member named key if it exist, defaultValue otherwise. 912 | /// \note deep copy 913 | /// \param key may contain embedded nulls. 914 | Value get(const JSONCPP_STRING& key, const Value& defaultValue) const; 915 | #ifdef JSON_USE_CPPTL 916 | /// Return the member named key if it exist, defaultValue otherwise. 917 | /// \note deep copy 918 | Value get(const CppTL::ConstString& key, const Value& defaultValue) const; 919 | #endif 920 | /// Most general and efficient version of isMember()const, get()const, 921 | /// and operator[]const 922 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 923 | Value const* find(char const* begin, char const* end) const; 924 | /// Most general and efficient version of object-mutators. 925 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 926 | /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. 927 | Value const* demand(char const* begin, char const* end); 928 | /// \brief Remove and return the named member. 929 | /// 930 | /// Do nothing if it did not exist. 931 | /// \return the removed Value, or null. 932 | /// \pre type() is objectValue or nullValue 933 | /// \post type() is unchanged 934 | /// \deprecated 935 | Value removeMember(const char* key); 936 | /// Same as removeMember(const char*) 937 | /// \param key may contain embedded nulls. 938 | /// \deprecated 939 | Value removeMember(const JSONCPP_STRING& key); 940 | /// Same as removeMember(const char* begin, const char* end, Value* removed), 941 | /// but 'key' is null-terminated. 942 | bool removeMember(const char* key, Value* removed); 943 | /** \brief Remove the named map member. 944 | 945 | Update 'removed' iff removed. 946 | \param key may contain embedded nulls. 947 | \return true iff removed (no exceptions) 948 | */ 949 | bool removeMember(JSONCPP_STRING const& key, Value* removed); 950 | /// Same as removeMember(JSONCPP_STRING const& key, Value* removed) 951 | bool removeMember(const char* begin, const char* end, Value* removed); 952 | /** \brief Remove the indexed array element. 953 | 954 | O(n) expensive operations. 955 | Update 'removed' iff removed. 956 | \return true iff removed (no exceptions) 957 | */ 958 | bool removeIndex(ArrayIndex i, Value* removed); 959 | 960 | /// Return true if the object has a member named key. 961 | /// \note 'key' must be null-terminated. 962 | bool isMember(const char* key) const; 963 | /// Return true if the object has a member named key. 964 | /// \param key may contain embedded nulls. 965 | bool isMember(const JSONCPP_STRING& key) const; 966 | /// Same as isMember(JSONCPP_STRING const& key)const 967 | bool isMember(const char* begin, const char* end) const; 968 | #ifdef JSON_USE_CPPTL 969 | /// Return true if the object has a member named key. 970 | bool isMember(const CppTL::ConstString& key) const; 971 | #endif 972 | 973 | /// \brief Return a list of the member names. 974 | /// 975 | /// If null, return an empty list. 976 | /// \pre type() is objectValue or nullValue 977 | /// \post if type() was nullValue, it remains nullValue 978 | Members getMemberNames() const; 979 | 980 | //# ifdef JSON_USE_CPPTL 981 | // EnumMemberNames enumMemberNames() const; 982 | // EnumValues enumValues() const; 983 | //# endif 984 | 985 | /// \deprecated Always pass len. 986 | JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.") 987 | void setComment(const char* comment, CommentPlacement placement); 988 | /// Comments must be //... or /* ... */ 989 | void setComment(const char* comment, size_t len, CommentPlacement placement); 990 | /// Comments must be //... or /* ... */ 991 | void setComment(const JSONCPP_STRING& comment, CommentPlacement placement); 992 | bool hasComment(CommentPlacement placement) const; 993 | /// Include delimiters and embedded newlines. 994 | JSONCPP_STRING getComment(CommentPlacement placement) const; 995 | 996 | JSONCPP_STRING toStyledString() const; 997 | 998 | const_iterator begin() const; 999 | const_iterator end() const; 1000 | 1001 | iterator begin(); 1002 | iterator end(); 1003 | 1004 | // Accessors for the [start, limit) range of bytes within the JSON text from 1005 | // which this value was parsed, if any. 1006 | void setOffsetStart(ptrdiff_t start); 1007 | void setOffsetLimit(ptrdiff_t limit); 1008 | ptrdiff_t getOffsetStart() const; 1009 | ptrdiff_t getOffsetLimit() const; 1010 | 1011 | private: 1012 | void initBasic(ValueType type, bool allocated = false); 1013 | 1014 | Value& resolveReference(const char* key); 1015 | Value& resolveReference(const char* key, const char* end); 1016 | 1017 | struct CommentInfo { 1018 | CommentInfo(); 1019 | ~CommentInfo(); 1020 | 1021 | void setComment(const char* text, size_t len); 1022 | 1023 | char* comment_; 1024 | }; 1025 | 1026 | // struct MemberNamesTransform 1027 | //{ 1028 | // typedef const char *result_type; 1029 | // const char *operator()( const CZString &name ) const 1030 | // { 1031 | // return name.c_str(); 1032 | // } 1033 | //}; 1034 | 1035 | union ValueHolder { 1036 | LargestInt int_; 1037 | LargestUInt uint_; 1038 | double real_; 1039 | bool bool_; 1040 | char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ 1041 | ObjectValues* map_; 1042 | } value_; 1043 | ValueType type_ : 8; 1044 | unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. 1045 | // If not allocated_, string_ must be null-terminated. 1046 | CommentInfo* comments_; 1047 | 1048 | // [start, limit) byte offsets in the source JSON text from which this Value 1049 | // was extracted. 1050 | ptrdiff_t start_; 1051 | ptrdiff_t limit_; 1052 | }; 1053 | 1054 | /** \brief Experimental and untested: represents an element of the "path" to 1055 | * access a node. 1056 | */ 1057 | class JSON_API PathArgument { 1058 | public: 1059 | friend class Path; 1060 | 1061 | PathArgument(); 1062 | PathArgument(ArrayIndex index); 1063 | PathArgument(const char* key); 1064 | PathArgument(const JSONCPP_STRING& key); 1065 | 1066 | private: 1067 | enum Kind { 1068 | kindNone = 0, 1069 | kindIndex, 1070 | kindKey 1071 | }; 1072 | JSONCPP_STRING key_; 1073 | ArrayIndex index_; 1074 | Kind kind_; 1075 | }; 1076 | 1077 | /** \brief Experimental and untested: represents a "path" to access a node. 1078 | * 1079 | * Syntax: 1080 | * - "." => root node 1081 | * - ".[n]" => elements at index 'n' of root node (an array value) 1082 | * - ".name" => member named 'name' of root node (an object value) 1083 | * - ".name1.name2.name3" 1084 | * - ".[0][1][2].name1[3]" 1085 | * - ".%" => member name is provided as parameter 1086 | * - ".[%]" => index is provied as parameter 1087 | */ 1088 | class JSON_API Path { 1089 | public: 1090 | Path(const JSONCPP_STRING& path, 1091 | const PathArgument& a1 = PathArgument(), 1092 | const PathArgument& a2 = PathArgument(), 1093 | const PathArgument& a3 = PathArgument(), 1094 | const PathArgument& a4 = PathArgument(), 1095 | const PathArgument& a5 = PathArgument()); 1096 | 1097 | const Value& resolve(const Value& root) const; 1098 | Value resolve(const Value& root, const Value& defaultValue) const; 1099 | /// Creates the "path" to access the specified node and returns a reference on 1100 | /// the node. 1101 | Value& make(Value& root) const; 1102 | 1103 | private: 1104 | typedef std::vector InArgs; 1105 | typedef std::vector Args; 1106 | 1107 | void makePath(const JSONCPP_STRING& path, const InArgs& in); 1108 | void addPathInArg(const JSONCPP_STRING& path, 1109 | const InArgs& in, 1110 | InArgs::const_iterator& itInArg, 1111 | PathArgument::Kind kind); 1112 | void invalidPath(const JSONCPP_STRING& path, int location); 1113 | 1114 | Args args_; 1115 | }; 1116 | 1117 | /** \brief base class for Value iterators. 1118 | * 1119 | */ 1120 | class JSON_API ValueIteratorBase { 1121 | public: 1122 | typedef std::bidirectional_iterator_tag iterator_category; 1123 | typedef unsigned int size_t; 1124 | typedef int difference_type; 1125 | typedef ValueIteratorBase SelfType; 1126 | 1127 | bool operator==(const SelfType& other) const { return isEqual(other); } 1128 | 1129 | bool operator!=(const SelfType& other) const { return !isEqual(other); } 1130 | 1131 | difference_type operator-(const SelfType& other) const { 1132 | return other.computeDistance(*this); 1133 | } 1134 | 1135 | /// Return either the index or the member name of the referenced value as a 1136 | /// Value. 1137 | Value key() const; 1138 | 1139 | /// Return the index of the referenced Value, or -1 if it is not an arrayValue. 1140 | UInt index() const; 1141 | 1142 | /// Return the member name of the referenced Value, or "" if it is not an 1143 | /// objectValue. 1144 | /// \note Avoid `c_str()` on result, as embedded zeroes are possible. 1145 | JSONCPP_STRING name() const; 1146 | 1147 | /// Return the member name of the referenced Value. "" if it is not an 1148 | /// objectValue. 1149 | /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. 1150 | JSONCPP_DEPRECATED("Use `key = name();` instead.") 1151 | char const* memberName() const; 1152 | /// Return the member name of the referenced Value, or NULL if it is not an 1153 | /// objectValue. 1154 | /// \note Better version than memberName(). Allows embedded nulls. 1155 | char const* memberName(char const** end) const; 1156 | 1157 | protected: 1158 | Value& deref() const; 1159 | 1160 | void increment(); 1161 | 1162 | void decrement(); 1163 | 1164 | difference_type computeDistance(const SelfType& other) const; 1165 | 1166 | bool isEqual(const SelfType& other) const; 1167 | 1168 | void copy(const SelfType& other); 1169 | 1170 | private: 1171 | Value::ObjectValues::iterator current_; 1172 | // Indicates that iterator is for a null value. 1173 | bool isNull_; 1174 | 1175 | public: 1176 | // For some reason, BORLAND needs these at the end, rather 1177 | // than earlier. No idea why. 1178 | ValueIteratorBase(); 1179 | explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); 1180 | }; 1181 | 1182 | /** \brief const iterator for object and array value. 1183 | * 1184 | */ 1185 | class JSON_API ValueConstIterator : public ValueIteratorBase { 1186 | friend class Value; 1187 | 1188 | public: 1189 | typedef const Value value_type; 1190 | //typedef unsigned int size_t; 1191 | //typedef int difference_type; 1192 | typedef const Value& reference; 1193 | typedef const Value* pointer; 1194 | typedef ValueConstIterator SelfType; 1195 | 1196 | ValueConstIterator(); 1197 | ValueConstIterator(ValueIterator const& other); 1198 | 1199 | private: 1200 | /*! \internal Use by Value to create an iterator. 1201 | */ 1202 | explicit ValueConstIterator(const Value::ObjectValues::iterator& current); 1203 | public: 1204 | SelfType& operator=(const ValueIteratorBase& other); 1205 | 1206 | SelfType operator++(int) { 1207 | SelfType temp(*this); 1208 | ++*this; 1209 | return temp; 1210 | } 1211 | 1212 | SelfType operator--(int) { 1213 | SelfType temp(*this); 1214 | --*this; 1215 | return temp; 1216 | } 1217 | 1218 | SelfType& operator--() { 1219 | decrement(); 1220 | return *this; 1221 | } 1222 | 1223 | SelfType& operator++() { 1224 | increment(); 1225 | return *this; 1226 | } 1227 | 1228 | reference operator*() const { return deref(); } 1229 | 1230 | pointer operator->() const { return &deref(); } 1231 | }; 1232 | 1233 | /** \brief Iterator for object and array value. 1234 | */ 1235 | class JSON_API ValueIterator : public ValueIteratorBase { 1236 | friend class Value; 1237 | 1238 | public: 1239 | typedef Value value_type; 1240 | typedef unsigned int size_t; 1241 | typedef int difference_type; 1242 | typedef Value& reference; 1243 | typedef Value* pointer; 1244 | typedef ValueIterator SelfType; 1245 | 1246 | ValueIterator(); 1247 | explicit ValueIterator(const ValueConstIterator& other); 1248 | ValueIterator(const ValueIterator& other); 1249 | 1250 | private: 1251 | /*! \internal Use by Value to create an iterator. 1252 | */ 1253 | explicit ValueIterator(const Value::ObjectValues::iterator& current); 1254 | public: 1255 | SelfType& operator=(const SelfType& other); 1256 | 1257 | SelfType operator++(int) { 1258 | SelfType temp(*this); 1259 | ++*this; 1260 | return temp; 1261 | } 1262 | 1263 | SelfType operator--(int) { 1264 | SelfType temp(*this); 1265 | --*this; 1266 | return temp; 1267 | } 1268 | 1269 | SelfType& operator--() { 1270 | decrement(); 1271 | return *this; 1272 | } 1273 | 1274 | SelfType& operator++() { 1275 | increment(); 1276 | return *this; 1277 | } 1278 | 1279 | reference operator*() const { return deref(); } 1280 | 1281 | pointer operator->() const { return &deref(); } 1282 | }; 1283 | 1284 | } // namespace Json 1285 | 1286 | 1287 | namespace std { 1288 | /// Specialize std::swap() for Json::Value. 1289 | template<> 1290 | inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } 1291 | } 1292 | 1293 | 1294 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1295 | #pragma warning(pop) 1296 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1297 | 1298 | #endif // CPPTL_JSON_H_INCLUDED 1299 | 1300 | // ////////////////////////////////////////////////////////////////////// 1301 | // End of content of file: include/json/value.h 1302 | // ////////////////////////////////////////////////////////////////////// 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | 1309 | // ////////////////////////////////////////////////////////////////////// 1310 | // Beginning of content of file: include/json/reader.h 1311 | // ////////////////////////////////////////////////////////////////////// 1312 | 1313 | // Copyright 2007-2010 Baptiste Lepilleur 1314 | // Distributed under MIT license, or public domain if desired and 1315 | // recognized in your jurisdiction. 1316 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1317 | 1318 | #ifndef CPPTL_JSON_READER_H_INCLUDED 1319 | #define CPPTL_JSON_READER_H_INCLUDED 1320 | 1321 | #if !defined(JSON_IS_AMALGAMATION) 1322 | #include "features.h" 1323 | #include "value.h" 1324 | #endif // if !defined(JSON_IS_AMALGAMATION) 1325 | #include 1326 | #include 1327 | #include 1328 | #include 1329 | #include 1330 | 1331 | // Disable warning C4251: : needs to have dll-interface to 1332 | // be used by... 1333 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1334 | #pragma warning(push) 1335 | #pragma warning(disable : 4251) 1336 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1337 | 1338 | namespace Json { 1339 | 1340 | /** \brief Unserialize a JSON document into a 1341 | *Value. 1342 | * 1343 | * \deprecated Use CharReader and CharReaderBuilder. 1344 | */ 1345 | class JSON_API Reader { 1346 | public: 1347 | typedef char Char; 1348 | typedef const Char* Location; 1349 | 1350 | /** \brief An error tagged with where in the JSON text it was encountered. 1351 | * 1352 | * The offsets give the [start, limit) range of bytes within the text. Note 1353 | * that this is bytes, not codepoints. 1354 | * 1355 | */ 1356 | struct StructuredError { 1357 | ptrdiff_t offset_start; 1358 | ptrdiff_t offset_limit; 1359 | JSONCPP_STRING message; 1360 | }; 1361 | 1362 | /** \brief Constructs a Reader allowing all features 1363 | * for parsing. 1364 | */ 1365 | Reader(); 1366 | 1367 | /** \brief Constructs a Reader allowing the specified feature set 1368 | * for parsing. 1369 | */ 1370 | Reader(const Features& features); 1371 | 1372 | /** \brief Read a Value from a JSON 1373 | * document. 1374 | * \param document UTF-8 encoded string containing the document to read. 1375 | * \param root [out] Contains the root value of the document if it was 1376 | * successfully parsed. 1377 | * \param collectComments \c true to collect comment and allow writing them 1378 | * back during 1379 | * serialization, \c false to discard comments. 1380 | * This parameter is ignored if 1381 | * Features::allowComments_ 1382 | * is \c false. 1383 | * \return \c true if the document was successfully parsed, \c false if an 1384 | * error occurred. 1385 | */ 1386 | bool 1387 | parse(const std::string& document, Value& root, bool collectComments = true); 1388 | 1389 | /** \brief Read a Value from a JSON 1390 | document. 1391 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1392 | document to read. 1393 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1394 | document to read. 1395 | * Must be >= beginDoc. 1396 | * \param root [out] Contains the root value of the document if it was 1397 | * successfully parsed. 1398 | * \param collectComments \c true to collect comment and allow writing them 1399 | back during 1400 | * serialization, \c false to discard comments. 1401 | * This parameter is ignored if 1402 | Features::allowComments_ 1403 | * is \c false. 1404 | * \return \c true if the document was successfully parsed, \c false if an 1405 | error occurred. 1406 | */ 1407 | bool parse(const char* beginDoc, 1408 | const char* endDoc, 1409 | Value& root, 1410 | bool collectComments = true); 1411 | 1412 | /// \brief Parse from input stream. 1413 | /// \see Json::operator>>(std::istream&, Json::Value&). 1414 | bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true); 1415 | 1416 | /** \brief Returns a user friendly string that list errors in the parsed 1417 | * document. 1418 | * \return Formatted error message with the list of errors with their location 1419 | * in 1420 | * the parsed document. An empty string is returned if no error 1421 | * occurred 1422 | * during parsing. 1423 | * \deprecated Use getFormattedErrorMessages() instead (typo fix). 1424 | */ 1425 | JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") 1426 | JSONCPP_STRING getFormatedErrorMessages() const; 1427 | 1428 | /** \brief Returns a user friendly string that list errors in the parsed 1429 | * document. 1430 | * \return Formatted error message with the list of errors with their location 1431 | * in 1432 | * the parsed document. An empty string is returned if no error 1433 | * occurred 1434 | * during parsing. 1435 | */ 1436 | JSONCPP_STRING getFormattedErrorMessages() const; 1437 | 1438 | /** \brief Returns a vector of structured erros encounted while parsing. 1439 | * \return A (possibly empty) vector of StructuredError objects. Currently 1440 | * only one error can be returned, but the caller should tolerate 1441 | * multiple 1442 | * errors. This can occur if the parser recovers from a non-fatal 1443 | * parse error and then encounters additional errors. 1444 | */ 1445 | std::vector getStructuredErrors() const; 1446 | 1447 | /** \brief Add a semantic error message. 1448 | * \param value JSON Value location associated with the error 1449 | * \param message The error message. 1450 | * \return \c true if the error was successfully added, \c false if the 1451 | * Value offset exceeds the document size. 1452 | */ 1453 | bool pushError(const Value& value, const JSONCPP_STRING& message); 1454 | 1455 | /** \brief Add a semantic error message with extra context. 1456 | * \param value JSON Value location associated with the error 1457 | * \param message The error message. 1458 | * \param extra Additional JSON Value location to contextualize the error 1459 | * \return \c true if the error was successfully added, \c false if either 1460 | * Value offset exceeds the document size. 1461 | */ 1462 | bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); 1463 | 1464 | /** \brief Return whether there are any errors. 1465 | * \return \c true if there are no errors to report \c false if 1466 | * errors have occurred. 1467 | */ 1468 | bool good() const; 1469 | 1470 | private: 1471 | enum TokenType { 1472 | tokenEndOfStream = 0, 1473 | tokenObjectBegin, 1474 | tokenObjectEnd, 1475 | tokenArrayBegin, 1476 | tokenArrayEnd, 1477 | tokenString, 1478 | tokenNumber, 1479 | tokenTrue, 1480 | tokenFalse, 1481 | tokenNull, 1482 | tokenArraySeparator, 1483 | tokenMemberSeparator, 1484 | tokenComment, 1485 | tokenError 1486 | }; 1487 | 1488 | class Token { 1489 | public: 1490 | TokenType type_; 1491 | Location start_; 1492 | Location end_; 1493 | }; 1494 | 1495 | class ErrorInfo { 1496 | public: 1497 | Token token_; 1498 | JSONCPP_STRING message_; 1499 | Location extra_; 1500 | }; 1501 | 1502 | typedef std::deque Errors; 1503 | 1504 | bool readToken(Token& token); 1505 | void skipSpaces(); 1506 | bool match(Location pattern, int patternLength); 1507 | bool readComment(); 1508 | bool readCStyleComment(); 1509 | bool readCppStyleComment(); 1510 | bool readString(); 1511 | void readNumber(); 1512 | bool readValue(); 1513 | bool readObject(Token& token); 1514 | bool readArray(Token& token); 1515 | bool decodeNumber(Token& token); 1516 | bool decodeNumber(Token& token, Value& decoded); 1517 | bool decodeString(Token& token); 1518 | bool decodeString(Token& token, JSONCPP_STRING& decoded); 1519 | bool decodeDouble(Token& token); 1520 | bool decodeDouble(Token& token, Value& decoded); 1521 | bool decodeUnicodeCodePoint(Token& token, 1522 | Location& current, 1523 | Location end, 1524 | unsigned int& unicode); 1525 | bool decodeUnicodeEscapeSequence(Token& token, 1526 | Location& current, 1527 | Location end, 1528 | unsigned int& unicode); 1529 | bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); 1530 | bool recoverFromError(TokenType skipUntilToken); 1531 | bool addErrorAndRecover(const JSONCPP_STRING& message, 1532 | Token& token, 1533 | TokenType skipUntilToken); 1534 | void skipUntilSpace(); 1535 | Value& currentValue(); 1536 | Char getNextChar(); 1537 | void 1538 | getLocationLineAndColumn(Location location, int& line, int& column) const; 1539 | JSONCPP_STRING getLocationLineAndColumn(Location location) const; 1540 | void addComment(Location begin, Location end, CommentPlacement placement); 1541 | void skipCommentTokens(Token& token); 1542 | 1543 | typedef std::stack Nodes; 1544 | Nodes nodes_; 1545 | Errors errors_; 1546 | JSONCPP_STRING document_; 1547 | Location begin_; 1548 | Location end_; 1549 | Location current_; 1550 | Location lastValueEnd_; 1551 | Value* lastValue_; 1552 | JSONCPP_STRING commentsBefore_; 1553 | Features features_; 1554 | bool collectComments_; 1555 | }; // Reader 1556 | 1557 | /** Interface for reading JSON from a char array. 1558 | */ 1559 | class JSON_API CharReader { 1560 | public: 1561 | virtual ~CharReader() {} 1562 | /** \brief Read a Value from a JSON 1563 | document. 1564 | * The document must be a UTF-8 encoded string containing the document to read. 1565 | * 1566 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1567 | document to read. 1568 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1569 | document to read. 1570 | * Must be >= beginDoc. 1571 | * \param root [out] Contains the root value of the document if it was 1572 | * successfully parsed. 1573 | * \param errs [out] Formatted error messages (if not NULL) 1574 | * a user friendly string that lists errors in the parsed 1575 | * document. 1576 | * \return \c true if the document was successfully parsed, \c false if an 1577 | error occurred. 1578 | */ 1579 | virtual bool parse( 1580 | char const* beginDoc, char const* endDoc, 1581 | Value* root, JSONCPP_STRING* errs) = 0; 1582 | 1583 | class JSON_API Factory { 1584 | public: 1585 | virtual ~Factory() {} 1586 | /** \brief Allocate a CharReader via operator new(). 1587 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1588 | */ 1589 | virtual CharReader* newCharReader() const = 0; 1590 | }; // Factory 1591 | }; // CharReader 1592 | 1593 | /** \brief Build a CharReader implementation. 1594 | 1595 | Usage: 1596 | \code 1597 | using namespace Json; 1598 | CharReaderBuilder builder; 1599 | builder["collectComments"] = false; 1600 | Value value; 1601 | JSONCPP_STRING errs; 1602 | bool ok = parseFromStream(builder, std::cin, &value, &errs); 1603 | \endcode 1604 | */ 1605 | class JSON_API CharReaderBuilder : public CharReader::Factory { 1606 | public: 1607 | // Note: We use a Json::Value so that we can add data-members to this class 1608 | // without a major version bump. 1609 | /** Configuration of this builder. 1610 | These are case-sensitive. 1611 | Available settings (case-sensitive): 1612 | - `"collectComments": false or true` 1613 | - true to collect comment and allow writing them 1614 | back during serialization, false to discard comments. 1615 | This parameter is ignored if allowComments is false. 1616 | - `"allowComments": false or true` 1617 | - true if comments are allowed. 1618 | - `"strictRoot": false or true` 1619 | - true if root must be either an array or an object value 1620 | - `"allowDroppedNullPlaceholders": false or true` 1621 | - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) 1622 | - `"allowNumericKeys": false or true` 1623 | - true if numeric object keys are allowed. 1624 | - `"allowSingleQuotes": false or true` 1625 | - true if '' are allowed for strings (both keys and values) 1626 | - `"stackLimit": integer` 1627 | - Exceeding stackLimit (recursive depth of `readValue()`) will 1628 | cause an exception. 1629 | - This is a security issue (seg-faults caused by deeply nested JSON), 1630 | so the default is low. 1631 | - `"failIfExtra": false or true` 1632 | - If true, `parse()` returns false when extra non-whitespace trails 1633 | the JSON value in the input string. 1634 | - `"rejectDupKeys": false or true` 1635 | - If true, `parse()` returns false when a key is duplicated within an object. 1636 | - `"allowSpecialFloats": false or true` 1637 | - If true, special float values (NaNs and infinities) are allowed 1638 | and their values are lossfree restorable. 1639 | 1640 | You can examine 'settings_` yourself 1641 | to see the defaults. You can also write and read them just like any 1642 | JSON Value. 1643 | \sa setDefaults() 1644 | */ 1645 | Json::Value settings_; 1646 | 1647 | CharReaderBuilder(); 1648 | ~CharReaderBuilder() JSONCPP_OVERRIDE; 1649 | 1650 | CharReader* newCharReader() const JSONCPP_OVERRIDE; 1651 | 1652 | /** \return true if 'settings' are legal and consistent; 1653 | * otherwise, indicate bad settings via 'invalid'. 1654 | */ 1655 | bool validate(Json::Value* invalid) const; 1656 | 1657 | /** A simple way to update a specific setting. 1658 | */ 1659 | Value& operator[](JSONCPP_STRING key); 1660 | 1661 | /** Called by ctor, but you can use this to reset settings_. 1662 | * \pre 'settings' != NULL (but Json::null is fine) 1663 | * \remark Defaults: 1664 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults 1665 | */ 1666 | static void setDefaults(Json::Value* settings); 1667 | /** Same as old Features::strictMode(). 1668 | * \pre 'settings' != NULL (but Json::null is fine) 1669 | * \remark Defaults: 1670 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode 1671 | */ 1672 | static void strictMode(Json::Value* settings); 1673 | }; 1674 | 1675 | /** Consume entire stream and use its begin/end. 1676 | * Someday we might have a real StreamReader, but for now this 1677 | * is convenient. 1678 | */ 1679 | bool JSON_API parseFromStream( 1680 | CharReader::Factory const&, 1681 | JSONCPP_ISTREAM&, 1682 | Value* root, std::string* errs); 1683 | 1684 | /** \brief Read from 'sin' into 'root'. 1685 | 1686 | Always keep comments from the input JSON. 1687 | 1688 | This can be used to read a file into a particular sub-object. 1689 | For example: 1690 | \code 1691 | Json::Value root; 1692 | cin >> root["dir"]["file"]; 1693 | cout << root; 1694 | \endcode 1695 | Result: 1696 | \verbatim 1697 | { 1698 | "dir": { 1699 | "file": { 1700 | // The input stream JSON would be nested here. 1701 | } 1702 | } 1703 | } 1704 | \endverbatim 1705 | \throw std::exception on parse error. 1706 | \see Json::operator<<() 1707 | */ 1708 | JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&); 1709 | 1710 | } // namespace Json 1711 | 1712 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1713 | #pragma warning(pop) 1714 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1715 | 1716 | #endif // CPPTL_JSON_READER_H_INCLUDED 1717 | 1718 | // ////////////////////////////////////////////////////////////////////// 1719 | // End of content of file: include/json/reader.h 1720 | // ////////////////////////////////////////////////////////////////////// 1721 | 1722 | 1723 | 1724 | 1725 | 1726 | 1727 | // ////////////////////////////////////////////////////////////////////// 1728 | // Beginning of content of file: include/json/writer.h 1729 | // ////////////////////////////////////////////////////////////////////// 1730 | 1731 | // Copyright 2007-2010 Baptiste Lepilleur 1732 | // Distributed under MIT license, or public domain if desired and 1733 | // recognized in your jurisdiction. 1734 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1735 | 1736 | #ifndef JSON_WRITER_H_INCLUDED 1737 | #define JSON_WRITER_H_INCLUDED 1738 | 1739 | #if !defined(JSON_IS_AMALGAMATION) 1740 | #include "value.h" 1741 | #endif // if !defined(JSON_IS_AMALGAMATION) 1742 | #include 1743 | #include 1744 | #include 1745 | 1746 | // Disable warning C4251: : needs to have dll-interface to 1747 | // be used by... 1748 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1749 | #pragma warning(push) 1750 | #pragma warning(disable : 4251) 1751 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1752 | 1753 | namespace Json { 1754 | 1755 | class Value; 1756 | 1757 | /** 1758 | 1759 | Usage: 1760 | \code 1761 | using namespace Json; 1762 | void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { 1763 | std::unique_ptr const writer( 1764 | factory.newStreamWriter()); 1765 | writer->write(value, &std::cout); 1766 | std::cout << std::endl; // add lf and flush 1767 | } 1768 | \endcode 1769 | */ 1770 | class JSON_API StreamWriter { 1771 | protected: 1772 | JSONCPP_OSTREAM* sout_; // not owned; will not delete 1773 | public: 1774 | StreamWriter(); 1775 | virtual ~StreamWriter(); 1776 | /** Write Value into document as configured in sub-class. 1777 | Do not take ownership of sout, but maintain a reference during function. 1778 | \pre sout != NULL 1779 | \return zero on success (For now, we always return zero, so check the stream instead.) 1780 | \throw std::exception possibly, depending on configuration 1781 | */ 1782 | virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; 1783 | 1784 | /** \brief A simple abstract factory. 1785 | */ 1786 | class JSON_API Factory { 1787 | public: 1788 | virtual ~Factory(); 1789 | /** \brief Allocate a CharReader via operator new(). 1790 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1791 | */ 1792 | virtual StreamWriter* newStreamWriter() const = 0; 1793 | }; // Factory 1794 | }; // StreamWriter 1795 | 1796 | /** \brief Write into stringstream, then return string, for convenience. 1797 | * A StreamWriter will be created from the factory, used, and then deleted. 1798 | */ 1799 | JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); 1800 | 1801 | 1802 | /** \brief Build a StreamWriter implementation. 1803 | 1804 | Usage: 1805 | \code 1806 | using namespace Json; 1807 | Value value = ...; 1808 | StreamWriterBuilder builder; 1809 | builder["commentStyle"] = "None"; 1810 | builder["indentation"] = " "; // or whatever you like 1811 | std::unique_ptr writer( 1812 | builder.newStreamWriter()); 1813 | writer->write(value, &std::cout); 1814 | std::cout << std::endl; // add lf and flush 1815 | \endcode 1816 | */ 1817 | class JSON_API StreamWriterBuilder : public StreamWriter::Factory { 1818 | public: 1819 | // Note: We use a Json::Value so that we can add data-members to this class 1820 | // without a major version bump. 1821 | /** Configuration of this builder. 1822 | Available settings (case-sensitive): 1823 | - "commentStyle": "None" or "All" 1824 | - "indentation": "" 1825 | - "enableYAMLCompatibility": false or true 1826 | - slightly change the whitespace around colons 1827 | - "dropNullPlaceholders": false or true 1828 | - Drop the "null" string from the writer's output for nullValues. 1829 | Strictly speaking, this is not valid JSON. But when the output is being 1830 | fed to a browser's Javascript, it makes for smaller output and the 1831 | browser can handle the output just fine. 1832 | - "useSpecialFloats": false or true 1833 | - If true, outputs non-finite floating point values in the following way: 1834 | NaN values as "NaN", positive infinity as "Infinity", and negative infinity 1835 | as "-Infinity". 1836 | 1837 | You can examine 'settings_` yourself 1838 | to see the defaults. You can also write and read them just like any 1839 | JSON Value. 1840 | \sa setDefaults() 1841 | */ 1842 | Json::Value settings_; 1843 | 1844 | StreamWriterBuilder(); 1845 | ~StreamWriterBuilder() JSONCPP_OVERRIDE; 1846 | 1847 | /** 1848 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1849 | */ 1850 | StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE; 1851 | 1852 | /** \return true if 'settings' are legal and consistent; 1853 | * otherwise, indicate bad settings via 'invalid'. 1854 | */ 1855 | bool validate(Json::Value* invalid) const; 1856 | /** A simple way to update a specific setting. 1857 | */ 1858 | Value& operator[](JSONCPP_STRING key); 1859 | 1860 | /** Called by ctor, but you can use this to reset settings_. 1861 | * \pre 'settings' != NULL (but Json::null is fine) 1862 | * \remark Defaults: 1863 | * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults 1864 | */ 1865 | static void setDefaults(Json::Value* settings); 1866 | }; 1867 | 1868 | /** \brief Abstract class for writers. 1869 | * \deprecated Use StreamWriter. (And really, this is an implementation detail.) 1870 | */ 1871 | class JSON_API Writer { 1872 | public: 1873 | virtual ~Writer(); 1874 | 1875 | virtual JSONCPP_STRING write(const Value& root) = 0; 1876 | }; 1877 | 1878 | /** \brief Outputs a Value in JSON format 1879 | *without formatting (not human friendly). 1880 | * 1881 | * The JSON document is written in a single line. It is not intended for 'human' 1882 | *consumption, 1883 | * but may be usefull to support feature such as RPC where bandwith is limited. 1884 | * \sa Reader, Value 1885 | * \deprecated Use StreamWriterBuilder. 1886 | */ 1887 | class JSON_API FastWriter : public Writer { 1888 | 1889 | public: 1890 | FastWriter(); 1891 | ~FastWriter() JSONCPP_OVERRIDE {} 1892 | 1893 | void enableYAMLCompatibility(); 1894 | 1895 | /** \brief Drop the "null" string from the writer's output for nullValues. 1896 | * Strictly speaking, this is not valid JSON. But when the output is being 1897 | * fed to a browser's Javascript, it makes for smaller output and the 1898 | * browser can handle the output just fine. 1899 | */ 1900 | void dropNullPlaceholders(); 1901 | 1902 | void omitEndingLineFeed(); 1903 | 1904 | public: // overridden from Writer 1905 | JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; 1906 | 1907 | private: 1908 | void writeValue(const Value& value); 1909 | 1910 | JSONCPP_STRING document_; 1911 | bool yamlCompatiblityEnabled_; 1912 | bool dropNullPlaceholders_; 1913 | bool omitEndingLineFeed_; 1914 | }; 1915 | 1916 | /** \brief Writes a Value in JSON format in a 1917 | *human friendly way. 1918 | * 1919 | * The rules for line break and indent are as follow: 1920 | * - Object value: 1921 | * - if empty then print {} without indent and line break 1922 | * - if not empty the print '{', line break & indent, print one value per 1923 | *line 1924 | * and then unindent and line break and print '}'. 1925 | * - Array value: 1926 | * - if empty then print [] without indent and line break 1927 | * - if the array contains no object value, empty array or some other value 1928 | *types, 1929 | * and all the values fit on one lines, then print the array on a single 1930 | *line. 1931 | * - otherwise, it the values do not fit on one line, or the array contains 1932 | * object or non empty array, then print one value per line. 1933 | * 1934 | * If the Value have comments then they are outputed according to their 1935 | *#CommentPlacement. 1936 | * 1937 | * \sa Reader, Value, Value::setComment() 1938 | * \deprecated Use StreamWriterBuilder. 1939 | */ 1940 | class JSON_API StyledWriter : public Writer { 1941 | public: 1942 | StyledWriter(); 1943 | ~StyledWriter() JSONCPP_OVERRIDE {} 1944 | 1945 | public: // overridden from Writer 1946 | /** \brief Serialize a Value in JSON format. 1947 | * \param root Value to serialize. 1948 | * \return String containing the JSON document that represents the root value. 1949 | */ 1950 | JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; 1951 | 1952 | private: 1953 | void writeValue(const Value& value); 1954 | void writeArrayValue(const Value& value); 1955 | bool isMultineArray(const Value& value); 1956 | void pushValue(const JSONCPP_STRING& value); 1957 | void writeIndent(); 1958 | void writeWithIndent(const JSONCPP_STRING& value); 1959 | void indent(); 1960 | void unindent(); 1961 | void writeCommentBeforeValue(const Value& root); 1962 | void writeCommentAfterValueOnSameLine(const Value& root); 1963 | bool hasCommentForValue(const Value& value); 1964 | static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); 1965 | 1966 | typedef std::vector ChildValues; 1967 | 1968 | ChildValues childValues_; 1969 | JSONCPP_STRING document_; 1970 | JSONCPP_STRING indentString_; 1971 | unsigned int rightMargin_; 1972 | unsigned int indentSize_; 1973 | bool addChildValues_; 1974 | }; 1975 | 1976 | /** \brief Writes a Value in JSON format in a 1977 | human friendly way, 1978 | to a stream rather than to a string. 1979 | * 1980 | * The rules for line break and indent are as follow: 1981 | * - Object value: 1982 | * - if empty then print {} without indent and line break 1983 | * - if not empty the print '{', line break & indent, print one value per 1984 | line 1985 | * and then unindent and line break and print '}'. 1986 | * - Array value: 1987 | * - if empty then print [] without indent and line break 1988 | * - if the array contains no object value, empty array or some other value 1989 | types, 1990 | * and all the values fit on one lines, then print the array on a single 1991 | line. 1992 | * - otherwise, it the values do not fit on one line, or the array contains 1993 | * object or non empty array, then print one value per line. 1994 | * 1995 | * If the Value have comments then they are outputed according to their 1996 | #CommentPlacement. 1997 | * 1998 | * \param indentation Each level will be indented by this amount extra. 1999 | * \sa Reader, Value, Value::setComment() 2000 | * \deprecated Use StreamWriterBuilder. 2001 | */ 2002 | class JSON_API StyledStreamWriter { 2003 | public: 2004 | StyledStreamWriter(JSONCPP_STRING indentation = "\t"); 2005 | ~StyledStreamWriter() {} 2006 | 2007 | public: 2008 | /** \brief Serialize a Value in JSON format. 2009 | * \param out Stream to write to. (Can be ostringstream, e.g.) 2010 | * \param root Value to serialize. 2011 | * \note There is no point in deriving from Writer, since write() should not 2012 | * return a value. 2013 | */ 2014 | void write(JSONCPP_OSTREAM& out, const Value& root); 2015 | 2016 | private: 2017 | void writeValue(const Value& value); 2018 | void writeArrayValue(const Value& value); 2019 | bool isMultineArray(const Value& value); 2020 | void pushValue(const JSONCPP_STRING& value); 2021 | void writeIndent(); 2022 | void writeWithIndent(const JSONCPP_STRING& value); 2023 | void indent(); 2024 | void unindent(); 2025 | void writeCommentBeforeValue(const Value& root); 2026 | void writeCommentAfterValueOnSameLine(const Value& root); 2027 | bool hasCommentForValue(const Value& value); 2028 | static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); 2029 | 2030 | typedef std::vector ChildValues; 2031 | 2032 | ChildValues childValues_; 2033 | JSONCPP_OSTREAM* document_; 2034 | JSONCPP_STRING indentString_; 2035 | unsigned int rightMargin_; 2036 | JSONCPP_STRING indentation_; 2037 | bool addChildValues_ : 1; 2038 | bool indented_ : 1; 2039 | }; 2040 | 2041 | #if defined(JSON_HAS_INT64) 2042 | JSONCPP_STRING JSON_API valueToString(Int value); 2043 | JSONCPP_STRING JSON_API valueToString(UInt value); 2044 | #endif // if defined(JSON_HAS_INT64) 2045 | JSONCPP_STRING JSON_API valueToString(LargestInt value); 2046 | JSONCPP_STRING JSON_API valueToString(LargestUInt value); 2047 | JSONCPP_STRING JSON_API valueToString(double value); 2048 | JSONCPP_STRING JSON_API valueToString(bool value); 2049 | JSONCPP_STRING JSON_API valueToQuotedString(const char* value); 2050 | 2051 | /// \brief Output using the StyledStreamWriter. 2052 | /// \see Json::operator>>() 2053 | JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root); 2054 | 2055 | } // namespace Json 2056 | 2057 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 2058 | #pragma warning(pop) 2059 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 2060 | 2061 | #endif // JSON_WRITER_H_INCLUDED 2062 | 2063 | // ////////////////////////////////////////////////////////////////////// 2064 | // End of content of file: include/json/writer.h 2065 | // ////////////////////////////////////////////////////////////////////// 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | // ////////////////////////////////////////////////////////////////////// 2073 | // Beginning of content of file: include/json/assertions.h 2074 | // ////////////////////////////////////////////////////////////////////// 2075 | 2076 | // Copyright 2007-2010 Baptiste Lepilleur 2077 | // Distributed under MIT license, or public domain if desired and 2078 | // recognized in your jurisdiction. 2079 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 2080 | 2081 | #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED 2082 | #define CPPTL_JSON_ASSERTIONS_H_INCLUDED 2083 | 2084 | #include 2085 | #include 2086 | 2087 | #if !defined(JSON_IS_AMALGAMATION) 2088 | #include "config.h" 2089 | #endif // if !defined(JSON_IS_AMALGAMATION) 2090 | 2091 | /** It should not be possible for a maliciously designed file to 2092 | * cause an abort() or seg-fault, so these macros are used only 2093 | * for pre-condition violations and internal logic errors. 2094 | */ 2095 | #if JSON_USE_EXCEPTION 2096 | 2097 | // @todo <= add detail about condition in exception 2098 | # define JSON_ASSERT(condition) \ 2099 | {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} 2100 | 2101 | # define JSON_FAIL_MESSAGE(message) \ 2102 | { \ 2103 | JSONCPP_OSTRINGSTREAM oss; oss << message; \ 2104 | Json::throwLogicError(oss.str()); \ 2105 | abort(); \ 2106 | } 2107 | 2108 | #else // JSON_USE_EXCEPTION 2109 | 2110 | # define JSON_ASSERT(condition) assert(condition) 2111 | 2112 | // The call to assert() will show the failure message in debug builds. In 2113 | // release builds we abort, for a core-dump or debugger. 2114 | # define JSON_FAIL_MESSAGE(message) \ 2115 | { \ 2116 | JSONCPP_OSTRINGSTREAM oss; oss << message; \ 2117 | assert(false && oss.str().c_str()); \ 2118 | abort(); \ 2119 | } 2120 | 2121 | 2122 | #endif 2123 | 2124 | #define JSON_ASSERT_MESSAGE(condition, message) \ 2125 | if (!(condition)) { \ 2126 | JSON_FAIL_MESSAGE(message); \ 2127 | } 2128 | 2129 | #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED 2130 | 2131 | // ////////////////////////////////////////////////////////////////////// 2132 | // End of content of file: include/json/assertions.h 2133 | // ////////////////////////////////////////////////////////////////////// 2134 | 2135 | 2136 | 2137 | 2138 | 2139 | #endif //ifndef JSON_AMALGATED_H_INCLUDED 2140 | -------------------------------------------------------------------------------- /inc/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef CMQ_SDK_INCLUDE_QUEUE_H__ 2 | #define CMQ_SDK_INCLUDE_QUEUE_H__ 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "cmq_client.h" 10 | #include "Message.h" 11 | using std::string; 12 | using std::map; 13 | using std::vector; 14 | 15 | 16 | namespace cmq 17 | { 18 | const unsigned int DEFAULT_POLLING_WAIT_SECONDS = 0; //缺省消息接收长轮询等待时间 19 | const unsigned int DEFAULT_VISIBILITY_TIMEOUT = 30; //缺省消息可见性超时 20 | const unsigned int DEFAULT_MAX_MSG_SIZE = 65536; //缺省消息最大长度 21 | const unsigned int DEFAULT_MSG_RETENTION_SECONDS = 345600; //缺省消息保留周期 22 | class QueueMeta 23 | { 24 | public: 25 | QueueMeta(); 26 | //最大堆积消息数 27 | int maxMsgHeapNum; 28 | //消息接收长轮询等待时间 29 | int pollingWaitSeconds; 30 | //消息可见性超时 31 | int visibilityTimeout; 32 | //消息最大长度 33 | int maxMsgSize; 34 | //消息保留周期 35 | int msgRetentionSeconds; 36 | //队列创建时间 37 | int createTime; 38 | //队列属性最后修改时间 39 | int lastModifyTime; 40 | //队列处于Active状态的消息总数 41 | int activeMsgNum; 42 | //队列处于Inactive状态的消息总数 43 | int inactiveMsgNum; 44 | // 队列设定的最大回溯时间 45 | unsigned int rewindSeconds ; 46 | // 已删除,但是还在回溯保留时间内的消息数量 47 | int rewindmsgNum ; 48 | // 消息最小未消费时间,单位为秒 49 | int minMsgTime; 50 | // 延时消息数量 51 | int delayMsgNum; 52 | }; 53 | 54 | /**Queue类对象非线程安全,如果多线程使用,需要每个线程单独初始化Queue类对象*/ 55 | class Queue 56 | { 57 | public: 58 | Queue(const string &queueName, const CMQClient &client); 59 | 60 | /** 61 | * @brief 设置队列属性 62 | * @param meta 队列属性参数 63 | **/ 64 | void setQueueAttributes(const QueueMeta &meta); 65 | /** 66 | * @brief 获取队列属性 67 | * @param meta 返回的队列属性参数 68 | **/ 69 | void getQueueAttributes(QueueMeta &meta); 70 | /** 71 | * @brief 发送消息 72 | * @param msgBody 消息内容 73 | * @param msgId 服务器返回的消息唯一标识 74 | **/ 75 | void sendMessage(const string &msgBody, string &msgId, const unsigned int delayTime =0); 76 | /** 77 | * @brief 批量发送消息 78 | * @param vtMsgBody 消息列表 79 | * @param vtMsgId 服务器返回的消息唯一标识列表 80 | **/ 81 | void batchSendMessage(const vector &vtMsgBody, vector &vtMsgId, const unsigned int delayTime = 0 ); 82 | /** 83 | * @brief 获取消息 84 | * @param pollingWaitSeconds 请求最长的Polling等待时间 85 | * @param msg 服务器返回消息 86 | **/ 87 | void receiveMessage(int pollingWaitSeconds, Message &msg); 88 | /** 89 | * @brief 批量获取消息 90 | * @param numOfMsg 准备获取消息数 91 | * @param pollingWaitSeconds 请求最长的Polling等待时间 92 | * @param msgList 服务器返回消息列表 93 | **/ 94 | void batchReceiveMessage(int numOfMsg, int pollingWaitSeconds, vector &msgList); 95 | /** 96 | * @brief 删除消息 97 | * @param receiptHandle 消息句柄,获取消息时由服务器返回 98 | **/ 99 | void deleteMessage(const string &receiptHandle); 100 | /** 101 | * @brief 批量删除消息 102 | * @param receiptHandle 消息句柄列表,获取消息时由服务器返回 103 | **/ 104 | void batchDeleteMessage(const vector &vtReceiptHandle); 105 | 106 | /* 107 | * 108 | * @brief rewind queue 109 | * 110 | */ 111 | void rewindQueue(const unsigned long); 112 | protected: 113 | string queueName; 114 | CMQClient client; 115 | }; 116 | 117 | } 118 | 119 | #endif 120 | 121 | -------------------------------------------------------------------------------- /sample/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(CMAKE_BUILD_TYPE "Debug") 2 | 3 | 4 | INCLUDE(CheckCXXCompilerFlag) 5 | CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) 6 | 7 | 8 | if(COMPILER_SUPPORTS_CXX11) 9 | add_definitions("-std=c++11") 10 | endif() 11 | 12 | 13 | 14 | SET(CMAKE_CXX_FLAGES_DEBUG "${CMAKE_CXX_FLAGES} -O0 -pipe -Wall -fno-strict-aliasing -D_GNU_SOURCE -D_REENTRANT -fPIC -g -ggdb") 15 | SET(CMAKE_CXX_FLAGES_RELEASE "${CMAKE_CXX_FLAGES} -O0 -pipe -Wall -fno-strict-aliasing -D_GNU_SOURCE -D_REENTRANT -fPIC ") 16 | FIND_PACKAGE(CURL REQUIRED) 17 | FIND_PACKAGE(OpenSSL REQUIRED) 18 | INCLUDE_DIRECTORIES(../inc/) 19 | INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR}) 20 | INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) 21 | LINK_DIRECTORIES(../src/) 22 | SET(LIBRARY ${OPENSSL_LIBRARIES} ${CURL_LIBRARIES} libCMQ.so) 23 | SET(SRC_TOPIC cmq_sample_topic.cpp) 24 | SET(SRC_QUEUE cmq_sample_queue.cpp) 25 | ADD_EXECUTABLE(cmq_sample_topic ${SRC_TOPIC}) 26 | TARGET_LINK_LIBRARIES(cmq_sample_topic ${LIBRARY}) 27 | ADD_EXECUTABLE(cmq_sample_queue ${SRC_QUEUE}) 28 | TARGET_LINK_LIBRARIES(cmq_sample_queue ${LIBRARY}) 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /sample/cmq_sample_queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "cmq_exception.h" 5 | #include "account.h" 6 | #include "queue.h" 7 | 8 | using namespace std; 9 | using namespace cmq; 10 | 11 | int main() 12 | { 13 | //从腾讯云官网查询的云API密钥信息 14 | string secretId=""; 15 | string secretKey=""; 16 | string endpoint="http://cmq-queue-sh.api.qcloud.com"; 17 | 18 | try 19 | { 20 | Account account(endpoint, secretId, secretKey); 21 | 22 | //创建队列 23 | cout<<"---------------create queue ...---------------"< vtQueue; 43 | int totalCount = 0; 44 | account.listQueue(totalCount,vtQueue); 45 | cout<<"totalCount:"< vtMsgId; 109 | vector vtMsgBody; 110 | string msgBody = "hello world,this is cmq sdk for c++ 1"; 111 | vtMsgBody.push_back(msgBody); 112 | msgBody = "hello world,this is cmq sdk for c++ 2"; 113 | vtMsgBody.push_back(msgBody); 114 | msgBody = "hello world,this is cmq sdk for c++ 3"; 115 | vtMsgBody.push_back(msgBody); 116 | queue.batchSendMessage(vtMsgBody,vtMsgId); 117 | for(size_t i=0;i vtReceiptHandle; //保存服务器返回的消息句柄,用于删除消息 124 | cout<<"---------------batch recv message ...---------------"< msgList; 126 | queue.batchReceiveMessage(10,10,msgList); 127 | cout<<"recv msg count:"< 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace cmq; 13 | 14 | int main() 15 | { 16 | //从腾讯云官网查询的云API密钥信息 17 | string secretId= ""; 18 | string secretKey= ""; 19 | string endpoint= ""; 20 | 21 | try 22 | { 23 | // create account and topic 24 | cout<<"Init account"< vbindKing; 44 | vector vflterTag; 45 | account.createSubscribe(topicName,subscriptionName,endpoint,protocol,vbindKing,vflterTag); 46 | cout<<"create subscription"< vmsg; 58 | for (unsigned int i = 0; i < 5; ++i) 59 | { 60 | string ss; 61 | ss = "this is a test message "; 62 | vmsg.push_back(ss); 63 | } 64 | vector vmsgId; 65 | topic.BatchPublishMessage(vmsg, vmsgId); 66 | cout<< "batch publish message "< > vTopic; 70 | int total(0); 71 | account.listTopic(total, vTopic); 72 | Subscription sub = account.getSubscription(topicName, subscriptionName); 73 | 74 | //set and get subscription meta 75 | SubscriptionMeta subMeta; 76 | sub.getSubscriptionAttributes(subMeta); 77 | cout<<"get sub meta"< > vsublist; 82 | topic.listSubscription(total, vsublist); 83 | account.deleteSubscribe(topicName,subscriptionName); 84 | account.deleteTopic(topicName); 85 | cout<<"delete sub and topic"< param; 23 | 24 | param["topicName"] = this->m_topicName; 25 | param["subscriptionName"] = this->m_subscriptionName; 26 | 27 | string result = this->m_client.call("ClearSubscriptionFilterTags", param); 28 | 29 | Json::Reader reader; 30 | Json::Value value; 31 | if (!reader.parse(result, value)) 32 | { 33 | throw CMQClientException("Json parse failed"); 34 | return; 35 | } 36 | 37 | int code = value["code"].asInt(); 38 | if (code != 0) 39 | { 40 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 41 | return; 42 | } 43 | } 44 | 45 | 46 | void Subscription::getSubscriptionAttributes(SubscriptionMeta & meta) 47 | { 48 | map param; 49 | 50 | param["topicName"] = this->m_topicName; 51 | param["subscriptionName"] = this->m_subscriptionName; 52 | 53 | string result = this->m_client.call("GetSubscriptionAttributes", param); 54 | 55 | Json::Reader reader; 56 | Json::Value value; 57 | if (!reader.parse(result, value)) 58 | { 59 | throw CMQClientException("Json parse failed"); 60 | return; 61 | } 62 | 63 | int code = value["code"].asInt(); 64 | if (code != 0) 65 | { 66 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 67 | return; 68 | } 69 | 70 | meta.TopicOwner = value["topicOwner"].asString(); 71 | meta.endpoint = value["endpoint"].asString(); 72 | meta.protocol = value["protocal"].asString(); 73 | meta.notifyStrategy = value["notifyStrategy"].asString(); 74 | meta.notifyContentFormat = value["notifyContentFormat"].asString(); 75 | meta.CreateTime = value["createTime"].asInt(); 76 | meta.LastModifyTime = value["lastModifyTime"].asInt(); 77 | meta.msgCount = value["msgCount"].asInt(); 78 | 79 | meta.filterTag.clear(); 80 | Json::Value FilterTagList = value["filterTag"]; 81 | for (unsigned int i = 0; i < FilterTagList.size(); ++i) 82 | { 83 | meta.filterTag.push_back(FilterTagList[i].asString()); 84 | } 85 | 86 | //clear bindingKey 87 | meta.bindingKey.clear(); 88 | Json::Value bindingKeyList = value["bindingKey"]; 89 | for(unsigned int i = 0 ; i < bindingKeyList.size(); ++i) 90 | { 91 | meta.bindingKey.push_back(bindingKeyList[i].asString()); 92 | } 93 | } 94 | 95 | void Subscription::setSubscriptionAttributes(const SubscriptionMeta meta) 96 | { 97 | map param; 98 | param["topicName"] = this->m_topicName; 99 | param["subscriptionName"] = this->m_subscriptionName; 100 | param["notifyStrategy"] = meta.notifyStrategy; 101 | param["notifyContentFormat"] = meta.notifyContentFormat; 102 | 103 | #if __cplusplus < 201103L 104 | if(! meta.bindingKey.empty()) 105 | { 106 | for(unsigned int i= 0 ; i < meta.bindingKey.size() ; ++i) 107 | 108 | { 109 | string k = "bindingKey." + cmq::int2str(i+1); 110 | param[k]=meta.bindingKey[i]; 111 | } 112 | } 113 | #else 114 | if (! meta.bindingKey.empty()) 115 | { 116 | unsigned int n = 1; 117 | for(auto tag : meta.bindingKey) 118 | { 119 | string k = "bindingKey." + cmq::int2str(n); 120 | param[k] = tag; 121 | ++n; 122 | } 123 | } 124 | 125 | #endif 126 | 127 | #if __cplusplus < 201103L 128 | if(! meta.filterTag.empty()) 129 | { 130 | for(unsigned int i= 0 ; i < meta.filterTag.size() ; ++i) 131 | 132 | { 133 | string k = "filterTag." + cmq::int2str(i+1); 134 | param[k]=meta.filterTag[i]; 135 | } 136 | } 137 | #else 138 | if (! meta.filterTag.empty()) 139 | { 140 | unsigned int n = 1; 141 | for(auto tag : meta.filterTag) 142 | { 143 | string k = "filterTag." + cmq::int2str(n); 144 | param[k] = tag; 145 | ++n; 146 | } 147 | } 148 | 149 | #endif 150 | 151 | string result = this->m_client.call("SetSubscriptionAttributes", param); 152 | Json::Reader reader; 153 | Json::Value value; 154 | if (!reader.parse(result, value)) 155 | { 156 | throw CMQClientException("Json parse failed"); 157 | return; 158 | } 159 | 160 | int code = value["code"].asInt(); 161 | if (code != 0) 162 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/SubscriptionMeta.cpp: -------------------------------------------------------------------------------- 1 | #include "SubscriptionMeta.h" 2 | 3 | using namespace cmq; 4 | 5 | SubscriptionMeta::SubscriptionMeta() 6 | { 7 | } 8 | 9 | 10 | SubscriptionMeta::~SubscriptionMeta() 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/Topic.cpp: -------------------------------------------------------------------------------- 1 | #include "TopicMeta.h" 2 | #include "Topic.h" 3 | #include "./json/json.h" 4 | #include "cmq_exception.h" 5 | #include "cmq_tool.h" 6 | 7 | using namespace cmq; 8 | 9 | 10 | namespace cmq 11 | { 12 | 13 | Topic::Topic(const string &topicName, const CMQClient &client): 14 | topicName(topicName), 15 | client(client) 16 | { 17 | } 18 | Topic::~Topic() 19 | { 20 | 21 | } 22 | void Topic::SetTopicAttributes(const unsigned int maxMsgSize) 23 | { 24 | if ( maxMsgSize > 65536) 25 | { 26 | throw CMQClientException("invalid argument maxMsgSize > 65536"); 27 | return ; 28 | } 29 | map param; 30 | param["topicName"] = this->topicName; 31 | param["maxMsgSize"] = cmq::int2str(maxMsgSize); 32 | 33 | string result = this->client.call("SetTopicAttributes", param); 34 | Json::Reader reader; 35 | Json::Value value; 36 | if(!reader.parse(result, value)) 37 | throw CMQClientException("Json parse failed"); 38 | 39 | int code = value["code"].asInt(); 40 | if(code != 0) 41 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 42 | } 43 | 44 | void Topic::GetTopicAttributes(TopicMeta &meta) 45 | { 46 | map param; 47 | param["topicName"] = this->topicName; 48 | string result = this->client.call("GetTopicAttributes", param); 49 | Json::Reader reader; 50 | Json::Value value; 51 | if(!reader.parse(result, value)) 52 | { 53 | throw CMQClientException("Json parse failed"); 54 | return; 55 | } 56 | 57 | int code = value["code"].asInt(); 58 | if(code != 0) 59 | { 60 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 61 | return; 62 | } 63 | 64 | meta.m_msgCount=value["msgCount"].asInt(); 65 | meta.m_maxMsgSize=value["maxMsgSize"].asInt(); 66 | meta.m_msgRetentionSeconds=value["msgRetentionSeconds"].asInt(); 67 | meta.m_loggingEnabled=value["LoggingEnabled"].asInt(); 68 | meta.m_createTime=value["createTime"].asInt(); 69 | meta.m_lastModifyTime=value["lastModifyTime"].asInt(); 70 | meta.m_filterType = value["filterType"].asInt(); 71 | } 72 | 73 | void Topic::PublishMessage(const string &msgBody, string &msgId, const string & routingKey) 74 | { 75 | vector vmsgTag; 76 | PublishMessage(msgBody, msgId, vmsgTag, routingKey); 77 | } 78 | 79 | void Topic::PublishMessage(const string &msgBody, string &msgId, const vector & msgTag, const string & routingKey) 80 | { 81 | map param; 82 | param["topicName"] = this->topicName; 83 | param["msgBody"] = msgBody; 84 | param["routingKey"] = routingKey; 85 | if(! msgTag.empty()) 86 | { 87 | for (unsigned int i = 0 ; i < msgTag.size() ; ++i) 88 | { 89 | string k = "msgTag." + cmq::int2str(i+1); 90 | param[k] = msgTag[i]; 91 | } 92 | } 93 | string result = this->client.call("PublishMessage", param); 94 | 95 | Json::Reader reader; 96 | Json::Value value; 97 | if(!reader.parse(result, value)) 98 | { 99 | throw CMQClientException("Json parse failed"); 100 | return; 101 | } 102 | 103 | int code = value["code"].asInt(); 104 | if(code != 0) 105 | { 106 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 107 | return; 108 | } 109 | 110 | msgId = value["msgId"].asString(); 111 | } 112 | 113 | void Topic::BatchPublishMessage(const vector &vtMsgBody, vector & vtMsgId,const string & routingKey) 114 | { 115 | 116 | vector vtMsgTag; 117 | BatchPublishMessage(vtMsgBody, vtMsgId, vtMsgTag, routingKey); 118 | 119 | } 120 | 121 | void Topic::BatchPublishMessage(const vector &vtMsgBody, vector &vtMsgId, const vector & vmsgTag, const string & routingKey) 122 | { 123 | if(vtMsgBody.empty()) 124 | return; 125 | map param; 126 | param["topicName"] = this->topicName; 127 | param["routingKey"] = routingKey; 128 | for(size_t i=0;iclient.call("BatchPublishMessage", param); 142 | Json::Reader reader; 143 | Json::Value value; 144 | if(!reader.parse(result, value)) 145 | { 146 | throw CMQClientException("Json parse failed"); 147 | return; 148 | } 149 | 150 | int code = value["code"].asInt(); 151 | if(code != 0) 152 | { 153 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 154 | return; 155 | } 156 | 157 | vtMsgId.clear(); 158 | Json::Value valMsgList = value["msgList"]; 159 | for(unsigned int i=0;i > & vSubscriptionList, const string & searchWord, const int offset, const int limit ) 168 | { 169 | map param; 170 | param["topicName"] = this->topicName; 171 | if (searchWord != "") 172 | param["searchWord"] = searchWord; 173 | if (offset >= 0) 174 | param["offset"] = cmq::int2str(offset); 175 | if (limit > 0) 176 | param["limit"] = cmq::int2str(limit); 177 | 178 | string result = this->client.call("ListSubscriptionByTopic", param); 179 | Json::Reader reader; 180 | Json::Value value; 181 | if (!reader.parse(result, value)) 182 | { 183 | throw CMQClientException("Json parse failed"); 184 | return; 185 | } 186 | 187 | int code = value["code"].asInt(); 188 | if (code != 0) 189 | { 190 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 191 | return; 192 | } 193 | 194 | totalCount = value["totalCount"].asInt(); 195 | Json::Value valSubList = value["subscriptionList"]; 196 | // clean vector 197 | vSubscriptionList.clear(); 198 | for (unsigned int i = 0; i < valSubList.size(); i++) 199 | { 200 | vector Subscribe; 201 | Subscribe.push_back(valSubList[i]["subscriptionName"].asString()); 202 | Subscribe.push_back(valSubList[i]["subscriptionId"].asString()); 203 | Subscribe.push_back(valSubList[i]["endpoint"].asString()); 204 | Subscribe.push_back(valSubList[i]["protocol"].asString()); 205 | vSubscriptionList.push_back(Subscribe); 206 | } 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /src/TopicMeta.cpp: -------------------------------------------------------------------------------- 1 | #include "TopicMeta.h" 2 | 3 | using namespace cmq; 4 | 5 | 6 | TopicMeta::TopicMeta(): 7 | m_filterType(1) 8 | { 9 | 10 | } 11 | 12 | 13 | TopicMeta::~TopicMeta() 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /src/account.cpp: -------------------------------------------------------------------------------- 1 | // for pair 2 | #include 3 | #include 4 | #include 5 | #include "account.h" 6 | #include "cmq_exception.h" 7 | #include "json/json.h" 8 | #include "cmq_tool.h" 9 | 10 | #include 11 | using namespace cmq; 12 | using namespace std; 13 | using std::pair; 14 | using std::map; 15 | using std::stringstream; 16 | using std::string; 17 | using std::vector; 18 | namespace cmq { 19 | 20 | 21 | Account::Account(const string &endpoint, const string &secretId, const string &secretKey, const string &method) 22 | :client(endpoint, "/v2/index.php", secretId, secretKey, method) 23 | { 24 | } 25 | 26 | Account::Account(const string &endpoint, const string &secretId, const string &secretKey, const string &path, const string &method) 27 | : client(endpoint, path, secretId, secretKey, method) 28 | { 29 | } 30 | 31 | void Account::createQueue(const string &queueName, const QueueMeta &meta) 32 | { 33 | map param; 34 | if (queueName == "") 35 | { 36 | throw CMQClientException("Invalid parameter:queueName is empty"); 37 | return; 38 | } 39 | else 40 | param["queueName"] = queueName; 41 | 42 | if (meta.maxMsgHeapNum > 0) 43 | param["maxMsgHeapNum"] = cmq::int2str(meta.maxMsgHeapNum); 44 | if (meta.pollingWaitSeconds > 0) 45 | param["pollingWaitSeconds"] = cmq::int2str(meta.pollingWaitSeconds); 46 | if (meta.visibilityTimeout > 0) 47 | param["visibilityTimeout"] = cmq::int2str(meta.visibilityTimeout); 48 | if (meta.maxMsgSize > 0) 49 | param["maxMsgSize"] = cmq::int2str(meta.maxMsgSize); 50 | if (meta.msgRetentionSeconds > 0) 51 | param["msgRetentionSeconds"] = cmq::int2str(meta.msgRetentionSeconds); 52 | 53 | param["rewindSeconds"] = cmq::int2str(meta.rewindSeconds); 54 | string result = this->client.call("CreateQueue", param); 55 | Json::Reader reader; 56 | Json::Value value; 57 | if (!reader.parse(result, value)) 58 | throw CMQClientException("Json parse failed"); 59 | 60 | int code = value["code"].asInt(); 61 | if (code != 0) 62 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 63 | } 64 | 65 | void Account::deleteQueue(const string &queueName) 66 | { 67 | map param; 68 | param["queueName"] = queueName; 69 | string result = this->client.call("DeleteQueue", param); 70 | Json::Reader reader; 71 | Json::Value value; 72 | if (!reader.parse(result, value)) 73 | throw CMQClientException("Json parse failed"); 74 | 75 | int code = value["code"].asInt(); 76 | if (code != 0) 77 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 78 | } 79 | 80 | void Account::listQueue(int &totalCount, vector &vtQueue, const string &searchWord, int offset, int limit) 81 | { 82 | map param; 83 | if (searchWord != "") 84 | param["searchWord"] = searchWord; 85 | if (offset >= 0) 86 | param["offset"] = cmq::int2str(offset); 87 | if (limit > 0) 88 | param["limit"] = cmq::int2str(limit); 89 | 90 | string result = this->client.call("ListQueue", param); 91 | Json::Reader reader; 92 | Json::Value value; 93 | if (!reader.parse(result, value)) 94 | { 95 | throw CMQClientException("Json parse failed"); 96 | return; 97 | } 98 | 99 | int code = value["code"].asInt(); 100 | if (code != 0) 101 | { 102 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 103 | return; 104 | } 105 | 106 | totalCount = value["totalCount"].asInt(); 107 | Json::Value valQueueList = value["queueList"]; 108 | for (unsigned int i = 0; i < valQueueList.size(); i++) 109 | { 110 | vtQueue.push_back(valQueueList[i]["queueName"].asString()); 111 | } 112 | } 113 | 114 | Queue Account::getQueue(const string &queueName) 115 | { 116 | return Queue(queueName, this->client); 117 | } 118 | 119 | 120 | void Account::createTopic(const string & topicName, const int maxMsgSize, const int filterType,const int LoggingEnabled) 121 | { 122 | map param; 123 | // not empty 124 | if (topicName == "") 125 | { 126 | throw CMQClientException("Invalid parameter:topicName is empty"); 127 | return; 128 | } 129 | // size < 64 130 | if (topicName.size() > 64){ 131 | throw CMQClientException("Invalid parameter:topicName length > 64"); 132 | return; 133 | } 134 | 135 | if (maxMsgSize < 1 || maxMsgSize > 65536) 136 | { 137 | throw CMQClientException("Invalid parameter:maxMsgSize Invalid"); 138 | return; 139 | } 140 | 141 | param["topicName"] = topicName; 142 | param["filterType"] = cmq::int2str(filterType); 143 | if (maxMsgSize > 0) 144 | param["maxMsgSize"] = cmq::int2str(maxMsgSize); 145 | 146 | string result = this->client.call("CreateTopic", param); 147 | Json::Reader reader; 148 | Json::Value value; 149 | if (!reader.parse(result, value)) 150 | throw CMQClientException("Json parse failed"); 151 | 152 | int code = value["code"].asInt(); 153 | 154 | if (code != 0) 155 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 156 | } 157 | 158 | void Account::deleteTopic(const string & topicName) 159 | { 160 | map param; 161 | param["topicName"] = topicName; 162 | 163 | string result = this->client.call("DeleteTopic", param); 164 | Json::Reader reader; 165 | Json::Value value; 166 | if (!reader.parse(result, value)) 167 | throw CMQClientException("Json parse failed"); 168 | 169 | int code = value["code"].asInt(); 170 | 171 | if (code != 0) 172 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 173 | } 174 | 175 | Topic Account::getTopic(const string &topicName) 176 | { 177 | return Topic(topicName, this->client); 178 | } 179 | 180 | void Account::listTopic(int & totalCount, vector< pair< string, string> > & vTopicList, const string & searchWord, const int offset, const int limit) 181 | { 182 | map param; 183 | if (searchWord != "") 184 | param["searchWord"] = searchWord; 185 | if (offset >= 0) 186 | param["offset"] = cmq::int2str(offset); 187 | if (limit > 0) 188 | param["limit"] = cmq::int2str(limit); 189 | 190 | string result = this->client.call("ListTopic", param); 191 | Json::Reader reader; 192 | Json::Value value; 193 | if (!reader.parse(result, value)) 194 | { 195 | throw CMQClientException("Json parse failed"); 196 | return; 197 | } 198 | 199 | int code = value["code"].asInt(); 200 | if (code != 0) 201 | { 202 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 203 | return; 204 | } 205 | 206 | totalCount = value["totalCount"].asInt(); 207 | Json::Value valTopicList = value["topicList"]; 208 | // clean vector 209 | vTopicList.clear(); 210 | for (unsigned int i = 0; i < valTopicList.size(); i++) 211 | { 212 | pair TopicItem(valTopicList[i]["topicId"].asString(), valTopicList[i]["topicName"].asString()); 213 | vTopicList.push_back(TopicItem); 214 | } 215 | } 216 | 217 | void Account::createSubscribe(const string & topicName, 218 | const string & subscriptionName, const string & endpoint, 219 | const string & protocol, const vector & bindingKey,const vector & vFilterTag, 220 | const string & notifyStrategy, const string & notifyContentFormat) 221 | { 222 | 223 | if (topicName.empty() || topicName.size() == 0) 224 | { 225 | throw CMQClientException("Invalid parameter:topicName is empty"); 226 | return; 227 | } 228 | if (subscriptionName.empty() || subscriptionName.size() == 0) 229 | { 230 | throw CMQClientException("Invalid parameter:topicName is empty"); 231 | return; 232 | } 233 | if (endpoint.empty() || endpoint.size() == 0) 234 | { 235 | throw CMQClientException("Invalia parameter:endpoint is empty"); 236 | return; 237 | } 238 | if (protocol.empty() || protocol.size() == 0) 239 | { 240 | throw CMQClientException("Invalia parameter:protocol is empty"); 241 | return; 242 | } 243 | 244 | map param; 245 | param["topicName"] = topicName; 246 | param["subscriptionName"] = subscriptionName; 247 | param["endpoint"] = endpoint; 248 | param["protocol"] = protocol; 249 | param["notifyStrategy"] = notifyStrategy; 250 | param["notifyContentFormat"] = notifyContentFormat; 251 | for(unsigned i = 0 ; i < bindingKey.size() ; ++i) 252 | { 253 | stringstream ss; 254 | ss<client.call("Subscribe", param); 267 | Json::Reader reader; 268 | Json::Value value; 269 | if (!reader.parse(result, value)) 270 | throw CMQClientException("Json parse failed"); 271 | 272 | int code = value["code"].asInt(); 273 | if (code != 0) 274 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 275 | 276 | 277 | } 278 | 279 | void Account::deleteSubscribe(const string & topicName, const string & subscriptionName) 280 | { 281 | if (topicName.empty() || topicName.size() == 0) 282 | { 283 | throw CMQClientException("Invalid parameter:topicName is empty"); 284 | return; 285 | } 286 | 287 | if (subscriptionName.empty() || subscriptionName.size() == 0) 288 | { 289 | throw CMQClientException("Invalid parameter:subscriptionName is empty"); 290 | return; 291 | } 292 | 293 | map param; 294 | param["topicName"] = topicName; 295 | param["subscriptionName"] = subscriptionName; 296 | 297 | string result = this->client.call("Unsubscribe", param); 298 | Json::Reader reader; 299 | Json::Value value; 300 | if (!reader.parse(result, value)) 301 | throw CMQClientException("Json parse failed"); 302 | 303 | int code = value["code"].asInt(); 304 | if (code != 0) 305 | throw CMQServerException(code, value["message"].asString(), value["requestId"].asString()); 306 | 307 | } 308 | 309 | 310 | Subscription Account::getSubscription(const string &topicName, const string & subscriptionName) 311 | { 312 | 313 | return Subscription(topicName, subscriptionName, this->client); 314 | } 315 | 316 | } 317 | -------------------------------------------------------------------------------- /src/cmq_client.cpp: -------------------------------------------------------------------------------- 1 | #include "cmq_client.h" 2 | #include "cmq_tool.h" 3 | #include "cmq_http.h" 4 | #include "cmq_exception.h" 5 | #include 6 | 7 | using namespace cmq; 8 | 9 | static const char __version__[] = "CMQ SDK VERSION:1.0.3,DATE:" __DATE__; 10 | const char* const CURRENT_VERSION = "SDK_CPP_1.3"; 11 | 12 | CMQClient::CMQClient() 13 | { 14 | } 15 | 16 | CMQClient::CMQClient(const string &endpoint, const string &path, const string &secretId, const string &secretKey, const string &method) 17 | { 18 | this->endpoint = endpoint; 19 | this->path = path; 20 | this->secretId = secretId; 21 | this->secretKey = secretKey; 22 | this->method = method; 23 | } 24 | 25 | string CMQClient::call(const string &action, map ¶m) 26 | { 27 | srand(time(NULL)); 28 | 29 | param["Action"] = action; 30 | param["Nonce"] = cmq::int2str(rand()); 31 | param["SecretId"] = this->secretId; 32 | param["Timestamp"] = cmq::int2str(time(NULL)); 33 | param["RequestClient"] = CURRENT_VERSION; 34 | if (this->signMethod =="sha1") 35 | param["SignatureMethod"] = "HmacSHA1"; 36 | else 37 | param["SignatureMethod"] ="HmacSHA256"; 38 | string prefix = this->endpoint.substr(0,5); 39 | 40 | string host=""; 41 | if(prefix=="https") 42 | host = this->endpoint.substr(8); 43 | else 44 | host = this->endpoint.substr(7); 45 | string src = ""; 46 | src += this->method + host + this->path + "?"; 47 | map::iterator it = param.begin(); 48 | bool flag = false; 49 | for(; it != param.end(); it++) 50 | { 51 | if(flag) 52 | src += "&"; 53 | string s = it->first; 54 | std::replace(s.begin(),s.end(),'_','.'); 55 | //src += it->first+ "=" + it->second; 56 | src += s + "=" + it->second; 57 | flag = true; 58 | } 59 | 60 | param["Signature"] = cmq::sign(src, this->secretKey,this->signMethod); 61 | 62 | string url = ""; 63 | string req = ""; 64 | string rsp = ""; 65 | if(this->method == "GET") 66 | { 67 | url = this->endpoint + this->path + "?"; 68 | map::iterator it = param.begin(); 69 | bool flag = false; 70 | for(; it != param.end(); it++) 71 | { 72 | if(flag) 73 | url += "&"; 74 | url += it->first+ "=" + cmq::url_encode(it->second); 75 | flag = true; 76 | } 77 | if(url.length() > 2048) 78 | { 79 | throw CMQClientException("URL length is larger than 2K when use GET method"); 80 | return rsp; 81 | } 82 | } 83 | else 84 | { 85 | url = this->endpoint + this->path; 86 | map::iterator it = param.begin(); 87 | bool flag = false; 88 | for(; it != param.end(); it++) 89 | { 90 | if(flag) 91 | req += "&"; 92 | req += it->first+ "=" + cmq::url_encode(it->second); 93 | flag = true; 94 | } 95 | } 96 | int timeout(0); 97 | if(param.find("UserpollingWaitSeconds") != param.end()) 98 | timeout=atoi(param["UserpollingWaitSeconds"].c_str()); 99 | //cout<<"url:"<method, url, req, rsp,timeout); 101 | //cout<<"rsp:"<msg.c_str(); 8 | } -------------------------------------------------------------------------------- /src/cmq_http.cpp: -------------------------------------------------------------------------------- 1 | #include "cmq_http.h" 2 | #include "cmq_exception.h" 3 | #include "cmq_tool.h" 4 | #include 5 | #include 6 | 7 | using namespace cmq; 8 | 9 | class CMQHttpGlobalInit 10 | { 11 | public: 12 | CMQHttpGlobalInit() 13 | { 14 | curl_global_init(CURL_GLOBAL_ALL); 15 | } 16 | ~CMQHttpGlobalInit() 17 | { 18 | curl_global_cleanup(); 19 | } 20 | }; 21 | 22 | static CMQHttpGlobalInit __cmq_http_global_init__; 23 | 24 | 25 | static size_t http_write_callback(void *buffer, size_t size, size_t nmemb, void *userp) 26 | { 27 | size_t n = size * nmemb; 28 | string *rsp = (string*)userp; 29 | 30 | rsp->append((const char*)buffer, n); 31 | 32 | return n; 33 | } 34 | 35 | CMQHttp::CMQHttp(int timeout,bool isKeepAlive) 36 | { 37 | this->timeout = timeout; 38 | this->isKeepAlive = isKeepAlive; 39 | this->curl = NULL; 40 | } 41 | 42 | CMQHttp::~CMQHttp() 43 | { 44 | if(this->curl != NULL) 45 | { 46 | curl_easy_cleanup(this->curl); 47 | this->curl = NULL; 48 | } 49 | } 50 | 51 | void CMQHttp::request(const string &method, const string &url, const string &req, string &rsp,const int timeout) 52 | { 53 | if(!this->isKeepAlive) 54 | { 55 | this->curl = curl_easy_init(); 56 | } 57 | else 58 | { 59 | if(this->curl == NULL) 60 | this->curl = curl_easy_init(); 61 | } 62 | 63 | if(this->curl == NULL) 64 | { 65 | throw CMQClientException("Curl init failed"); 66 | return; 67 | } 68 | 69 | curl_easy_setopt(this->curl, CURLOPT_URL, url.c_str()); 70 | curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, this->timeout); 71 | curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, 1); 72 | curl_easy_setopt(this->curl, CURLOPT_TIMEOUT, this->timeout+timeout); 73 | curl_slist* header = NULL; 74 | if(this->isKeepAlive) 75 | { 76 | header = curl_slist_append(header, "Connection: keep-alive"); 77 | curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, header); 78 | } 79 | 80 | curl_easy_setopt(this->curl, CURLOPT_ENCODING, "UTF-8"); 81 | 82 | if(method == "POST") 83 | { 84 | curl_easy_setopt(this->curl, CURLOPT_POST, 1L); 85 | curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, req.c_str()); 86 | curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE,req.size()); 87 | } 88 | 89 | curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, http_write_callback); 90 | curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&rsp); 91 | 92 | CURLcode ret = curl_easy_perform(this->curl); 93 | if(this->isKeepAlive) 94 | curl_slist_free_all(header); 95 | 96 | if(ret != CURLE_OK) 97 | { 98 | string error = "Curl Send Request Fail, code:" + cmq::int2str(ret) + " ,error:" + curl_easy_strerror(ret); 99 | throw CMQClientException(error); 100 | return; 101 | } 102 | 103 | long status = 0; 104 | curl_easy_getinfo(this->curl, CURLINFO_RESPONSE_CODE, &status); 105 | if(status != 200) 106 | throw CMQServerNetworkException((int)status); 107 | } 108 | -------------------------------------------------------------------------------- /src/cmq_tool.cpp: -------------------------------------------------------------------------------- 1 | //for hmacsha1 or hmacsha256 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include "cmq_tool.h" 9 | 10 | 11 | using std::string; 12 | using std::stringstream; 13 | 14 | namespace cmq 15 | { 16 | 17 | string int2str(int n) 18 | { 19 | stringstream ss; 20 | ss << n; 21 | return ss.str(); 22 | } 23 | 24 | string url_encode(const string &src) 25 | { 26 | static const char *hex = "0123456789ABCDEF"; 27 | 28 | string dst; 29 | for (size_t i = 0; i < src.size(); i++) 30 | { 31 | byte c = (byte)src[i]; 32 | if (isalnum(c) || (c == '-') || (c == '_') || (c == '.') || (c == '!') || 33 | (c == '~') || (c == '*') || (c == '\'') || (c == '(') || 34 | (c == ')') || (c == '/')) 35 | { 36 | dst += c; 37 | } 38 | else if (c == ' ') 39 | { 40 | dst += "%20"; 41 | } 42 | else 43 | { 44 | dst += '%'; 45 | dst += hex[c >> 4]; 46 | dst += hex[c & 15]; 47 | } 48 | } 49 | 50 | return dst; 51 | } 52 | 53 | string base64_encode(const byte *src, int length) 54 | { 55 | static const char *b64c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 56 | 57 | string dst; 58 | const byte *p = src; 59 | 60 | while (length) 61 | { 62 | dst += b64c[*p >> 2]; 63 | if (!--length) 64 | { 65 | dst += b64c[(*p & 0x3) << 4]; 66 | dst += "=="; 67 | break; 68 | } 69 | dst += b64c[((*p & 0x3) << 4) | (*(p + 1) >> 4)]; 70 | p++; 71 | if (!--length) 72 | { 73 | dst += b64c[(*p & 0xF) << 2]; 74 | dst += '='; 75 | break; 76 | } 77 | dst += b64c[((*p & 0xF) << 2) | (*(p + 1) >> 6)]; 78 | p++; 79 | 80 | dst += b64c[*p & 0x3F]; 81 | p++, length--; 82 | } 83 | 84 | return dst; 85 | } 86 | 87 | 88 | string sign(const string &src, const string &key,const string &method) 89 | { 90 | unsigned char result[32]; 91 | unsigned int len=0; 92 | HMAC_CTX ctx; 93 | HMAC_CTX_init(&ctx); 94 | 95 | if(method == "sha1") 96 | { 97 | HMAC_Init_ex(&ctx,key.c_str(),key.size(),EVP_sha1(),NULL); 98 | len=20; 99 | } 100 | else 101 | { 102 | HMAC_Init_ex(&ctx,key.c_str(),key.size(),EVP_sha256(),NULL); 103 | len=32; 104 | } 105 | HMAC_Update(&ctx, (unsigned char*)src.c_str(), src.size()); 106 | HMAC_Final(&ctx, result, &len); 107 | HMAC_CTX_cleanup(&ctx); 108 | 109 | return cmq::base64_encode(result,len); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/queue.cpp: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | #include "cmq_exception.h" 3 | #include "json/json.h" 4 | #include "cmq_tool.h" 5 | 6 | using namespace cmq; 7 | 8 | QueueMeta::QueueMeta() 9 | :maxMsgHeapNum(-1) 10 | ,pollingWaitSeconds(DEFAULT_POLLING_WAIT_SECONDS) 11 | ,visibilityTimeout(DEFAULT_VISIBILITY_TIMEOUT) 12 | ,maxMsgSize(DEFAULT_MAX_MSG_SIZE) 13 | ,msgRetentionSeconds(DEFAULT_MSG_RETENTION_SECONDS) 14 | ,createTime(-1),lastModifyTime(-1),activeMsgNum(-1),inactiveMsgNum(-1) 15 | { 16 | } 17 | 18 | 19 | Queue::Queue(const string &queueName, const CMQClient &client): 20 | queueName(queueName), 21 | client(client) 22 | { 23 | } 24 | 25 | void Queue::setQueueAttributes(const QueueMeta &meta) 26 | { 27 | map param; 28 | param["queueName"] = this->queueName; 29 | 30 | if(meta.maxMsgHeapNum > 0) 31 | param["maxMsgHeapNum"] = cmq::int2str(meta.maxMsgHeapNum); 32 | if(meta.pollingWaitSeconds > 0) 33 | param["pollingWaitSeconds"] = cmq::int2str(meta.pollingWaitSeconds); 34 | if(meta.visibilityTimeout > 0) 35 | param["visibilityTimeout"] = cmq::int2str(meta.visibilityTimeout); 36 | if(meta.maxMsgSize > 0) 37 | param["maxMsgSize"] = cmq::int2str(meta.maxMsgSize); 38 | if(meta.msgRetentionSeconds > 0) 39 | param["msgRetentionSeconds"] = cmq::int2str(meta.msgRetentionSeconds); 40 | param["rewindSeconds"] = cmq::int2str(meta.rewindSeconds); 41 | string result = this->client.call("SetQueueAttributes", param); 42 | Json::Reader reader; 43 | Json::Value value; 44 | if(!reader.parse(result, value)) 45 | throw CMQClientException("Json parse failed"); 46 | 47 | int code = value["code"].asInt(); 48 | if(code != 0) 49 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 50 | } 51 | 52 | void Queue::getQueueAttributes(QueueMeta &meta) 53 | { 54 | map param; 55 | param["queueName"] = this->queueName; 56 | string result = this->client.call("GetQueueAttributes", param); 57 | Json::Reader reader; 58 | Json::Value value; 59 | if(!reader.parse(result, value)) 60 | { 61 | throw CMQClientException("Json parse failed"); 62 | return; 63 | } 64 | 65 | int code = value["code"].asInt(); 66 | if(code != 0) 67 | { 68 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 69 | return; 70 | } 71 | 72 | meta.maxMsgHeapNum = value["maxMsgHeapNum"].asInt(); 73 | meta.pollingWaitSeconds = value["pollingWaitSeconds"].asInt(); 74 | meta.visibilityTimeout = value["visibilityTimeout"].asInt(); 75 | meta.maxMsgSize = value["maxMsgSize"].asInt(); 76 | meta.msgRetentionSeconds = value["msgRetentionSeconds"].asInt(); 77 | meta.createTime = value["createTime"].asInt(); 78 | meta.lastModifyTime = value["lastModifyTime"].asInt(); 79 | meta.activeMsgNum = value["activeMsgNum"].asInt(); 80 | meta.inactiveMsgNum = value["inactiveMsgNum"].asInt(); 81 | meta.rewindSeconds = value["rewindSeconds"].asInt(); 82 | meta.rewindmsgNum = value["rewindmsgNum"].asInt(); 83 | meta.minMsgTime = value["minMsgTime"].asInt(); 84 | meta.delayMsgNum = value["delayMsgNum"].asInt(); 85 | 86 | } 87 | 88 | void Queue::sendMessage(const string &msgBody, string &msgId, const unsigned int delayTime) 89 | { 90 | map param; 91 | param["queueName"] = this->queueName; 92 | param["msgBody"] = msgBody; 93 | param["delaySeconds"] = cmq::int2str(delayTime); 94 | string result = this->client.call("SendMessage", param); 95 | 96 | Json::Reader reader; 97 | Json::Value value; 98 | if(!reader.parse(result, value)) 99 | { 100 | throw CMQClientException("Json parse failed"); 101 | return; 102 | } 103 | 104 | int code = value["code"].asInt(); 105 | if(code != 0) 106 | { 107 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 108 | return; 109 | } 110 | 111 | msgId = value["msgId"].asString(); 112 | } 113 | 114 | void Queue::batchSendMessage(const vector &vtMsgBody, vector &vtMsgId, const unsigned int delayTime) 115 | { 116 | if(vtMsgBody.empty()) 117 | return; 118 | map param; 119 | param["queueName"] = this->queueName; 120 | for(size_t i=0;iclient.call("BatchSendMessage", param); 127 | Json::Reader reader; 128 | Json::Value value; 129 | if(!reader.parse(result, value)) 130 | { 131 | throw CMQClientException("Json parse failed"); 132 | return; 133 | } 134 | 135 | int code = value["code"].asInt(); 136 | if(code != 0) 137 | { 138 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 139 | return; 140 | } 141 | 142 | Json::Value valMsgList = value["msgList"]; 143 | for(unsigned int i=0;i param; 153 | param["queueName"] = this->queueName; 154 | if(pollingWaitSeconds > 0 ) 155 | { 156 | param["UserpollingWaitSeconds"] = cmq::int2str(pollingWaitSeconds); 157 | param["pollingWaitSeconds"] = cmq::int2str(pollingWaitSeconds); 158 | } 159 | else 160 | { 161 | param["UserpollingWaitSeconds"] = cmq::int2str(30); 162 | } 163 | string result = this->client.call("ReceiveMessage", param); 164 | 165 | Json::Reader reader; 166 | Json::Value value; 167 | if(!reader.parse(result, value)) 168 | { 169 | throw CMQClientException("Json parse failed"); 170 | return; 171 | } 172 | 173 | int code = value["code"].asInt(); 174 | if(code != 0) 175 | { 176 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 177 | return; 178 | } 179 | 180 | msg.msgId = value["msgId"].asString(); 181 | msg.receiptHandle = value["receiptHandle"].asString(); 182 | msg.msgBody = value["msgBody"].asString(); 183 | msg.enqueueTime = value["enqueueTime"].asUInt64(); 184 | msg.nextVisibleTime = value["nextVisibleTime"].asUInt64(); 185 | msg.firstDequeueTime = value["firstDequeueTime"].asUInt64(); 186 | msg.dequeueCount = value["dequeueCount"].asInt(); 187 | } 188 | 189 | void Queue::batchReceiveMessage(int numOfMsg, int pollingWaitSeconds, vector &msgList) 190 | { 191 | map param; 192 | param["queueName"] = this->queueName; 193 | param["numOfMsg"] = cmq::int2str(numOfMsg); 194 | if(pollingWaitSeconds > 0) 195 | { 196 | param["UserpollingWaitSeconds"] = cmq::int2str(pollingWaitSeconds); 197 | param["pollingWaitSeconds"] = cmq::int2str(pollingWaitSeconds); 198 | 199 | } 200 | else 201 | { 202 | param["UserpollingWaitSeconds"] = cmq::int2str(30); 203 | } 204 | string result = this->client.call("BatchReceiveMessage", param); 205 | Json::Reader reader; 206 | Json::Value value; 207 | if(!reader.parse(result, value)) 208 | { 209 | throw CMQClientException("Json parse failed"); 210 | return; 211 | } 212 | 213 | int code = value["code"].asInt(); 214 | if(code != 0) 215 | { 216 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 217 | return; 218 | } 219 | 220 | Json::Value valMsgList = value["msgInfoList"]; 221 | for(unsigned int i=0;i param; 240 | param["queueName"] = this->queueName; 241 | param["receiptHandle"] = receiptHandle; 242 | string result = this->client.call("DeleteMessage", param); 243 | Json::Reader reader; 244 | Json::Value value; 245 | if(!reader.parse(result, value)) 246 | throw CMQClientException("Json parse failed"); 247 | 248 | int code = value["code"].asInt(); 249 | if(code != 0) 250 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 251 | } 252 | 253 | void Queue::batchDeleteMessage(const vector &vtReceiptHandle) 254 | { 255 | if(vtReceiptHandle.empty()) 256 | return; 257 | map param; 258 | param["queueName"] = this->queueName; 259 | for(size_t i=0;iclient.call("BatchDeleteMessage", param); 265 | Json::Reader reader; 266 | Json::Value value; 267 | if(!reader.parse(result, value)) 268 | throw CMQClientException("Json parse failed"); 269 | 270 | int code = value["code"].asInt(); 271 | if(code != 0) 272 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 273 | } 274 | 275 | void Queue::rewindQueue(const unsigned long backTrackingTime) 276 | { 277 | 278 | map param; 279 | param["queueName"] = this->queueName; 280 | param["startConsumeTime"] = backTrackingTime; 281 | string result = this->client.call("RewindQueue", param); 282 | Json::Reader reader; 283 | Json::Value value; 284 | if(!reader.parse(result, value)) 285 | throw CMQClientException("Json parse failed"); 286 | 287 | int code = value["code"].asInt(); 288 | if(code != 0) 289 | throw CMQServerException(code,value["message"].asString(),value["requestId"].asString()); 290 | } 291 | --------------------------------------------------------------------------------