├── README.md ├── global.cpp ├── global.h ├── json ├── json-forwards.h └── json.h ├── jsoncpp.cpp ├── main.cpp ├── makefile ├── spider.cpp └── spider.h /README.md: -------------------------------------------------------------------------------- 1 | ##某个社交app爬虫 2 | 3 | 主要用libcurl实现的一个爬虫,写这个主要因为好玩,绝不是程序员的闷骚。。哈哈哈 4 | 5 | 抓取某个社交app用户(只抓取女性用户。。。)的头像图片、基本信息、相册、动态(包括动态文本和图片)。 6 | 7 | 多线程,线程之间无锁(只在获取id的时候使用了__sync_fetch_and_add),抓取速度快,基本满带宽下载 8 | 9 | 10 | ##INSTALL: 11 | ```Bash 12 | ./makefile 13 | ``` 14 | 15 | ##Usage: 16 | ```Bash 17 | spider -t thread_count -p save path -i start_id 18 | ``` 19 | 20 |

thread_count:线程数,可以看情况多开点

21 |

save:保存的路径

22 |

start_id:抓取的用户起始id,不会重复抓取已经抓取的用户

23 | 24 | 注:我已经很久没更新,这个目标app的有些api可能已经更改,所以可能会失效。但是代码可以参考。 25 | 26 | 27 | ##我的邮箱: 28 | 29 | 646452100@qq.com 30 | -------------------------------------------------------------------------------- /global.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "curl/curl.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | Global* Global::m_instance = NULL; 13 | __thread char Global::m_log_buff[MSG_BUFF] = {}; 14 | 15 | Global::Global() 16 | { 17 | m_init = false; 18 | m_path[0] = '\0'; 19 | m_pic_path[0] = '\0'; 20 | m_json_path[0] = '\0'; 21 | m_terminated = false; 22 | m_spider_cnt = 0; 23 | } 24 | 25 | Global::~Global() 26 | { 27 | if (m_init) 28 | { 29 | curl_global_cleanup(); 30 | } 31 | 32 | on_end(); 33 | } 34 | 35 | bool Global::check_path(const char* path) 36 | { 37 | if (!opendir(path)) 38 | { 39 | if (errno != ENOENT) 40 | { 41 | fprintf(stderr, "open path %s error.%s. \n", path, strerror(errno)); 42 | return false; 43 | } 44 | 45 | if (mkdir(path, 0777) != 0) 46 | { 47 | fprintf(stderr, "create path %s error.%s. \n", path, strerror(errno)); 48 | return false; 49 | } 50 | } 51 | 52 | return true; 53 | } 54 | 55 | bool Global::set_path(const char* path) 56 | { 57 | if (!path || path[0] == '\0') return false; 58 | 59 | strncpy(m_path, path, MAX_PATH); 60 | 61 | int len = strlen(m_path); 62 | if (m_path[len - 1] == '/') 63 | { 64 | m_path[len - 1] = '\0'; 65 | } 66 | 67 | strncpy(m_pic_path, path, MAX_PATH); 68 | strcat(m_pic_path, "/pics"); 69 | strncpy(m_json_path, path, MAX_PATH); 70 | strcat(m_json_path, "/jsons"); 71 | 72 | if (!check_path(path)) return false; 73 | if (!check_path(m_pic_path)) return false; 74 | if (!check_path(m_json_path)) return false; 75 | 76 | return true; 77 | } 78 | 79 | Global* Global::get_instance() 80 | { 81 | if (!m_instance) 82 | m_instance = new Global(); 83 | 84 | return m_instance; 85 | } 86 | 87 | bool Global::init_global_env() 88 | { 89 | if (m_init) return false; 90 | 91 | CURLcode ret = curl_global_init(CURL_GLOBAL_ALL); 92 | if (CURLE_OK != ret) 93 | { 94 | return false; 95 | } 96 | 97 | m_init = true; 98 | return true; 99 | } 100 | 101 | void Global::out_log(const char* sFormat, ...) 102 | { 103 | time_t tNow = time(NULL); 104 | struct tm ptm = {}; 105 | localtime_r(&tNow, &ptm); 106 | strftime(m_log_buff, MSG_BUFF, "[%Y-%m-%d %H:%M:%S]", &ptm); 107 | 108 | int len = strlen(m_log_buff); 109 | sprintf(m_log_buff + len, "Thread[%lu]->", pthread_self()); 110 | len = strlen(m_log_buff); 111 | 112 | va_list ap; 113 | va_start(ap, sFormat); 114 | vsnprintf(m_log_buff + len, MSG_BUFF - len, sFormat, ap); 115 | va_end(ap); 116 | m_log_buff[MSG_BUFF - 1] = '\0'; 117 | 118 | fprintf(stderr, m_log_buff); 119 | } 120 | 121 | void Global::on_end() 122 | { 123 | char path[MAX_PATH]; 124 | strcpy(path, m_path); 125 | strcat(path, "/spider_log.txt"); 126 | 127 | FILE *fptr = fopen(path, "a"); 128 | if (!fptr) return; 129 | 130 | time_t tNow = time(NULL); 131 | struct tm ptm = {}; 132 | localtime_r(&tNow, &ptm); 133 | strftime(m_log_buff, MSG_BUFF, "[%Y-%m-%d %H:%M:%S]", &ptm); 134 | int len = strlen(m_log_buff); 135 | 136 | sprintf(m_log_buff + len, "Start-->[%d], End-->[%d], Available-->[%d].\r\n", m_log_start, m_target_start - 1, m_spider_cnt); 137 | 138 | fprintf(fptr, m_log_buff); 139 | 140 | fclose(fptr); 141 | fprintf(stderr, m_log_buff); 142 | } 143 | -------------------------------------------------------------------------------- /global.h: -------------------------------------------------------------------------------- 1 | #ifndef __GLOBAL_H__ 2 | #define __GLOBAL_H__ 3 | 4 | #include 5 | 6 | #define MAX_PATH 256 7 | 8 | class Global 9 | { 10 | public: 11 | static const int MSG_BUFF = 256; 12 | 13 | virtual ~Global(); 14 | 15 | static Global* get_instance(); 16 | 17 | bool set_path(const char* path); 18 | 19 | const char* get_path() 20 | { 21 | return m_path; 22 | } 23 | 24 | const char* get_pic_path() 25 | { 26 | return m_pic_path; 27 | } 28 | 29 | const char* get_json_path() 30 | { 31 | return m_json_path; 32 | } 33 | 34 | bool init_global_env(); 35 | 36 | void set_target_start(int target_id) 37 | { 38 | m_target_start = target_id; 39 | m_log_start = target_id; 40 | } 41 | 42 | int get_target_id() 43 | { 44 | return __sync_fetch_and_add(&m_target_start, 1); 45 | } 46 | 47 | void add_spider_cnt() 48 | { 49 | __sync_fetch_and_add(&m_spider_cnt, 1); 50 | } 51 | 52 | bool is_terminated() 53 | { 54 | return m_terminated; 55 | } 56 | 57 | void set_terminated() 58 | { 59 | m_terminated = true; 60 | } 61 | 62 | void out_log(const char* sFormat, ...); 63 | 64 | void on_end(); 65 | 66 | private: 67 | Global(); 68 | bool check_path(const char* path); 69 | 70 | private: 71 | char m_path[MAX_PATH]; 72 | char m_pic_path[MAX_PATH]; 73 | char m_json_path[MAX_PATH]; 74 | 75 | bool m_init; 76 | static Global* m_instance; 77 | int m_target_start; 78 | int m_log_start; 79 | int m_spider_cnt; //爬下来的id个数 80 | bool m_terminated; 81 | 82 | static __thread char m_log_buff[MSG_BUFF]; 83 | }; 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /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 | 94 | /// If defined, indicates that json library is embedded in CppTL library. 95 | //# define JSON_IN_CPPTL 1 96 | 97 | /// If defined, indicates that json may leverage CppTL library 98 | //# define JSON_USE_CPPTL 1 99 | /// If defined, indicates that cpptl vector based map should be used instead of 100 | /// std::map 101 | /// as Value container. 102 | //# define JSON_USE_CPPTL_SMALLMAP 1 103 | 104 | // If non-zero, the library uses exceptions to report bad input instead of C 105 | // assertion macros. The default is to use exceptions. 106 | #ifndef JSON_USE_EXCEPTION 107 | #define JSON_USE_EXCEPTION 1 108 | #endif 109 | 110 | /// If defined, indicates that the source file is amalgated 111 | /// to prevent private header inclusion. 112 | /// Remarks: it is automatically defined in the generated amalgated header. 113 | // #define JSON_IS_AMALGAMATION 114 | 115 | #ifdef JSON_IN_CPPTL 116 | #include 117 | #ifndef JSON_USE_CPPTL 118 | #define JSON_USE_CPPTL 1 119 | #endif 120 | #endif 121 | 122 | #ifdef JSON_IN_CPPTL 123 | #define JSON_API CPPTL_API 124 | #elif defined(JSON_DLL_BUILD) 125 | #if defined(_MSC_VER) 126 | #define JSON_API __declspec(dllexport) 127 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 128 | #endif // if defined(_MSC_VER) 129 | #elif defined(JSON_DLL) 130 | #if defined(_MSC_VER) 131 | #define JSON_API __declspec(dllimport) 132 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 133 | #endif // if defined(_MSC_VER) 134 | #endif // ifdef JSON_IN_CPPTL 135 | #if !defined(JSON_API) 136 | #define JSON_API 137 | #endif 138 | 139 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 140 | // integer 141 | // Storages, and 64 bits integer support is disabled. 142 | // #define JSON_NO_INT64 1 143 | 144 | #if defined(_MSC_VER) // MSVC 145 | # if _MSC_VER <= 1200 // MSVC 6 146 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 147 | // (no conversion from unsigned __int64). 148 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 149 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 150 | // characters in the debug information) 151 | // All projects I've ever seen with VS6 were using this globally (not bothering 152 | // with pragma push/pop). 153 | # pragma warning(disable : 4786) 154 | # endif // MSVC 6 155 | 156 | # if _MSC_VER >= 1500 // MSVC 2008 157 | /// Indicates that the following function is deprecated. 158 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 159 | # endif 160 | 161 | #endif // defined(_MSC_VER) 162 | 163 | 164 | #ifndef JSON_HAS_RVALUE_REFERENCES 165 | 166 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 167 | #define JSON_HAS_RVALUE_REFERENCES 1 168 | #endif // MSVC >= 2010 169 | 170 | #ifdef __clang__ 171 | #if __has_feature(cxx_rvalue_references) 172 | #define JSON_HAS_RVALUE_REFERENCES 1 173 | #endif // has_feature 174 | 175 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 176 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) 177 | #define JSON_HAS_RVALUE_REFERENCES 1 178 | #endif // GXX_EXPERIMENTAL 179 | 180 | #endif // __clang__ || __GNUC__ 181 | 182 | #endif // not defined JSON_HAS_RVALUE_REFERENCES 183 | 184 | #ifndef JSON_HAS_RVALUE_REFERENCES 185 | #define JSON_HAS_RVALUE_REFERENCES 0 186 | #endif 187 | 188 | #ifdef __clang__ 189 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 190 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 191 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 192 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 193 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 194 | # endif // GNUC version 195 | #endif // __clang__ || __GNUC__ 196 | 197 | #if !defined(JSONCPP_DEPRECATED) 198 | #define JSONCPP_DEPRECATED(message) 199 | #endif // if !defined(JSONCPP_DEPRECATED) 200 | 201 | namespace Json { 202 | typedef int Int; 203 | typedef unsigned int UInt; 204 | #if defined(JSON_NO_INT64) 205 | typedef int LargestInt; 206 | typedef unsigned int LargestUInt; 207 | #undef JSON_HAS_INT64 208 | #else // if defined(JSON_NO_INT64) 209 | // For Microsoft Visual use specific types as long long is not supported 210 | #if defined(_MSC_VER) // Microsoft Visual Studio 211 | typedef __int64 Int64; 212 | typedef unsigned __int64 UInt64; 213 | #else // if defined(_MSC_VER) // Other platforms, use long long 214 | typedef long long int Int64; 215 | typedef unsigned long long int UInt64; 216 | #endif // if defined(_MSC_VER) 217 | typedef Int64 LargestInt; 218 | typedef UInt64 LargestUInt; 219 | #define JSON_HAS_INT64 220 | #endif // if defined(JSON_NO_INT64) 221 | } // end namespace Json 222 | 223 | #endif // JSON_CONFIG_H_INCLUDED 224 | 225 | // ////////////////////////////////////////////////////////////////////// 226 | // End of content of file: include/json/config.h 227 | // ////////////////////////////////////////////////////////////////////// 228 | 229 | 230 | 231 | 232 | 233 | 234 | // ////////////////////////////////////////////////////////////////////// 235 | // Beginning of content of file: include/json/forwards.h 236 | // ////////////////////////////////////////////////////////////////////// 237 | 238 | // Copyright 2007-2010 Baptiste Lepilleur 239 | // Distributed under MIT license, or public domain if desired and 240 | // recognized in your jurisdiction. 241 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 242 | 243 | #ifndef JSON_FORWARDS_H_INCLUDED 244 | #define JSON_FORWARDS_H_INCLUDED 245 | 246 | #if !defined(JSON_IS_AMALGAMATION) 247 | #include "config.h" 248 | #endif // if !defined(JSON_IS_AMALGAMATION) 249 | 250 | namespace Json { 251 | 252 | // writer.h 253 | class FastWriter; 254 | class StyledWriter; 255 | 256 | // reader.h 257 | class Reader; 258 | 259 | // features.h 260 | class Features; 261 | 262 | // value.h 263 | typedef unsigned int ArrayIndex; 264 | class StaticString; 265 | class Path; 266 | class PathArgument; 267 | class Value; 268 | class ValueIteratorBase; 269 | class ValueIterator; 270 | class ValueConstIterator; 271 | 272 | } // namespace Json 273 | 274 | #endif // JSON_FORWARDS_H_INCLUDED 275 | 276 | // ////////////////////////////////////////////////////////////////////// 277 | // End of content of file: include/json/forwards.h 278 | // ////////////////////////////////////////////////////////////////////// 279 | 280 | 281 | 282 | 283 | 284 | #endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED 285 | -------------------------------------------------------------------------------- /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.6.5" 91 | # define JSONCPP_VERSION_MAJOR 1 92 | # define JSONCPP_VERSION_MINOR 6 93 | # define JSONCPP_VERSION_PATCH 5 94 | # define JSONCPP_VERSION_QUALIFIER 95 | # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) 96 | 97 | #endif // JSON_VERSION_H_INCLUDED 98 | 99 | // ////////////////////////////////////////////////////////////////////// 100 | // End of content of file: include/json/version.h 101 | // ////////////////////////////////////////////////////////////////////// 102 | 103 | 104 | 105 | 106 | 107 | 108 | // ////////////////////////////////////////////////////////////////////// 109 | // Beginning of content of file: include/json/config.h 110 | // ////////////////////////////////////////////////////////////////////// 111 | 112 | // Copyright 2007-2010 Baptiste Lepilleur 113 | // Distributed under MIT license, or public domain if desired and 114 | // recognized in your jurisdiction. 115 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 116 | 117 | #ifndef JSON_CONFIG_H_INCLUDED 118 | #define JSON_CONFIG_H_INCLUDED 119 | 120 | /// If defined, indicates that json library is embedded in CppTL library. 121 | //# define JSON_IN_CPPTL 1 122 | 123 | /// If defined, indicates that json may leverage CppTL library 124 | //# define JSON_USE_CPPTL 1 125 | /// If defined, indicates that cpptl vector based map should be used instead of 126 | /// std::map 127 | /// as Value container. 128 | //# define JSON_USE_CPPTL_SMALLMAP 1 129 | 130 | // If non-zero, the library uses exceptions to report bad input instead of C 131 | // assertion macros. The default is to use exceptions. 132 | #ifndef JSON_USE_EXCEPTION 133 | #define JSON_USE_EXCEPTION 1 134 | #endif 135 | 136 | /// If defined, indicates that the source file is amalgated 137 | /// to prevent private header inclusion. 138 | /// Remarks: it is automatically defined in the generated amalgated header. 139 | // #define JSON_IS_AMALGAMATION 140 | 141 | #ifdef JSON_IN_CPPTL 142 | #include 143 | #ifndef JSON_USE_CPPTL 144 | #define JSON_USE_CPPTL 1 145 | #endif 146 | #endif 147 | 148 | #ifdef JSON_IN_CPPTL 149 | #define JSON_API CPPTL_API 150 | #elif defined(JSON_DLL_BUILD) 151 | #if defined(_MSC_VER) 152 | #define JSON_API __declspec(dllexport) 153 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 154 | #endif // if defined(_MSC_VER) 155 | #elif defined(JSON_DLL) 156 | #if defined(_MSC_VER) 157 | #define JSON_API __declspec(dllimport) 158 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 159 | #endif // if defined(_MSC_VER) 160 | #endif // ifdef JSON_IN_CPPTL 161 | #if !defined(JSON_API) 162 | #define JSON_API 163 | #endif 164 | 165 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 166 | // integer 167 | // Storages, and 64 bits integer support is disabled. 168 | // #define JSON_NO_INT64 1 169 | 170 | #if defined(_MSC_VER) // MSVC 171 | # if _MSC_VER <= 1200 // MSVC 6 172 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 173 | // (no conversion from unsigned __int64). 174 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1 175 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 176 | // characters in the debug information) 177 | // All projects I've ever seen with VS6 were using this globally (not bothering 178 | // with pragma push/pop). 179 | # pragma warning(disable : 4786) 180 | # endif // MSVC 6 181 | 182 | # if _MSC_VER >= 1500 // MSVC 2008 183 | /// Indicates that the following function is deprecated. 184 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 185 | # endif 186 | 187 | #endif // defined(_MSC_VER) 188 | 189 | 190 | #ifndef JSON_HAS_RVALUE_REFERENCES 191 | 192 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 193 | #define JSON_HAS_RVALUE_REFERENCES 1 194 | #endif // MSVC >= 2010 195 | 196 | #ifdef __clang__ 197 | #if __has_feature(cxx_rvalue_references) 198 | #define JSON_HAS_RVALUE_REFERENCES 1 199 | #endif // has_feature 200 | 201 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 202 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) 203 | #define JSON_HAS_RVALUE_REFERENCES 1 204 | #endif // GXX_EXPERIMENTAL 205 | 206 | #endif // __clang__ || __GNUC__ 207 | 208 | #endif // not defined JSON_HAS_RVALUE_REFERENCES 209 | 210 | #ifndef JSON_HAS_RVALUE_REFERENCES 211 | #define JSON_HAS_RVALUE_REFERENCES 0 212 | #endif 213 | 214 | #ifdef __clang__ 215 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) 216 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 217 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 218 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 219 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 220 | # endif // GNUC version 221 | #endif // __clang__ || __GNUC__ 222 | 223 | #if !defined(JSONCPP_DEPRECATED) 224 | #define JSONCPP_DEPRECATED(message) 225 | #endif // if !defined(JSONCPP_DEPRECATED) 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 | } // end namespace Json 248 | 249 | #endif // JSON_CONFIG_H_INCLUDED 250 | 251 | // ////////////////////////////////////////////////////////////////////// 252 | // End of content of file: include/json/config.h 253 | // ////////////////////////////////////////////////////////////////////// 254 | 255 | 256 | 257 | 258 | 259 | 260 | // ////////////////////////////////////////////////////////////////////// 261 | // Beginning of content of file: include/json/forwards.h 262 | // ////////////////////////////////////////////////////////////////////// 263 | 264 | // Copyright 2007-2010 Baptiste Lepilleur 265 | // Distributed under MIT license, or public domain if desired and 266 | // recognized in your jurisdiction. 267 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 268 | 269 | #ifndef JSON_FORWARDS_H_INCLUDED 270 | #define JSON_FORWARDS_H_INCLUDED 271 | 272 | #if !defined(JSON_IS_AMALGAMATION) 273 | #include "config.h" 274 | #endif // if !defined(JSON_IS_AMALGAMATION) 275 | 276 | namespace Json { 277 | 278 | // writer.h 279 | class FastWriter; 280 | class StyledWriter; 281 | 282 | // reader.h 283 | class Reader; 284 | 285 | // features.h 286 | class Features; 287 | 288 | // value.h 289 | typedef unsigned int ArrayIndex; 290 | class StaticString; 291 | class Path; 292 | class PathArgument; 293 | class Value; 294 | class ValueIteratorBase; 295 | class ValueIterator; 296 | class ValueConstIterator; 297 | 298 | } // namespace Json 299 | 300 | #endif // JSON_FORWARDS_H_INCLUDED 301 | 302 | // ////////////////////////////////////////////////////////////////////// 303 | // End of content of file: include/json/forwards.h 304 | // ////////////////////////////////////////////////////////////////////// 305 | 306 | 307 | 308 | 309 | 310 | 311 | // ////////////////////////////////////////////////////////////////////// 312 | // Beginning of content of file: include/json/features.h 313 | // ////////////////////////////////////////////////////////////////////// 314 | 315 | // Copyright 2007-2010 Baptiste Lepilleur 316 | // Distributed under MIT license, or public domain if desired and 317 | // recognized in your jurisdiction. 318 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 319 | 320 | #ifndef CPPTL_JSON_FEATURES_H_INCLUDED 321 | #define CPPTL_JSON_FEATURES_H_INCLUDED 322 | 323 | #if !defined(JSON_IS_AMALGAMATION) 324 | #include "forwards.h" 325 | #endif // if !defined(JSON_IS_AMALGAMATION) 326 | 327 | namespace Json { 328 | 329 | /** \brief Configuration passed to reader and writer. 330 | * This configuration object can be used to force the Reader or Writer 331 | * to behave in a standard conforming way. 332 | */ 333 | class JSON_API Features { 334 | public: 335 | /** \brief A configuration that allows all features and assumes all strings 336 | * are UTF-8. 337 | * - C & C++ comments are allowed 338 | * - Root object can be any JSON value 339 | * - Assumes Value strings are encoded in UTF-8 340 | */ 341 | static Features all(); 342 | 343 | /** \brief A configuration that is strictly compatible with the JSON 344 | * specification. 345 | * - Comments are forbidden. 346 | * - Root object must be either an array or an object value. 347 | * - Assumes Value strings are encoded in UTF-8 348 | */ 349 | static Features strictMode(); 350 | 351 | /** \brief Initialize the configuration like JsonConfig::allFeatures; 352 | */ 353 | Features(); 354 | 355 | /// \c true if comments are allowed. Default: \c true. 356 | bool allowComments_; 357 | 358 | /// \c true if root must be either an array or an object value. Default: \c 359 | /// false. 360 | bool strictRoot_; 361 | 362 | /// \c true if dropped null placeholders are allowed. Default: \c false. 363 | bool allowDroppedNullPlaceholders_; 364 | 365 | /// \c true if numeric object key are allowed. Default: \c false. 366 | bool allowNumericKeys_; 367 | }; 368 | 369 | } // namespace Json 370 | 371 | #endif // CPPTL_JSON_FEATURES_H_INCLUDED 372 | 373 | // ////////////////////////////////////////////////////////////////////// 374 | // End of content of file: include/json/features.h 375 | // ////////////////////////////////////////////////////////////////////// 376 | 377 | 378 | 379 | 380 | 381 | 382 | // ////////////////////////////////////////////////////////////////////// 383 | // Beginning of content of file: include/json/value.h 384 | // ////////////////////////////////////////////////////////////////////// 385 | 386 | // Copyright 2007-2010 Baptiste Lepilleur 387 | // Distributed under MIT license, or public domain if desired and 388 | // recognized in your jurisdiction. 389 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 390 | 391 | #ifndef CPPTL_JSON_H_INCLUDED 392 | #define CPPTL_JSON_H_INCLUDED 393 | 394 | #if !defined(JSON_IS_AMALGAMATION) 395 | #include "forwards.h" 396 | #endif // if !defined(JSON_IS_AMALGAMATION) 397 | #include 398 | #include 399 | #include 400 | 401 | #ifndef JSON_USE_CPPTL_SMALLMAP 402 | #include 403 | #else 404 | #include 405 | #endif 406 | #ifdef JSON_USE_CPPTL 407 | #include 408 | #endif 409 | 410 | // Disable warning C4251: : needs to have dll-interface to 411 | // be used by... 412 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 413 | #pragma warning(push) 414 | #pragma warning(disable : 4251) 415 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 416 | 417 | /** \brief JSON (JavaScript Object Notation). 418 | */ 419 | namespace Json { 420 | 421 | /** Base class for all exceptions we throw. 422 | * 423 | * We use nothing but these internally. Of course, STL can throw others. 424 | */ 425 | class JSON_API Exception : public std::exception { 426 | public: 427 | Exception(std::string const& msg); 428 | ~Exception() throw() override; 429 | char const* what() const throw() override; 430 | protected: 431 | std::string msg_; 432 | }; 433 | 434 | /** Exceptions which the user cannot easily avoid. 435 | * 436 | * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input 437 | * 438 | * \remark derived from Json::Exception 439 | */ 440 | class JSON_API RuntimeError : public Exception { 441 | public: 442 | RuntimeError(std::string const& msg); 443 | }; 444 | 445 | /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. 446 | * 447 | * These are precondition-violations (user bugs) and internal errors (our bugs). 448 | * 449 | * \remark derived from Json::Exception 450 | */ 451 | class JSON_API LogicError : public Exception { 452 | public: 453 | LogicError(std::string const& msg); 454 | }; 455 | 456 | /// used internally 457 | void throwRuntimeError(std::string const& msg); 458 | /// used internally 459 | void throwLogicError(std::string const& msg); 460 | 461 | /** \brief Type of the value held by a Value object. 462 | */ 463 | enum ValueType { 464 | nullValue = 0, ///< 'null' value 465 | intValue, ///< signed integer value 466 | uintValue, ///< unsigned integer value 467 | realValue, ///< double value 468 | stringValue, ///< UTF-8 string value 469 | booleanValue, ///< bool value 470 | arrayValue, ///< array value (ordered list) 471 | objectValue ///< object value (collection of name/value pairs). 472 | }; 473 | 474 | enum CommentPlacement { 475 | commentBefore = 0, ///< a comment placed on the line before a value 476 | commentAfterOnSameLine, ///< a comment just after a value on the same line 477 | commentAfter, ///< a comment on the line after a value (only make sense for 478 | /// root value) 479 | numberOfCommentPlacement 480 | }; 481 | 482 | //# ifdef JSON_USE_CPPTL 483 | // typedef CppTL::AnyEnumerator EnumMemberNames; 484 | // typedef CppTL::AnyEnumerator EnumValues; 485 | //# endif 486 | 487 | /** \brief Lightweight wrapper to tag static string. 488 | * 489 | * Value constructor and objectValue member assignement takes advantage of the 490 | * StaticString and avoid the cost of string duplication when storing the 491 | * string or the member name. 492 | * 493 | * Example of usage: 494 | * \code 495 | * Json::Value aValue( StaticString("some text") ); 496 | * Json::Value object; 497 | * static const StaticString code("code"); 498 | * object[code] = 1234; 499 | * \endcode 500 | */ 501 | class JSON_API StaticString { 502 | public: 503 | explicit StaticString(const char* czstring) : c_str_(czstring) {} 504 | 505 | operator const char*() const { return c_str_; } 506 | 507 | const char* c_str() const { return c_str_; } 508 | 509 | private: 510 | const char* c_str_; 511 | }; 512 | 513 | /** \brief Represents a JSON value. 514 | * 515 | * This class is a discriminated union wrapper that can represents a: 516 | * - signed integer [range: Value::minInt - Value::maxInt] 517 | * - unsigned integer (range: 0 - Value::maxUInt) 518 | * - double 519 | * - UTF-8 string 520 | * - boolean 521 | * - 'null' 522 | * - an ordered list of Value 523 | * - collection of name/value pairs (javascript object) 524 | * 525 | * The type of the held value is represented by a #ValueType and 526 | * can be obtained using type(). 527 | * 528 | * Values of an #objectValue or #arrayValue can be accessed using operator[]() 529 | * methods. 530 | * Non-const methods will automatically create the a #nullValue element 531 | * if it does not exist. 532 | * The sequence of an #arrayValue will be automatically resized and initialized 533 | * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. 534 | * 535 | * The get() methods can be used to obtain default value in the case the 536 | * required element does not exist. 537 | * 538 | * It is possible to iterate over the list of a #objectValue values using 539 | * the getMemberNames() method. 540 | * 541 | * \note #Value string-length fit in size_t, but keys must be < 2^30. 542 | * (The reason is an implementation detail.) A #CharReader will raise an 543 | * exception if a bound is exceeded to avoid security holes in your app, 544 | * but the Value API does *not* check bounds. That is the responsibility 545 | * of the caller. 546 | */ 547 | class JSON_API Value { 548 | friend class ValueIteratorBase; 549 | public: 550 | typedef std::vector Members; 551 | typedef ValueIterator iterator; 552 | typedef ValueConstIterator const_iterator; 553 | typedef Json::UInt UInt; 554 | typedef Json::Int Int; 555 | #if defined(JSON_HAS_INT64) 556 | typedef Json::UInt64 UInt64; 557 | typedef Json::Int64 Int64; 558 | #endif // defined(JSON_HAS_INT64) 559 | typedef Json::LargestInt LargestInt; 560 | typedef Json::LargestUInt LargestUInt; 561 | typedef Json::ArrayIndex ArrayIndex; 562 | 563 | static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). 564 | static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null 565 | /// Minimum signed integer value that can be stored in a Json::Value. 566 | static const LargestInt minLargestInt; 567 | /// Maximum signed integer value that can be stored in a Json::Value. 568 | static const LargestInt maxLargestInt; 569 | /// Maximum unsigned integer value that can be stored in a Json::Value. 570 | static const LargestUInt maxLargestUInt; 571 | 572 | /// Minimum signed int value that can be stored in a Json::Value. 573 | static const Int minInt; 574 | /// Maximum signed int value that can be stored in a Json::Value. 575 | static const Int maxInt; 576 | /// Maximum unsigned int value that can be stored in a Json::Value. 577 | static const UInt maxUInt; 578 | 579 | #if defined(JSON_HAS_INT64) 580 | /// Minimum signed 64 bits int value that can be stored in a Json::Value. 581 | static const Int64 minInt64; 582 | /// Maximum signed 64 bits int value that can be stored in a Json::Value. 583 | static const Int64 maxInt64; 584 | /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. 585 | static const UInt64 maxUInt64; 586 | #endif // defined(JSON_HAS_INT64) 587 | 588 | private: 589 | #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 590 | class CZString { 591 | public: 592 | enum DuplicationPolicy { 593 | noDuplication = 0, 594 | duplicate, 595 | duplicateOnCopy 596 | }; 597 | CZString(ArrayIndex index); 598 | CZString(char const* str, unsigned length, DuplicationPolicy allocate); 599 | CZString(CZString const& other); 600 | #if JSON_HAS_RVALUE_REFERENCES 601 | CZString(CZString&& other); 602 | #endif 603 | ~CZString(); 604 | CZString& operator=(CZString other); 605 | bool operator<(CZString const& other) const; 606 | bool operator==(CZString const& other) const; 607 | ArrayIndex index() const; 608 | //const char* c_str() const; ///< \deprecated 609 | char const* data() const; 610 | unsigned length() const; 611 | bool isStaticString() const; 612 | 613 | private: 614 | void swap(CZString& other); 615 | 616 | struct StringStorage { 617 | unsigned policy_: 2; 618 | unsigned length_: 30; // 1GB max 619 | }; 620 | 621 | char const* cstr_; // actually, a prefixed string, unless policy is noDup 622 | union { 623 | ArrayIndex index_; 624 | StringStorage storage_; 625 | }; 626 | }; 627 | 628 | public: 629 | #ifndef JSON_USE_CPPTL_SMALLMAP 630 | typedef std::map ObjectValues; 631 | #else 632 | typedef CppTL::SmallMap ObjectValues; 633 | #endif // ifndef JSON_USE_CPPTL_SMALLMAP 634 | #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 635 | 636 | public: 637 | /** \brief Create a default Value of the given type. 638 | 639 | This is a very useful constructor. 640 | To create an empty array, pass arrayValue. 641 | To create an empty object, pass objectValue. 642 | Another Value can then be set to this one by assignment. 643 | This is useful since clear() and resize() will not alter types. 644 | 645 | Examples: 646 | \code 647 | Json::Value null_value; // null 648 | Json::Value arr_value(Json::arrayValue); // [] 649 | Json::Value obj_value(Json::objectValue); // {} 650 | \endcode 651 | */ 652 | Value(ValueType type = nullValue); 653 | Value(Int value); 654 | Value(UInt value); 655 | #if defined(JSON_HAS_INT64) 656 | Value(Int64 value); 657 | Value(UInt64 value); 658 | #endif // if defined(JSON_HAS_INT64) 659 | Value(double value); 660 | Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) 661 | Value(const char* begin, const char* end); ///< Copy all, incl zeroes. 662 | /** \brief Constructs a value from a static string. 663 | 664 | * Like other value string constructor but do not duplicate the string for 665 | * internal storage. The given string must remain alive after the call to this 666 | * constructor. 667 | * \note This works only for null-terminated strings. (We cannot change the 668 | * size of this class, so we have nowhere to store the length, 669 | * which might be computed later for various operations.) 670 | * 671 | * Example of usage: 672 | * \code 673 | * static StaticString foo("some text"); 674 | * Json::Value aValue(foo); 675 | * \endcode 676 | */ 677 | Value(const StaticString& value); 678 | Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too. 679 | #ifdef JSON_USE_CPPTL 680 | Value(const CppTL::ConstString& value); 681 | #endif 682 | Value(bool value); 683 | /// Deep copy. 684 | Value(const Value& other); 685 | #if JSON_HAS_RVALUE_REFERENCES 686 | /// Move constructor 687 | Value(Value&& other); 688 | #endif 689 | ~Value(); 690 | 691 | /// Deep copy, then swap(other). 692 | /// \note Over-write existing comments. To preserve comments, use #swapPayload(). 693 | Value& operator=(Value other); 694 | /// Swap everything. 695 | void swap(Value& other); 696 | /// Swap values but leave comments and source offsets in place. 697 | void swapPayload(Value& other); 698 | 699 | ValueType type() const; 700 | 701 | /// Compare payload only, not comments etc. 702 | bool operator<(const Value& other) const; 703 | bool operator<=(const Value& other) const; 704 | bool operator>=(const Value& other) const; 705 | bool operator>(const Value& other) const; 706 | bool operator==(const Value& other) const; 707 | bool operator!=(const Value& other) const; 708 | int compare(const Value& other) const; 709 | 710 | const char* asCString() const; ///< Embedded zeroes could cause you trouble! 711 | std::string asString() const; ///< Embedded zeroes are possible. 712 | /** Get raw char* of string-value. 713 | * \return false if !string. (Seg-fault if str or end are NULL.) 714 | */ 715 | bool getString( 716 | char const** begin, char const** end) const; 717 | #ifdef JSON_USE_CPPTL 718 | CppTL::ConstString asConstString() const; 719 | #endif 720 | Int asInt() const; 721 | UInt asUInt() const; 722 | #if defined(JSON_HAS_INT64) 723 | Int64 asInt64() const; 724 | UInt64 asUInt64() const; 725 | #endif // if defined(JSON_HAS_INT64) 726 | LargestInt asLargestInt() const; 727 | LargestUInt asLargestUInt() const; 728 | float asFloat() const; 729 | double asDouble() const; 730 | bool asBool() const; 731 | 732 | bool isNull() const; 733 | bool isBool() const; 734 | bool isInt() const; 735 | bool isInt64() const; 736 | bool isUInt() const; 737 | bool isUInt64() const; 738 | bool isIntegral() const; 739 | bool isDouble() const; 740 | bool isNumeric() const; 741 | bool isString() const; 742 | bool isArray() const; 743 | bool isObject() const; 744 | 745 | bool isConvertibleTo(ValueType other) const; 746 | 747 | /// Number of values in array or object 748 | ArrayIndex size() const; 749 | 750 | /// \brief Return true if empty array, empty object, or null; 751 | /// otherwise, false. 752 | bool empty() const; 753 | 754 | /// Return isNull() 755 | bool operator!() const; 756 | 757 | /// Remove all object members and array elements. 758 | /// \pre type() is arrayValue, objectValue, or nullValue 759 | /// \post type() is unchanged 760 | void clear(); 761 | 762 | /// Resize the array to size elements. 763 | /// New elements are initialized to null. 764 | /// May only be called on nullValue or arrayValue. 765 | /// \pre type() is arrayValue or nullValue 766 | /// \post type() is arrayValue 767 | void resize(ArrayIndex size); 768 | 769 | /// Access an array element (zero based index ). 770 | /// If the array contains less than index element, then null value are 771 | /// inserted 772 | /// in the array so that its size is index+1. 773 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 774 | /// this from the operator[] which takes a string.) 775 | Value& operator[](ArrayIndex index); 776 | 777 | /// Access an array element (zero based index ). 778 | /// If the array contains less than index element, then null value are 779 | /// inserted 780 | /// in the array so that its size is index+1. 781 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 782 | /// this from the operator[] which takes a string.) 783 | Value& operator[](int index); 784 | 785 | /// Access an array element (zero based index ) 786 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 787 | /// this from the operator[] which takes a string.) 788 | const Value& operator[](ArrayIndex index) const; 789 | 790 | /// Access an array element (zero based index ) 791 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 792 | /// this from the operator[] which takes a string.) 793 | const Value& operator[](int index) const; 794 | 795 | /// If the array contains at least index+1 elements, returns the element 796 | /// value, 797 | /// otherwise returns defaultValue. 798 | Value get(ArrayIndex index, const Value& defaultValue) const; 799 | /// Return true if index < size(). 800 | bool isValidIndex(ArrayIndex index) const; 801 | /// \brief Append value to array at the end. 802 | /// 803 | /// Equivalent to jsonvalue[jsonvalue.size()] = value; 804 | Value& append(const Value& value); 805 | 806 | /// Access an object value by name, create a null member if it does not exist. 807 | /// \note Because of our implementation, keys are limited to 2^30 -1 chars. 808 | /// Exceeding that will cause an exception. 809 | Value& operator[](const char* key); 810 | /// Access an object value by name, returns null if there is no member with 811 | /// that name. 812 | const Value& operator[](const char* key) const; 813 | /// Access an object value by name, create a null member if it does not exist. 814 | /// \param key may contain embedded nulls. 815 | Value& operator[](const std::string& key); 816 | /// Access an object value by name, returns null if there is no member with 817 | /// that name. 818 | /// \param key may contain embedded nulls. 819 | const Value& operator[](const std::string& key) const; 820 | /** \brief Access an object value by name, create a null member if it does not 821 | exist. 822 | 823 | * If the object has no entry for that name, then the member name used to store 824 | * the new entry is not duplicated. 825 | * Example of use: 826 | * \code 827 | * Json::Value object; 828 | * static const StaticString code("code"); 829 | * object[code] = 1234; 830 | * \endcode 831 | */ 832 | Value& operator[](const StaticString& key); 833 | #ifdef JSON_USE_CPPTL 834 | /// Access an object value by name, create a null member if it does not exist. 835 | Value& operator[](const CppTL::ConstString& key); 836 | /// Access an object value by name, returns null if there is no member with 837 | /// that name. 838 | const Value& operator[](const CppTL::ConstString& key) const; 839 | #endif 840 | /// Return the member named key if it exist, defaultValue otherwise. 841 | /// \note deep copy 842 | Value get(const char* key, const Value& defaultValue) const; 843 | /// Return the member named key if it exist, defaultValue otherwise. 844 | /// \note deep copy 845 | /// \note key may contain embedded nulls. 846 | Value get(const char* begin, const char* end, const Value& defaultValue) const; 847 | /// Return the member named key if it exist, defaultValue otherwise. 848 | /// \note deep copy 849 | /// \param key may contain embedded nulls. 850 | Value get(const std::string& key, const Value& defaultValue) const; 851 | #ifdef JSON_USE_CPPTL 852 | /// Return the member named key if it exist, defaultValue otherwise. 853 | /// \note deep copy 854 | Value get(const CppTL::ConstString& key, const Value& defaultValue) const; 855 | #endif 856 | /// Most general and efficient version of isMember()const, get()const, 857 | /// and operator[]const 858 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 859 | Value const* find(char const* begin, char const* end) const; 860 | /// Most general and efficient version of object-mutators. 861 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 862 | /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. 863 | Value const* demand(char const* begin, char const* end); 864 | /// \brief Remove and return the named member. 865 | /// 866 | /// Do nothing if it did not exist. 867 | /// \return the removed Value, or null. 868 | /// \pre type() is objectValue or nullValue 869 | /// \post type() is unchanged 870 | /// \deprecated 871 | Value removeMember(const char* key); 872 | /// Same as removeMember(const char*) 873 | /// \param key may contain embedded nulls. 874 | /// \deprecated 875 | Value removeMember(const std::string& key); 876 | /// Same as removeMember(const char* begin, const char* end, Value* removed), 877 | /// but 'key' is null-terminated. 878 | bool removeMember(const char* key, Value* removed); 879 | /** \brief Remove the named map member. 880 | 881 | Update 'removed' iff removed. 882 | \param key may contain embedded nulls. 883 | \return true iff removed (no exceptions) 884 | */ 885 | bool removeMember(std::string const& key, Value* removed); 886 | /// Same as removeMember(std::string const& key, Value* removed) 887 | bool removeMember(const char* begin, const char* end, Value* removed); 888 | /** \brief Remove the indexed array element. 889 | 890 | O(n) expensive operations. 891 | Update 'removed' iff removed. 892 | \return true iff removed (no exceptions) 893 | */ 894 | bool removeIndex(ArrayIndex i, Value* removed); 895 | 896 | /// Return true if the object has a member named key. 897 | /// \note 'key' must be null-terminated. 898 | bool isMember(const char* key) const; 899 | /// Return true if the object has a member named key. 900 | /// \param key may contain embedded nulls. 901 | bool isMember(const std::string& key) const; 902 | /// Same as isMember(std::string const& key)const 903 | bool isMember(const char* begin, const char* end) const; 904 | #ifdef JSON_USE_CPPTL 905 | /// Return true if the object has a member named key. 906 | bool isMember(const CppTL::ConstString& key) const; 907 | #endif 908 | 909 | /// \brief Return a list of the member names. 910 | /// 911 | /// If null, return an empty list. 912 | /// \pre type() is objectValue or nullValue 913 | /// \post if type() was nullValue, it remains nullValue 914 | Members getMemberNames() const; 915 | 916 | //# ifdef JSON_USE_CPPTL 917 | // EnumMemberNames enumMemberNames() const; 918 | // EnumValues enumValues() const; 919 | //# endif 920 | 921 | /// \deprecated Always pass len. 922 | JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.") 923 | void setComment(const char* comment, CommentPlacement placement); 924 | /// Comments must be //... or /* ... */ 925 | void setComment(const char* comment, size_t len, CommentPlacement placement); 926 | /// Comments must be //... or /* ... */ 927 | void setComment(const std::string& comment, CommentPlacement placement); 928 | bool hasComment(CommentPlacement placement) const; 929 | /// Include delimiters and embedded newlines. 930 | std::string getComment(CommentPlacement placement) const; 931 | 932 | std::string toStyledString() const; 933 | 934 | const_iterator begin() const; 935 | const_iterator end() const; 936 | 937 | iterator begin(); 938 | iterator end(); 939 | 940 | // Accessors for the [start, limit) range of bytes within the JSON text from 941 | // which this value was parsed, if any. 942 | void setOffsetStart(size_t start); 943 | void setOffsetLimit(size_t limit); 944 | size_t getOffsetStart() const; 945 | size_t getOffsetLimit() const; 946 | 947 | private: 948 | void initBasic(ValueType type, bool allocated = false); 949 | 950 | Value& resolveReference(const char* key); 951 | Value& resolveReference(const char* key, const char* end); 952 | 953 | struct CommentInfo { 954 | CommentInfo(); 955 | ~CommentInfo(); 956 | 957 | void setComment(const char* text, size_t len); 958 | 959 | char* comment_; 960 | }; 961 | 962 | // struct MemberNamesTransform 963 | //{ 964 | // typedef const char *result_type; 965 | // const char *operator()( const CZString &name ) const 966 | // { 967 | // return name.c_str(); 968 | // } 969 | //}; 970 | 971 | union ValueHolder { 972 | LargestInt int_; 973 | LargestUInt uint_; 974 | double real_; 975 | bool bool_; 976 | char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ 977 | ObjectValues* map_; 978 | } value_; 979 | ValueType type_ : 8; 980 | unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. 981 | // If not allocated_, string_ must be null-terminated. 982 | CommentInfo* comments_; 983 | 984 | // [start, limit) byte offsets in the source JSON text from which this Value 985 | // was extracted. 986 | size_t start_; 987 | size_t limit_; 988 | }; 989 | 990 | /** \brief Experimental and untested: represents an element of the "path" to 991 | * access a node. 992 | */ 993 | class JSON_API PathArgument { 994 | public: 995 | friend class Path; 996 | 997 | PathArgument(); 998 | PathArgument(ArrayIndex index); 999 | PathArgument(const char* key); 1000 | PathArgument(const std::string& key); 1001 | 1002 | private: 1003 | enum Kind { 1004 | kindNone = 0, 1005 | kindIndex, 1006 | kindKey 1007 | }; 1008 | std::string key_; 1009 | ArrayIndex index_; 1010 | Kind kind_; 1011 | }; 1012 | 1013 | /** \brief Experimental and untested: represents a "path" to access a node. 1014 | * 1015 | * Syntax: 1016 | * - "." => root node 1017 | * - ".[n]" => elements at index 'n' of root node (an array value) 1018 | * - ".name" => member named 'name' of root node (an object value) 1019 | * - ".name1.name2.name3" 1020 | * - ".[0][1][2].name1[3]" 1021 | * - ".%" => member name is provided as parameter 1022 | * - ".[%]" => index is provied as parameter 1023 | */ 1024 | class JSON_API Path { 1025 | public: 1026 | Path(const std::string& path, 1027 | const PathArgument& a1 = PathArgument(), 1028 | const PathArgument& a2 = PathArgument(), 1029 | const PathArgument& a3 = PathArgument(), 1030 | const PathArgument& a4 = PathArgument(), 1031 | const PathArgument& a5 = PathArgument()); 1032 | 1033 | const Value& resolve(const Value& root) const; 1034 | Value resolve(const Value& root, const Value& defaultValue) const; 1035 | /// Creates the "path" to access the specified node and returns a reference on 1036 | /// the node. 1037 | Value& make(Value& root) const; 1038 | 1039 | private: 1040 | typedef std::vector InArgs; 1041 | typedef std::vector Args; 1042 | 1043 | void makePath(const std::string& path, const InArgs& in); 1044 | void addPathInArg(const std::string& path, 1045 | const InArgs& in, 1046 | InArgs::const_iterator& itInArg, 1047 | PathArgument::Kind kind); 1048 | void invalidPath(const std::string& path, int location); 1049 | 1050 | Args args_; 1051 | }; 1052 | 1053 | /** \brief base class for Value iterators. 1054 | * 1055 | */ 1056 | class JSON_API ValueIteratorBase { 1057 | public: 1058 | typedef std::bidirectional_iterator_tag iterator_category; 1059 | typedef unsigned int size_t; 1060 | typedef int difference_type; 1061 | typedef ValueIteratorBase SelfType; 1062 | 1063 | bool operator==(const SelfType& other) const { return isEqual(other); } 1064 | 1065 | bool operator!=(const SelfType& other) const { return !isEqual(other); } 1066 | 1067 | difference_type operator-(const SelfType& other) const { 1068 | return other.computeDistance(*this); 1069 | } 1070 | 1071 | /// Return either the index or the member name of the referenced value as a 1072 | /// Value. 1073 | Value key() const; 1074 | 1075 | /// Return the index of the referenced Value, or -1 if it is not an arrayValue. 1076 | UInt index() const; 1077 | 1078 | /// Return the member name of the referenced Value, or "" if it is not an 1079 | /// objectValue. 1080 | /// \note Avoid `c_str()` on result, as embedded zeroes are possible. 1081 | std::string name() const; 1082 | 1083 | /// Return the member name of the referenced Value. "" if it is not an 1084 | /// objectValue. 1085 | /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. 1086 | JSONCPP_DEPRECATED("Use `key = name();` instead.") 1087 | char const* memberName() const; 1088 | /// Return the member name of the referenced Value, or NULL if it is not an 1089 | /// objectValue. 1090 | /// \note Better version than memberName(). Allows embedded nulls. 1091 | char const* memberName(char const** end) const; 1092 | 1093 | protected: 1094 | Value& deref() const; 1095 | 1096 | void increment(); 1097 | 1098 | void decrement(); 1099 | 1100 | difference_type computeDistance(const SelfType& other) const; 1101 | 1102 | bool isEqual(const SelfType& other) const; 1103 | 1104 | void copy(const SelfType& other); 1105 | 1106 | private: 1107 | Value::ObjectValues::iterator current_; 1108 | // Indicates that iterator is for a null value. 1109 | bool isNull_; 1110 | 1111 | public: 1112 | // For some reason, BORLAND needs these at the end, rather 1113 | // than earlier. No idea why. 1114 | ValueIteratorBase(); 1115 | explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); 1116 | }; 1117 | 1118 | /** \brief const iterator for object and array value. 1119 | * 1120 | */ 1121 | class JSON_API ValueConstIterator : public ValueIteratorBase { 1122 | friend class Value; 1123 | 1124 | public: 1125 | typedef const Value value_type; 1126 | //typedef unsigned int size_t; 1127 | //typedef int difference_type; 1128 | typedef const Value& reference; 1129 | typedef const Value* pointer; 1130 | typedef ValueConstIterator SelfType; 1131 | 1132 | ValueConstIterator(); 1133 | ValueConstIterator(ValueIterator const& other); 1134 | 1135 | private: 1136 | /*! \internal Use by Value to create an iterator. 1137 | */ 1138 | explicit ValueConstIterator(const Value::ObjectValues::iterator& current); 1139 | public: 1140 | SelfType& operator=(const ValueIteratorBase& other); 1141 | 1142 | SelfType operator++(int) { 1143 | SelfType temp(*this); 1144 | ++*this; 1145 | return temp; 1146 | } 1147 | 1148 | SelfType operator--(int) { 1149 | SelfType temp(*this); 1150 | --*this; 1151 | return temp; 1152 | } 1153 | 1154 | SelfType& operator--() { 1155 | decrement(); 1156 | return *this; 1157 | } 1158 | 1159 | SelfType& operator++() { 1160 | increment(); 1161 | return *this; 1162 | } 1163 | 1164 | reference operator*() const { return deref(); } 1165 | 1166 | pointer operator->() const { return &deref(); } 1167 | }; 1168 | 1169 | /** \brief Iterator for object and array value. 1170 | */ 1171 | class JSON_API ValueIterator : public ValueIteratorBase { 1172 | friend class Value; 1173 | 1174 | public: 1175 | typedef Value value_type; 1176 | typedef unsigned int size_t; 1177 | typedef int difference_type; 1178 | typedef Value& reference; 1179 | typedef Value* pointer; 1180 | typedef ValueIterator SelfType; 1181 | 1182 | ValueIterator(); 1183 | explicit ValueIterator(const ValueConstIterator& other); 1184 | ValueIterator(const ValueIterator& other); 1185 | 1186 | private: 1187 | /*! \internal Use by Value to create an iterator. 1188 | */ 1189 | explicit ValueIterator(const Value::ObjectValues::iterator& current); 1190 | public: 1191 | SelfType& operator=(const SelfType& other); 1192 | 1193 | SelfType operator++(int) { 1194 | SelfType temp(*this); 1195 | ++*this; 1196 | return temp; 1197 | } 1198 | 1199 | SelfType operator--(int) { 1200 | SelfType temp(*this); 1201 | --*this; 1202 | return temp; 1203 | } 1204 | 1205 | SelfType& operator--() { 1206 | decrement(); 1207 | return *this; 1208 | } 1209 | 1210 | SelfType& operator++() { 1211 | increment(); 1212 | return *this; 1213 | } 1214 | 1215 | reference operator*() const { return deref(); } 1216 | 1217 | pointer operator->() const { return &deref(); } 1218 | }; 1219 | 1220 | } // namespace Json 1221 | 1222 | 1223 | namespace std { 1224 | /// Specialize std::swap() for Json::Value. 1225 | template<> 1226 | inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } 1227 | } 1228 | 1229 | 1230 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1231 | #pragma warning(pop) 1232 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1233 | 1234 | #endif // CPPTL_JSON_H_INCLUDED 1235 | 1236 | // ////////////////////////////////////////////////////////////////////// 1237 | // End of content of file: include/json/value.h 1238 | // ////////////////////////////////////////////////////////////////////// 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | // ////////////////////////////////////////////////////////////////////// 1246 | // Beginning of content of file: include/json/reader.h 1247 | // ////////////////////////////////////////////////////////////////////// 1248 | 1249 | // Copyright 2007-2010 Baptiste Lepilleur 1250 | // Distributed under MIT license, or public domain if desired and 1251 | // recognized in your jurisdiction. 1252 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1253 | 1254 | #ifndef CPPTL_JSON_READER_H_INCLUDED 1255 | #define CPPTL_JSON_READER_H_INCLUDED 1256 | 1257 | #if !defined(JSON_IS_AMALGAMATION) 1258 | #include "features.h" 1259 | #include "value.h" 1260 | #endif // if !defined(JSON_IS_AMALGAMATION) 1261 | #include 1262 | #include 1263 | #include 1264 | #include 1265 | #include 1266 | 1267 | // Disable warning C4251: : needs to have dll-interface to 1268 | // be used by... 1269 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1270 | #pragma warning(push) 1271 | #pragma warning(disable : 4251) 1272 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1273 | 1274 | namespace Json { 1275 | 1276 | /** \brief Unserialize a JSON document into a 1277 | *Value. 1278 | * 1279 | * \deprecated Use CharReader and CharReaderBuilder. 1280 | */ 1281 | class JSON_API Reader { 1282 | public: 1283 | typedef char Char; 1284 | typedef const Char* Location; 1285 | 1286 | /** \brief An error tagged with where in the JSON text it was encountered. 1287 | * 1288 | * The offsets give the [start, limit) range of bytes within the text. Note 1289 | * that this is bytes, not codepoints. 1290 | * 1291 | */ 1292 | struct StructuredError { 1293 | size_t offset_start; 1294 | size_t offset_limit; 1295 | std::string message; 1296 | }; 1297 | 1298 | /** \brief Constructs a Reader allowing all features 1299 | * for parsing. 1300 | */ 1301 | Reader(); 1302 | 1303 | /** \brief Constructs a Reader allowing the specified feature set 1304 | * for parsing. 1305 | */ 1306 | Reader(const Features& features); 1307 | 1308 | /** \brief Read a Value from a JSON 1309 | * document. 1310 | * \param document UTF-8 encoded string containing the document to read. 1311 | * \param root [out] Contains the root value of the document if it was 1312 | * successfully parsed. 1313 | * \param collectComments \c true to collect comment and allow writing them 1314 | * back during 1315 | * serialization, \c false to discard comments. 1316 | * This parameter is ignored if 1317 | * Features::allowComments_ 1318 | * is \c false. 1319 | * \return \c true if the document was successfully parsed, \c false if an 1320 | * error occurred. 1321 | */ 1322 | bool 1323 | parse(const std::string& document, Value& root, bool collectComments = true); 1324 | 1325 | /** \brief Read a Value from a JSON 1326 | document. 1327 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1328 | document to read. 1329 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1330 | document to read. 1331 | * Must be >= beginDoc. 1332 | * \param root [out] Contains the root value of the document if it was 1333 | * successfully parsed. 1334 | * \param collectComments \c true to collect comment and allow writing them 1335 | back during 1336 | * serialization, \c false to discard comments. 1337 | * This parameter is ignored if 1338 | Features::allowComments_ 1339 | * is \c false. 1340 | * \return \c true if the document was successfully parsed, \c false if an 1341 | error occurred. 1342 | */ 1343 | bool parse(const char* beginDoc, 1344 | const char* endDoc, 1345 | Value& root, 1346 | bool collectComments = true); 1347 | 1348 | /// \brief Parse from input stream. 1349 | /// \see Json::operator>>(std::istream&, Json::Value&). 1350 | bool parse(std::istream& is, Value& root, bool collectComments = true); 1351 | 1352 | /** \brief Returns a user friendly string that list errors in the parsed 1353 | * document. 1354 | * \return Formatted error message with the list of errors with their location 1355 | * in 1356 | * the parsed document. An empty string is returned if no error 1357 | * occurred 1358 | * during parsing. 1359 | * \deprecated Use getFormattedErrorMessages() instead (typo fix). 1360 | */ 1361 | JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") 1362 | std::string getFormatedErrorMessages() const; 1363 | 1364 | /** \brief Returns a user friendly string that list errors in the parsed 1365 | * document. 1366 | * \return Formatted error message with the list of errors with their location 1367 | * in 1368 | * the parsed document. An empty string is returned if no error 1369 | * occurred 1370 | * during parsing. 1371 | */ 1372 | std::string getFormattedErrorMessages() const; 1373 | 1374 | /** \brief Returns a vector of structured erros encounted while parsing. 1375 | * \return A (possibly empty) vector of StructuredError objects. Currently 1376 | * only one error can be returned, but the caller should tolerate 1377 | * multiple 1378 | * errors. This can occur if the parser recovers from a non-fatal 1379 | * parse error and then encounters additional errors. 1380 | */ 1381 | std::vector getStructuredErrors() const; 1382 | 1383 | /** \brief Add a semantic error message. 1384 | * \param value JSON Value location associated with the error 1385 | * \param message The error message. 1386 | * \return \c true if the error was successfully added, \c false if the 1387 | * Value offset exceeds the document size. 1388 | */ 1389 | bool pushError(const Value& value, const std::string& message); 1390 | 1391 | /** \brief Add a semantic error message with extra context. 1392 | * \param value JSON Value location associated with the error 1393 | * \param message The error message. 1394 | * \param extra Additional JSON Value location to contextualize the error 1395 | * \return \c true if the error was successfully added, \c false if either 1396 | * Value offset exceeds the document size. 1397 | */ 1398 | bool pushError(const Value& value, const std::string& message, const Value& extra); 1399 | 1400 | /** \brief Return whether there are any errors. 1401 | * \return \c true if there are no errors to report \c false if 1402 | * errors have occurred. 1403 | */ 1404 | bool good() const; 1405 | 1406 | private: 1407 | enum TokenType { 1408 | tokenEndOfStream = 0, 1409 | tokenObjectBegin, 1410 | tokenObjectEnd, 1411 | tokenArrayBegin, 1412 | tokenArrayEnd, 1413 | tokenString, 1414 | tokenNumber, 1415 | tokenTrue, 1416 | tokenFalse, 1417 | tokenNull, 1418 | tokenArraySeparator, 1419 | tokenMemberSeparator, 1420 | tokenComment, 1421 | tokenError 1422 | }; 1423 | 1424 | class Token { 1425 | public: 1426 | TokenType type_; 1427 | Location start_; 1428 | Location end_; 1429 | }; 1430 | 1431 | class ErrorInfo { 1432 | public: 1433 | Token token_; 1434 | std::string message_; 1435 | Location extra_; 1436 | }; 1437 | 1438 | typedef std::deque Errors; 1439 | 1440 | bool readToken(Token& token); 1441 | void skipSpaces(); 1442 | bool match(Location pattern, int patternLength); 1443 | bool readComment(); 1444 | bool readCStyleComment(); 1445 | bool readCppStyleComment(); 1446 | bool readString(); 1447 | void readNumber(); 1448 | bool readValue(); 1449 | bool readObject(Token& token); 1450 | bool readArray(Token& token); 1451 | bool decodeNumber(Token& token); 1452 | bool decodeNumber(Token& token, Value& decoded); 1453 | bool decodeString(Token& token); 1454 | bool decodeString(Token& token, std::string& decoded); 1455 | bool decodeDouble(Token& token); 1456 | bool decodeDouble(Token& token, Value& decoded); 1457 | bool decodeUnicodeCodePoint(Token& token, 1458 | Location& current, 1459 | Location end, 1460 | unsigned int& unicode); 1461 | bool decodeUnicodeEscapeSequence(Token& token, 1462 | Location& current, 1463 | Location end, 1464 | unsigned int& unicode); 1465 | bool addError(const std::string& message, Token& token, Location extra = 0); 1466 | bool recoverFromError(TokenType skipUntilToken); 1467 | bool addErrorAndRecover(const std::string& message, 1468 | Token& token, 1469 | TokenType skipUntilToken); 1470 | void skipUntilSpace(); 1471 | Value& currentValue(); 1472 | Char getNextChar(); 1473 | void 1474 | getLocationLineAndColumn(Location location, int& line, int& column) const; 1475 | std::string getLocationLineAndColumn(Location location) const; 1476 | void addComment(Location begin, Location end, CommentPlacement placement); 1477 | void skipCommentTokens(Token& token); 1478 | 1479 | typedef std::stack Nodes; 1480 | Nodes nodes_; 1481 | Errors errors_; 1482 | std::string document_; 1483 | Location begin_; 1484 | Location end_; 1485 | Location current_; 1486 | Location lastValueEnd_; 1487 | Value* lastValue_; 1488 | std::string commentsBefore_; 1489 | Features features_; 1490 | bool collectComments_; 1491 | }; // Reader 1492 | 1493 | /** Interface for reading JSON from a char array. 1494 | */ 1495 | class JSON_API CharReader { 1496 | public: 1497 | virtual ~CharReader() {} 1498 | /** \brief Read a Value from a JSON 1499 | document. 1500 | * The document must be a UTF-8 encoded string containing the document to read. 1501 | * 1502 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1503 | document to read. 1504 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1505 | document to read. 1506 | * Must be >= beginDoc. 1507 | * \param root [out] Contains the root value of the document if it was 1508 | * successfully parsed. 1509 | * \param errs [out] Formatted error messages (if not NULL) 1510 | * a user friendly string that lists errors in the parsed 1511 | * document. 1512 | * \return \c true if the document was successfully parsed, \c false if an 1513 | error occurred. 1514 | */ 1515 | virtual bool parse( 1516 | char const* beginDoc, char const* endDoc, 1517 | Value* root, std::string* errs) = 0; 1518 | 1519 | class JSON_API Factory { 1520 | public: 1521 | virtual ~Factory() {} 1522 | /** \brief Allocate a CharReader via operator new(). 1523 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1524 | */ 1525 | virtual CharReader* newCharReader() const = 0; 1526 | }; // Factory 1527 | }; // CharReader 1528 | 1529 | /** \brief Build a CharReader implementation. 1530 | 1531 | Usage: 1532 | \code 1533 | using namespace Json; 1534 | CharReaderBuilder builder; 1535 | builder["collectComments"] = false; 1536 | Value value; 1537 | std::string errs; 1538 | bool ok = parseFromStream(builder, std::cin, &value, &errs); 1539 | \endcode 1540 | */ 1541 | class JSON_API CharReaderBuilder : public CharReader::Factory { 1542 | public: 1543 | // Note: We use a Json::Value so that we can add data-members to this class 1544 | // without a major version bump. 1545 | /** Configuration of this builder. 1546 | These are case-sensitive. 1547 | Available settings (case-sensitive): 1548 | - `"collectComments": false or true` 1549 | - true to collect comment and allow writing them 1550 | back during serialization, false to discard comments. 1551 | This parameter is ignored if allowComments is false. 1552 | - `"allowComments": false or true` 1553 | - true if comments are allowed. 1554 | - `"strictRoot": false or true` 1555 | - true if root must be either an array or an object value 1556 | - `"allowDroppedNullPlaceholders": false or true` 1557 | - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) 1558 | - `"allowNumericKeys": false or true` 1559 | - true if numeric object keys are allowed. 1560 | - `"allowSingleQuotes": false or true` 1561 | - true if '' are allowed for strings (both keys and values) 1562 | - `"stackLimit": integer` 1563 | - Exceeding stackLimit (recursive depth of `readValue()`) will 1564 | cause an exception. 1565 | - This is a security issue (seg-faults caused by deeply nested JSON), 1566 | so the default is low. 1567 | - `"failIfExtra": false or true` 1568 | - If true, `parse()` returns false when extra non-whitespace trails 1569 | the JSON value in the input string. 1570 | - `"rejectDupKeys": false or true` 1571 | - If true, `parse()` returns false when a key is duplicated within an object. 1572 | - `"allowSpecialFloats": false or true` 1573 | - If true, special float values (NaNs and infinities) are allowed 1574 | and their values are lossfree restorable. 1575 | 1576 | You can examine 'settings_` yourself 1577 | to see the defaults. You can also write and read them just like any 1578 | JSON Value. 1579 | \sa setDefaults() 1580 | */ 1581 | Json::Value settings_; 1582 | 1583 | CharReaderBuilder(); 1584 | ~CharReaderBuilder() override; 1585 | 1586 | CharReader* newCharReader() const override; 1587 | 1588 | /** \return true if 'settings' are legal and consistent; 1589 | * otherwise, indicate bad settings via 'invalid'. 1590 | */ 1591 | bool validate(Json::Value* invalid) const; 1592 | 1593 | /** A simple way to update a specific setting. 1594 | */ 1595 | Value& operator[](std::string key); 1596 | 1597 | /** Called by ctor, but you can use this to reset settings_. 1598 | * \pre 'settings' != NULL (but Json::null is fine) 1599 | * \remark Defaults: 1600 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults 1601 | */ 1602 | static void setDefaults(Json::Value* settings); 1603 | /** Same as old Features::strictMode(). 1604 | * \pre 'settings' != NULL (but Json::null is fine) 1605 | * \remark Defaults: 1606 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode 1607 | */ 1608 | static void strictMode(Json::Value* settings); 1609 | }; 1610 | 1611 | /** Consume entire stream and use its begin/end. 1612 | * Someday we might have a real StreamReader, but for now this 1613 | * is convenient. 1614 | */ 1615 | bool JSON_API parseFromStream( 1616 | CharReader::Factory const&, 1617 | std::istream&, 1618 | Value* root, std::string* errs); 1619 | 1620 | /** \brief Read from 'sin' into 'root'. 1621 | 1622 | Always keep comments from the input JSON. 1623 | 1624 | This can be used to read a file into a particular sub-object. 1625 | For example: 1626 | \code 1627 | Json::Value root; 1628 | cin >> root["dir"]["file"]; 1629 | cout << root; 1630 | \endcode 1631 | Result: 1632 | \verbatim 1633 | { 1634 | "dir": { 1635 | "file": { 1636 | // The input stream JSON would be nested here. 1637 | } 1638 | } 1639 | } 1640 | \endverbatim 1641 | \throw std::exception on parse error. 1642 | \see Json::operator<<() 1643 | */ 1644 | JSON_API std::istream& operator>>(std::istream&, Value&); 1645 | 1646 | } // namespace Json 1647 | 1648 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1649 | #pragma warning(pop) 1650 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1651 | 1652 | #endif // CPPTL_JSON_READER_H_INCLUDED 1653 | 1654 | // ////////////////////////////////////////////////////////////////////// 1655 | // End of content of file: include/json/reader.h 1656 | // ////////////////////////////////////////////////////////////////////// 1657 | 1658 | 1659 | 1660 | 1661 | 1662 | 1663 | // ////////////////////////////////////////////////////////////////////// 1664 | // Beginning of content of file: include/json/writer.h 1665 | // ////////////////////////////////////////////////////////////////////// 1666 | 1667 | // Copyright 2007-2010 Baptiste Lepilleur 1668 | // Distributed under MIT license, or public domain if desired and 1669 | // recognized in your jurisdiction. 1670 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1671 | 1672 | #ifndef JSON_WRITER_H_INCLUDED 1673 | #define JSON_WRITER_H_INCLUDED 1674 | 1675 | #if !defined(JSON_IS_AMALGAMATION) 1676 | #include "value.h" 1677 | #endif // if !defined(JSON_IS_AMALGAMATION) 1678 | #include 1679 | #include 1680 | #include 1681 | 1682 | // Disable warning C4251: : needs to have dll-interface to 1683 | // be used by... 1684 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1685 | #pragma warning(push) 1686 | #pragma warning(disable : 4251) 1687 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1688 | 1689 | namespace Json { 1690 | 1691 | class Value; 1692 | 1693 | /** 1694 | 1695 | Usage: 1696 | \code 1697 | using namespace Json; 1698 | void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { 1699 | std::unique_ptr const writer( 1700 | factory.newStreamWriter()); 1701 | writer->write(value, &std::cout); 1702 | std::cout << std::endl; // add lf and flush 1703 | } 1704 | \endcode 1705 | */ 1706 | class JSON_API StreamWriter { 1707 | protected: 1708 | std::ostream* sout_; // not owned; will not delete 1709 | public: 1710 | StreamWriter(); 1711 | virtual ~StreamWriter(); 1712 | /** Write Value into document as configured in sub-class. 1713 | Do not take ownership of sout, but maintain a reference during function. 1714 | \pre sout != NULL 1715 | \return zero on success (For now, we always return zero, so check the stream instead.) 1716 | \throw std::exception possibly, depending on configuration 1717 | */ 1718 | virtual int write(Value const& root, std::ostream* sout) = 0; 1719 | 1720 | /** \brief A simple abstract factory. 1721 | */ 1722 | class JSON_API Factory { 1723 | public: 1724 | virtual ~Factory(); 1725 | /** \brief Allocate a CharReader via operator new(). 1726 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1727 | */ 1728 | virtual StreamWriter* newStreamWriter() const = 0; 1729 | }; // Factory 1730 | }; // StreamWriter 1731 | 1732 | /** \brief Write into stringstream, then return string, for convenience. 1733 | * A StreamWriter will be created from the factory, used, and then deleted. 1734 | */ 1735 | std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); 1736 | 1737 | 1738 | /** \brief Build a StreamWriter implementation. 1739 | 1740 | Usage: 1741 | \code 1742 | using namespace Json; 1743 | Value value = ...; 1744 | StreamWriterBuilder builder; 1745 | builder["commentStyle"] = "None"; 1746 | builder["indentation"] = " "; // or whatever you like 1747 | std::unique_ptr writer( 1748 | builder.newStreamWriter()); 1749 | writer->write(value, &std::cout); 1750 | std::cout << std::endl; // add lf and flush 1751 | \endcode 1752 | */ 1753 | class JSON_API StreamWriterBuilder : public StreamWriter::Factory { 1754 | public: 1755 | // Note: We use a Json::Value so that we can add data-members to this class 1756 | // without a major version bump. 1757 | /** Configuration of this builder. 1758 | Available settings (case-sensitive): 1759 | - "commentStyle": "None" or "All" 1760 | - "indentation": "" 1761 | - "enableYAMLCompatibility": false or true 1762 | - slightly change the whitespace around colons 1763 | - "dropNullPlaceholders": false or true 1764 | - Drop the "null" string from the writer's output for nullValues. 1765 | Strictly speaking, this is not valid JSON. But when the output is being 1766 | fed to a browser's Javascript, it makes for smaller output and the 1767 | browser can handle the output just fine. 1768 | - "useSpecialFloats": false or true 1769 | - If true, outputs non-finite floating point values in the following way: 1770 | NaN values as "NaN", positive infinity as "Infinity", and negative infinity 1771 | as "-Infinity". 1772 | 1773 | You can examine 'settings_` yourself 1774 | to see the defaults. You can also write and read them just like any 1775 | JSON Value. 1776 | \sa setDefaults() 1777 | */ 1778 | Json::Value settings_; 1779 | 1780 | StreamWriterBuilder(); 1781 | ~StreamWriterBuilder() override; 1782 | 1783 | /** 1784 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1785 | */ 1786 | StreamWriter* newStreamWriter() const override; 1787 | 1788 | /** \return true if 'settings' are legal and consistent; 1789 | * otherwise, indicate bad settings via 'invalid'. 1790 | */ 1791 | bool validate(Json::Value* invalid) const; 1792 | /** A simple way to update a specific setting. 1793 | */ 1794 | Value& operator[](std::string key); 1795 | 1796 | /** Called by ctor, but you can use this to reset settings_. 1797 | * \pre 'settings' != NULL (but Json::null is fine) 1798 | * \remark Defaults: 1799 | * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults 1800 | */ 1801 | static void setDefaults(Json::Value* settings); 1802 | }; 1803 | 1804 | /** \brief Abstract class for writers. 1805 | * \deprecated Use StreamWriter. (And really, this is an implementation detail.) 1806 | */ 1807 | class JSON_API Writer { 1808 | public: 1809 | virtual ~Writer(); 1810 | 1811 | virtual std::string write(const Value& root) = 0; 1812 | }; 1813 | 1814 | /** \brief Outputs a Value in JSON format 1815 | *without formatting (not human friendly). 1816 | * 1817 | * The JSON document is written in a single line. It is not intended for 'human' 1818 | *consumption, 1819 | * but may be usefull to support feature such as RPC where bandwith is limited. 1820 | * \sa Reader, Value 1821 | * \deprecated Use StreamWriterBuilder. 1822 | */ 1823 | class JSON_API FastWriter : public Writer { 1824 | 1825 | public: 1826 | FastWriter(); 1827 | ~FastWriter() override {} 1828 | 1829 | void enableYAMLCompatibility(); 1830 | 1831 | /** \brief Drop the "null" string from the writer's output for nullValues. 1832 | * Strictly speaking, this is not valid JSON. But when the output is being 1833 | * fed to a browser's Javascript, it makes for smaller output and the 1834 | * browser can handle the output just fine. 1835 | */ 1836 | void dropNullPlaceholders(); 1837 | 1838 | void omitEndingLineFeed(); 1839 | 1840 | public: // overridden from Writer 1841 | std::string write(const Value& root) override; 1842 | 1843 | private: 1844 | void writeValue(const Value& value); 1845 | 1846 | std::string document_; 1847 | bool yamlCompatiblityEnabled_; 1848 | bool dropNullPlaceholders_; 1849 | bool omitEndingLineFeed_; 1850 | }; 1851 | 1852 | /** \brief Writes a Value in JSON format in a 1853 | *human friendly way. 1854 | * 1855 | * The rules for line break and indent are as follow: 1856 | * - Object value: 1857 | * - if empty then print {} without indent and line break 1858 | * - if not empty the print '{', line break & indent, print one value per 1859 | *line 1860 | * and then unindent and line break and print '}'. 1861 | * - Array value: 1862 | * - if empty then print [] without indent and line break 1863 | * - if the array contains no object value, empty array or some other value 1864 | *types, 1865 | * and all the values fit on one lines, then print the array on a single 1866 | *line. 1867 | * - otherwise, it the values do not fit on one line, or the array contains 1868 | * object or non empty array, then print one value per line. 1869 | * 1870 | * If the Value have comments then they are outputed according to their 1871 | *#CommentPlacement. 1872 | * 1873 | * \sa Reader, Value, Value::setComment() 1874 | * \deprecated Use StreamWriterBuilder. 1875 | */ 1876 | class JSON_API StyledWriter : public Writer { 1877 | public: 1878 | StyledWriter(); 1879 | ~StyledWriter() override {} 1880 | 1881 | public: // overridden from Writer 1882 | /** \brief Serialize a Value in JSON format. 1883 | * \param root Value to serialize. 1884 | * \return String containing the JSON document that represents the root value. 1885 | */ 1886 | std::string write(const Value& root) override; 1887 | 1888 | private: 1889 | void writeValue(const Value& value); 1890 | void writeArrayValue(const Value& value); 1891 | bool isMultineArray(const Value& value); 1892 | void pushValue(const std::string& value); 1893 | void writeIndent(); 1894 | void writeWithIndent(const std::string& value); 1895 | void indent(); 1896 | void unindent(); 1897 | void writeCommentBeforeValue(const Value& root); 1898 | void writeCommentAfterValueOnSameLine(const Value& root); 1899 | bool hasCommentForValue(const Value& value); 1900 | static std::string normalizeEOL(const std::string& text); 1901 | 1902 | typedef std::vector ChildValues; 1903 | 1904 | ChildValues childValues_; 1905 | std::string document_; 1906 | std::string indentString_; 1907 | int rightMargin_; 1908 | int indentSize_; 1909 | bool addChildValues_; 1910 | }; 1911 | 1912 | /** \brief Writes a Value in JSON format in a 1913 | human friendly way, 1914 | to a stream rather than to a string. 1915 | * 1916 | * The rules for line break and indent are as follow: 1917 | * - Object value: 1918 | * - if empty then print {} without indent and line break 1919 | * - if not empty the print '{', line break & indent, print one value per 1920 | line 1921 | * and then unindent and line break and print '}'. 1922 | * - Array value: 1923 | * - if empty then print [] without indent and line break 1924 | * - if the array contains no object value, empty array or some other value 1925 | types, 1926 | * and all the values fit on one lines, then print the array on a single 1927 | line. 1928 | * - otherwise, it the values do not fit on one line, or the array contains 1929 | * object or non empty array, then print one value per line. 1930 | * 1931 | * If the Value have comments then they are outputed according to their 1932 | #CommentPlacement. 1933 | * 1934 | * \param indentation Each level will be indented by this amount extra. 1935 | * \sa Reader, Value, Value::setComment() 1936 | * \deprecated Use StreamWriterBuilder. 1937 | */ 1938 | class JSON_API StyledStreamWriter { 1939 | public: 1940 | StyledStreamWriter(std::string indentation = "\t"); 1941 | ~StyledStreamWriter() {} 1942 | 1943 | public: 1944 | /** \brief Serialize a Value in JSON format. 1945 | * \param out Stream to write to. (Can be ostringstream, e.g.) 1946 | * \param root Value to serialize. 1947 | * \note There is no point in deriving from Writer, since write() should not 1948 | * return a value. 1949 | */ 1950 | void write(std::ostream& out, const Value& root); 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 std::string& value); 1957 | void writeIndent(); 1958 | void writeWithIndent(const std::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 std::string normalizeEOL(const std::string& text); 1965 | 1966 | typedef std::vector ChildValues; 1967 | 1968 | ChildValues childValues_; 1969 | std::ostream* document_; 1970 | std::string indentString_; 1971 | int rightMargin_; 1972 | std::string indentation_; 1973 | bool addChildValues_ : 1; 1974 | bool indented_ : 1; 1975 | }; 1976 | 1977 | #if defined(JSON_HAS_INT64) 1978 | std::string JSON_API valueToString(Int value); 1979 | std::string JSON_API valueToString(UInt value); 1980 | #endif // if defined(JSON_HAS_INT64) 1981 | std::string JSON_API valueToString(LargestInt value); 1982 | std::string JSON_API valueToString(LargestUInt value); 1983 | std::string JSON_API valueToString(double value); 1984 | std::string JSON_API valueToString(bool value); 1985 | std::string JSON_API valueToQuotedString(const char* value); 1986 | 1987 | /// \brief Output using the StyledStreamWriter. 1988 | /// \see Json::operator>>() 1989 | JSON_API std::ostream& operator<<(std::ostream&, const Value& root); 1990 | 1991 | } // namespace Json 1992 | 1993 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1994 | #pragma warning(pop) 1995 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1996 | 1997 | #endif // JSON_WRITER_H_INCLUDED 1998 | 1999 | // ////////////////////////////////////////////////////////////////////// 2000 | // End of content of file: include/json/writer.h 2001 | // ////////////////////////////////////////////////////////////////////// 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | // ////////////////////////////////////////////////////////////////////// 2009 | // Beginning of content of file: include/json/assertions.h 2010 | // ////////////////////////////////////////////////////////////////////// 2011 | 2012 | // Copyright 2007-2010 Baptiste Lepilleur 2013 | // Distributed under MIT license, or public domain if desired and 2014 | // recognized in your jurisdiction. 2015 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 2016 | 2017 | #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED 2018 | #define CPPTL_JSON_ASSERTIONS_H_INCLUDED 2019 | 2020 | #include 2021 | #include 2022 | 2023 | #if !defined(JSON_IS_AMALGAMATION) 2024 | #include "config.h" 2025 | #endif // if !defined(JSON_IS_AMALGAMATION) 2026 | 2027 | /** It should not be possible for a maliciously designed file to 2028 | * cause an abort() or seg-fault, so these macros are used only 2029 | * for pre-condition violations and internal logic errors. 2030 | */ 2031 | #if JSON_USE_EXCEPTION 2032 | 2033 | // @todo <= add detail about condition in exception 2034 | # define JSON_ASSERT(condition) \ 2035 | {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} 2036 | 2037 | # define JSON_FAIL_MESSAGE(message) \ 2038 | { \ 2039 | std::ostringstream oss; oss << message; \ 2040 | Json::throwLogicError(oss.str()); \ 2041 | abort(); \ 2042 | } 2043 | 2044 | #else // JSON_USE_EXCEPTION 2045 | 2046 | # define JSON_ASSERT(condition) assert(condition) 2047 | 2048 | // The call to assert() will show the failure message in debug builds. In 2049 | // release builds we abort, for a core-dump or debugger. 2050 | # define JSON_FAIL_MESSAGE(message) \ 2051 | { \ 2052 | std::ostringstream oss; oss << message; \ 2053 | assert(false && oss.str().c_str()); \ 2054 | abort(); \ 2055 | } 2056 | 2057 | 2058 | #endif 2059 | 2060 | #define JSON_ASSERT_MESSAGE(condition, message) \ 2061 | if (!(condition)) { \ 2062 | JSON_FAIL_MESSAGE(message); \ 2063 | } 2064 | 2065 | #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED 2066 | 2067 | // ////////////////////////////////////////////////////////////////////// 2068 | // End of content of file: include/json/assertions.h 2069 | // ////////////////////////////////////////////////////////////////////// 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | #endif //ifndef JSON_AMALGATED_H_INCLUDED 2076 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "spider.h" 2 | #include "global.h" 3 | 4 | #include 5 | #include 6 | 7 | void show_usage() 8 | { 9 | fprintf(stderr, "Usage:\nspider -t thread_count -p save path -i start_id\n"); 10 | } 11 | 12 | void start_thread(int cnt) 13 | { 14 | pthread_t *pid = new pthread_t[cnt]; 15 | 16 | for (int i = 0; i < cnt; ++i) 17 | { 18 | if (pthread_create(&pid[i], NULL, Spider::start_spider_thread, NULL)) { 19 | fprintf(stderr, "Create server thread failed.\n"); 20 | exit(1); 21 | } 22 | } 23 | 24 | for (int i = 0; i < cnt; ++i) 25 | { 26 | pthread_join(pid[i], NULL); 27 | } 28 | 29 | delete []pid; 30 | } 31 | 32 | int main(int argc, const char*argv[]) { 33 | if (argc < 7) 34 | { 35 | show_usage(); 36 | return -1; 37 | } 38 | 39 | int thread_cnt = 0; 40 | const char* path = NULL; 41 | int start_id = 0; 42 | 43 | for (int i = 1; i < argc; ++i) 44 | { 45 | if (i % 2 == 0 || i + 1 >= argc) continue; 46 | 47 | if (strncmp(argv[i], "-t", 2) == 0) 48 | { 49 | thread_cnt = atoi(argv[i + 1]); 50 | continue; 51 | } 52 | 53 | if (strncmp(argv[i], "-p", 2) == 0) 54 | { 55 | path = argv[i + 1]; 56 | continue; 57 | } 58 | 59 | if (strncmp(argv[i], "-i", 2) == 0) 60 | { 61 | start_id = atoi(argv[i + 1]); 62 | continue; 63 | } 64 | } 65 | 66 | if (thread_cnt <= 0 || start_id <= 0 || !path || path[0] == '\0') 67 | { 68 | show_usage(); 69 | return -1; 70 | } 71 | 72 | Global* g = Global::get_instance(); 73 | if (!g->set_path(path)) 74 | { 75 | delete g; 76 | return -1; 77 | } 78 | 79 | g->set_target_start(start_id); 80 | g->init_global_env(); 81 | 82 | start_thread(thread_cnt); 83 | 84 | delete g; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | g++ -MMD -ggdb -std=c++11 -Wall -lcurl -o spider jsoncpp.cpp global.cpp spider.cpp main.cpp 2 | 3 | -------------------------------------------------------------------------------- /spider.cpp: -------------------------------------------------------------------------------- 1 | #include "spider.h" 2 | #include "global.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | Spider::Spider() 10 | { 11 | m_headers = NULL; 12 | m_json_curl = NULL; 13 | m_pic_curl = NULL; 14 | m_file = NULL; 15 | m_data_shift = 0; 16 | m_target_id = 0; 17 | } 18 | 19 | Spider::~Spider() 20 | { 21 | if (m_headers) 22 | { 23 | curl_slist_free_all(m_headers); 24 | } 25 | 26 | if (m_json_curl) 27 | { 28 | curl_easy_cleanup(m_json_curl); 29 | } 30 | 31 | if (m_pic_curl) 32 | { 33 | curl_easy_cleanup(m_pic_curl); 34 | } 35 | } 36 | 37 | void Spider::init_header() 38 | { 39 | m_headers = curl_slist_append(m_headers, "Accept-Encoding:gzip; charset=UTF-8"); 40 | m_headers = curl_slist_append(m_headers, "Accept:application/json"); 41 | m_headers = curl_slist_append(m_headers, "Accept-Language:zh-Hans-CN, en-CN, en-us;q=0.8"); 42 | m_headers = curl_slist_append(m_headers, "Authorization:Basic MTY3MDM5NTA6NHkzVzJaTVdjM01wdmpxMXQ2dHJIN1dDRWllb1JnYlh6Nkg2NmhYS0Z2WldHQkpXS2doZ0pMMmdUZFRodDhjMQ=="); 43 | m_headers = curl_slist_append(m_headers, "Connection:keep-alive"); 44 | m_headers = curl_slist_append(m_headers, "Host:api.nyx.l99.com"); 45 | m_headers = curl_slist_append(m_headers, "api-version:2"); 46 | m_headers = curl_slist_append(m_headers, "X-UDID:B22C3C4F-BDC1-46AD-A825-B5657AE49A89"); 47 | m_headers = curl_slist_append(m_headers, "X-DoveBox-API-Version:2"); 48 | m_headers = curl_slist_append(m_headers, "Accept-Language:zh-Hans-CN, en-CN, en-us;q=0.8"); 49 | m_headers = curl_slist_append(m_headers, "User-Agent:com.l99.newchuangshang/4.5.4(11828, iPhone OS 9.1, iPhone6,2, Scale/2.0"); 50 | } 51 | 52 | bool Spider::init_env() 53 | { 54 | m_json_curl = curl_easy_init(); 55 | if (!m_json_curl) 56 | { 57 | return false; 58 | } 59 | 60 | m_pic_curl = curl_easy_init(); 61 | if (!m_pic_curl) 62 | { 63 | return false; 64 | } 65 | 66 | init_header(); 67 | 68 | return true; 69 | } 70 | 71 | size_t Spider::write_json_data(void *ptr, size_t size, size_t nmemb, void *stream) 72 | { 73 | Spider* spider_ptr = (Spider*)stream; 74 | int shift = spider_ptr->get_buff_shift(); 75 | int max_size = MAX_BUFF - shift; 76 | assert(max_size >= 0); 77 | 78 | size_t res_size = size * nmemb; 79 | assert(res_size <= (size_t)max_size); 80 | 81 | char* data = spider_ptr->get_buff_ptr(); 82 | memcpy(data + shift, ptr, res_size); 83 | spider_ptr->shift_buff(res_size); 84 | 85 | FILE* file = spider_ptr->get_open_file(); 86 | if (file) 87 | { 88 | fwrite(ptr, size, nmemb, file); 89 | } 90 | 91 | return res_size; 92 | } 93 | 94 | size_t Spider::write_pic_data(void *ptr, size_t size, size_t nmemb, void *stream) 95 | { 96 | size_t res_size = size * nmemb; 97 | Spider* spider_ptr = (Spider*)stream; 98 | 99 | fwrite(ptr, size, nmemb, spider_ptr->get_open_file()); 100 | 101 | return res_size; 102 | } 103 | 104 | CURLcode Spider::perform() 105 | { 106 | reset_data_shift(); 107 | return curl_easy_perform(m_json_curl); 108 | } 109 | 110 | CURLcode Spider::json_spider(char* url, size_t max_len) 111 | { 112 | char tmp[64]; 113 | sprintf(tmp, "&target_id=%d", m_target_id); 114 | size_t len = strlen(tmp) + 1; 115 | size_t str_len = strlen(url); 116 | assert(len + str_len < max_len); 117 | strcpy(url + str_len, tmp); 118 | 119 | curl_easy_setopt(m_json_curl, CURLOPT_URL, url); 120 | //curl_easy_setopt(m_curl, CURLOPT_HTTPGET); 121 | curl_easy_setopt(m_json_curl, CURLOPT_USERAGENT, "com.l99.newchuangshang/4.5.4(11828, iPhone OS 9.1, iPhone6,2, Scale/2.0"); 122 | 123 | //curl_easy_setopt(m_curl, CURLOPT_HEADER, 1); 124 | curl_easy_setopt(m_json_curl, CURLOPT_TIMEOUT, 20); //下载超时时间 125 | curl_easy_setopt(m_json_curl, CURLOPT_CONNECTTIMEOUT, 10); //连接超时时间 126 | 127 | curl_easy_setopt(m_json_curl, CURLOPT_WRITEFUNCTION, &Spider::write_json_data); 128 | curl_easy_setopt(m_json_curl, CURLOPT_WRITEDATA, this); 129 | 130 | curl_easy_setopt(m_json_curl, CURLOPT_SSL_VERIFYPEER, 0); 131 | curl_easy_setopt(m_json_curl, CURLOPT_SSL_VERIFYHOST, 0); 132 | curl_easy_setopt(m_json_curl, CURLOPT_HTTPHEADER, m_headers); 133 | 134 | curl_easy_setopt(m_json_curl, CURLOPT_FOLLOWLOCATION, 1); 135 | 136 | return perform(); //do it 137 | } 138 | 139 | void Spider::pic_spider(const char* pic) 140 | { 141 | char path[MAX_PATH]; 142 | char url[512]; 143 | 144 | const char* pic_name = strrchr(pic, '/'); 145 | if (!pic_name) return; //pic_name = "/xxxxxx.jpg" 146 | 147 | Global* g = Global::get_instance(); 148 | const char* pic_dir = g->get_pic_path(); 149 | strncpy(path, pic_dir, MAX_PATH); 150 | strncat(path, pic_name, strlen(pic_name)); 151 | 152 | FILE *fptr = open_new_file(path); 153 | if (!fptr) return; 154 | 155 | static const char* cdn[] = { 156 | "http://7xavvq.com2.z0.glb.qiniucdn.com/", 157 | "http://7xavvn.com2.z0.glb.qiniucdn.com/" 158 | }; 159 | 160 | bool real_url = false; 161 | if (strncmp(pic, "http://", strlen("http://")) == 0) 162 | { 163 | real_url = true; 164 | } 165 | else 166 | { 167 | strncpy(url, cdn[0], 512); 168 | strcat(url, pic); 169 | } 170 | 171 | CURLcode ret = CURLE_OK; 172 | m_file = fptr; 173 | 174 | for (int i = 0; i < 2; ++i) 175 | { 176 | curl_easy_setopt(m_pic_curl, CURLOPT_URL, real_url ? pic : url); 177 | curl_easy_setopt(m_pic_curl, CURLOPT_USERAGENT, "com.l99.newchuangshang/4.5.4(11828, iPhone OS 9.1, iPhone6,2, Scale/2.0"); 178 | curl_easy_setopt(m_pic_curl, CURLOPT_TIMEOUT, 200); //设置下载超时时间 179 | curl_easy_setopt(m_pic_curl, CURLOPT_CONNECTTIMEOUT, 10); //设置连接超时时间 180 | curl_easy_setopt(m_pic_curl, CURLOPT_WRITEFUNCTION, &Spider::write_pic_data); 181 | curl_easy_setopt(m_pic_curl, CURLOPT_WRITEDATA, this); 182 | curl_easy_setopt(m_pic_curl, CURLOPT_FOLLOWLOCATION, 1); 183 | curl_easy_setopt(m_pic_curl, CURLOPT_HTTPHEADER, 0); 184 | 185 | ret = curl_easy_perform(m_pic_curl); 186 | 187 | long retcode = 200; 188 | if (ret == CURLE_OK) 189 | { 190 | ret = curl_easy_getinfo(m_pic_curl, CURLINFO_RESPONSE_CODE, &retcode); 191 | } 192 | 193 | if ((ret != CURLE_OK || retcode != 200) && i + 1 < 2 && !real_url) 194 | { 195 | strncpy(url, cdn[i + 1], 512); 196 | strcat(url, pic); 197 | rewind(fptr); 198 | } 199 | } 200 | 201 | fclose(fptr); 202 | m_file = NULL; 203 | 204 | if (ret != CURLE_OK) 205 | { 206 | remove(path); 207 | } 208 | else 209 | { 210 | g->out_log("Download pic %s success.\n", pic_name + 1); 211 | } 212 | } 213 | 214 | const char* Spider::parse_base_json() 215 | { 216 | bool ret = m_reader.parse(m_buff, m_buff + m_data_shift, m_root); 217 | if (!ret) return NULL; 218 | 219 | Global* g = Global::get_instance(); 220 | 221 | Json::Value &code = m_root["code"]; 222 | if (code == Json::nullValue) 223 | { 224 | g->out_log("parse_base_json error, code is null.\n"); 225 | return NULL; 226 | } 227 | 228 | if (code.asInt() != 1000) 229 | { 230 | Json::Value &msg = m_root["message"]; 231 | const char* str = msg != Json::nullValue ? msg.asCString() : ""; 232 | g->out_log("parse_base_json error, code is %d. msg is %s.\n", code.asInt(), str); 233 | return NULL; 234 | } 235 | 236 | Json::Value &data = m_root["data"]; 237 | if (data != Json::nullValue && data["spaceInfo"] != Json::nullValue && data["spaceInfo"]["gender"] != Json::nullValue) 238 | { 239 | Json::Value &spaceInfo = data["spaceInfo"]; 240 | int gender = spaceInfo["gender"].asInt(); 241 | if (gender != 0) //only female 242 | { 243 | return NULL; 244 | } 245 | 246 | Json::Value &photo_path = spaceInfo["photo_path"]; 247 | if (photo_path == Json::nullValue) return NULL; 248 | 249 | const char *pp = photo_path.asCString(); 250 | if (!pp) return NULL; 251 | 252 | //不要使用默认头像的资料 253 | if (strcmp(pp, "male.jpg") == 0 || strcmp(pp, "female.jpg") == 0) 254 | { 255 | g->out_log("target_id %d use defaul pic %s, pass.\n", m_target_id, pp); 256 | return NULL; 257 | } 258 | 259 | return pp; 260 | } 261 | else 262 | { 263 | g->out_log("parse_base_json error, data format wrong. target_id %d.\n", m_target_id); 264 | return NULL; 265 | } 266 | } 267 | 268 | void Spider::parse_photo_json() 269 | { 270 | bool ret = m_reader.parse(m_buff, m_buff + m_data_shift, m_root); 271 | if (!ret) return; 272 | 273 | Global* g = Global::get_instance(); 274 | 275 | Json::Value &code = m_root["code"]; 276 | if (code == Json::nullValue) 277 | { 278 | g->out_log("parse_photo_json error, code is null.\n"); 279 | return; 280 | } 281 | 282 | if (code.asInt() != 1000) 283 | { 284 | Json::Value &msg = m_root["message"]; 285 | const char* str = msg != Json::nullValue ? msg.asCString() : ""; 286 | g->out_log("parse_photo_json error, code is %d. msg is %s.\n", code.asInt(), str); 287 | return; 288 | } 289 | 290 | Json::Value &data = m_root["data"]; 291 | if (data != Json::nullValue && data["photos"] != Json::nullValue) 292 | { 293 | Json::Value &photos = data["photos"]; 294 | unsigned int size = photos.size(); 295 | for (unsigned int i = 0; i < size; ++i) 296 | { 297 | Json::Value &one_photo = photos[i]; 298 | const char* path = one_photo["path"].asCString(); 299 | pic_spider(path); 300 | } 301 | } 302 | } 303 | 304 | void Spider::parse_space_json() 305 | { 306 | bool ret = m_reader.parse(m_buff, m_buff + m_data_shift, m_root); 307 | if (!ret) return; 308 | 309 | Global* g = Global::get_instance(); 310 | Json::Value &code = m_root["code"]; 311 | if (code == Json::nullValue) 312 | { 313 | g->out_log("parse_space_json error, code is null.\n"); 314 | return; 315 | } 316 | 317 | if (code.asInt() != 200) 318 | { 319 | Json::Value &msg = m_root["message"]; 320 | const char* str = msg != Json::nullValue ? msg.asCString() : ""; 321 | g->out_log("parse_photo_json error, code is %d. msg is %s.\n", code.asInt(), str); 322 | return; 323 | } 324 | 325 | Json::Value &data = m_root["data"]; 326 | if (data != Json::nullValue && data["dashboards"] != Json::nullValue) 327 | { 328 | Json::Value &dashboards = data["dashboards"]; 329 | unsigned int size = dashboards.size(); 330 | for (unsigned int i = 0; i < size; ++i) 331 | { 332 | Json::Value &photos = dashboards[i]["text_images"]; 333 | if (photos != Json::nullValue) 334 | { 335 | unsigned int p_cnt = photos.size(); 336 | for (unsigned int j = 0; j < p_cnt; ++j) 337 | { 338 | const char* path = photos[j].asCString(); 339 | pic_spider(path); 340 | } 341 | } 342 | } 343 | } 344 | } 345 | 346 | void Spider::do_spider() 347 | { 348 | Global* g = Global::get_instance(); 349 | m_target_id = g->get_target_id(); 350 | 351 | char json[MAX_PATH]; 352 | char tmp[32]; 353 | const char* json_path = g->get_json_path(); 354 | strncpy(json, json_path, MAX_PATH); 355 | int len = strlen(json); 356 | 357 | sprintf(tmp, "/%d_base.json", m_target_id); 358 | strcat(json, tmp); 359 | 360 | FILE* fptr = open_new_file(json); 361 | if (!fptr) 362 | { 363 | g->out_log("target_id %d had downloaded. \n", m_target_id); 364 | return; 365 | } 366 | 367 | g->out_log("Target id %d start . \n", m_target_id); 368 | 369 | //基本信息 step 1 370 | char url_base[512] = { "https://api.nyx.l99.com/space/info/viewall?machine_code=B22C3C4F-BDC1-46AD-A825-B5657AE49A89&version=4.5.4&idfa=CFD0100E-C97E-4E7B-AB08-325564F2E47C&dev_token=32b3f249%20c395f65a%2059908cb0%20619a1320%209d69f4d3%20b912e5bc%20f70f2434%202ebd48f0&api_version=2&type=0&lat=23.128961&format=json&language=zh_CN&limit=20&lng=113.333376&client=key%3ABedForiPhone" }; 371 | CURLcode ret = json_spider(url_base, 512); 372 | if (ret != CURLE_OK) 373 | { 374 | fclose(fptr); 375 | remove(json); 376 | 377 | g->out_log("target_id %d get base json failed. code:%d.\n", m_target_id, ret); 378 | return; 379 | } 380 | 381 | const char* head_pic = parse_base_json(); 382 | if (!head_pic) 383 | { 384 | fclose(fptr); 385 | remove(json); 386 | return; 387 | } 388 | 389 | fwrite(m_buff, m_data_shift, 1, fptr); 390 | fclose(fptr); 391 | 392 | pic_spider(head_pic); 393 | 394 | //相册 step 2 395 | sprintf(tmp, "/%d_photo.json", m_target_id); 396 | strcpy(json + len, tmp); 397 | 398 | fptr = open_new_file(json); 399 | if (fptr) 400 | { 401 | m_file = fptr; 402 | char url_photos[512] = { "https://api.nyx.l99.com/account/photo/view?format=json&machine_code=B22C3C4F-BDC1-46AD-A825-B5657AE49A89&client=key%3ABedForiPhone&dev_token=32b3f249%20c395f65a%2059908cb0%20619a1320%209d69f4d3%20b912e5bc%20f70f2434%202ebd48f0&limit=15&language=zh_CN&version=4.5.4&lat=23.128950&lng=113.333376&idfa=CFD0100E-C97E-4E7B-AB08-325564F2E47C" }; 403 | CURLcode ret = json_spider(url_photos, 512); 404 | fclose(fptr); 405 | m_file = NULL; 406 | 407 | if (ret != CURLE_OK) 408 | { 409 | remove(json); 410 | } 411 | else 412 | { 413 | parse_photo_json(); 414 | } 415 | } 416 | 417 | //动态 step 3 418 | sprintf(tmp, "/%d_space.json", m_target_id); 419 | strcpy(json + len, tmp); 420 | 421 | fptr = open_new_file(json); 422 | if (fptr) 423 | { 424 | m_file = fptr; 425 | char url_space[512] = { "https://api.nyx.l99.com/content/dovebox/list?machine_code=B22C3C4F-BDC1-46AD-A825-B5657AE49A89&version=4.5.4&idfa=CFD0100E-C97E-4E7B-AB08-325564F2E47C&dev_token=32b3f249%20c395f65a%2059908cb0%20619a1320%209d69f4d3%20b912e5bc%20f70f2434%202ebd48f0&api_version=2&lat=23.129054&format=json&language=zh_CN&limit=20&lng=113.333431&client=key%3ABedForiPhone" }; 426 | CURLcode ret = json_spider(url_space, 512); 427 | fclose(fptr); 428 | m_file = NULL; 429 | 430 | if (ret != CURLE_OK) 431 | { 432 | remove(json); 433 | } 434 | else 435 | { 436 | parse_space_json(); 437 | } 438 | } 439 | 440 | g->add_spider_cnt(); 441 | g->out_log("Target id %d end . \n", m_target_id); 442 | } 443 | 444 | FILE* Spider::open_new_file(const char* path) 445 | { 446 | if (access(path, F_OK) == 0) 447 | { 448 | //已经有这个文件了 449 | return NULL; 450 | } 451 | 452 | FILE *fptr = fopen(path, "w"); 453 | if (!fptr) 454 | { 455 | //errno 456 | return NULL; 457 | } 458 | 459 | return fptr; 460 | } 461 | 462 | void* Spider::start_spider_thread(void* param) 463 | { 464 | Global* g = Global::get_instance(); 465 | 466 | Spider s; 467 | bool ret = s.init_env(); 468 | if (!ret) 469 | { 470 | g->out_log("init_env error, exiting... \n"); 471 | return NULL; 472 | } 473 | 474 | while (!g->is_terminated()) 475 | { 476 | s.do_spider(); 477 | } 478 | 479 | g->out_log("Exiting... \n"); 480 | return NULL; 481 | } 482 | 483 | void Spider::reset_data_shift() 484 | { 485 | m_data_shift = 0; 486 | } 487 | -------------------------------------------------------------------------------- /spider.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPIDER_H__ 2 | #define __SPIDER_H__ 3 | 4 | #include "curl/curl.h" 5 | #include "json/json.h" 6 | 7 | class Spider 8 | { 9 | public: 10 | const static int MAX_BUFF = 1024 * 512; 11 | 12 | Spider(); 13 | virtual ~Spider(); 14 | 15 | bool init_env(); 16 | 17 | CURLcode json_spider(char* url, size_t max_len); 18 | 19 | static void* start_spider_thread(void* param); 20 | 21 | static size_t write_json_data(void *ptr, size_t size, size_t nmemb, void *stream); 22 | static size_t write_pic_data(void *ptr, size_t size, size_t nmemb, void *stream); 23 | 24 | void reset_data_shift(); 25 | 26 | void pic_spider(const char* pic); 27 | 28 | void do_spider(); 29 | 30 | private: 31 | int get_buff_shift() 32 | { 33 | return m_data_shift; 34 | } 35 | 36 | void shift_buff(int shift) 37 | { 38 | m_data_shift += shift; 39 | } 40 | 41 | char* get_buff_ptr() 42 | { 43 | return m_buff; 44 | } 45 | 46 | void init_header(); 47 | 48 | CURLcode perform(); 49 | 50 | FILE* open_new_file(const char* path); 51 | 52 | FILE* get_open_file() 53 | { 54 | return m_file; 55 | } 56 | 57 | const char* parse_base_json(); 58 | void parse_photo_json(); 59 | 60 | void parse_space_json(); 61 | 62 | private: 63 | struct curl_slist *m_headers; 64 | CURL *m_json_curl; 65 | CURL *m_pic_curl; 66 | 67 | char m_buff[MAX_BUFF]; //0.5mb for store json 68 | int m_data_shift; 69 | int m_target_id; // 70 | FILE* m_file; 71 | bool m_is_pic; 72 | 73 | Json::Value m_root; 74 | Json::Reader m_reader; 75 | }; 76 | 77 | #endif 78 | --------------------------------------------------------------------------------