├── Jamroot.jam ├── LICENSE ├── README.md ├── dllmain.cpp ├── reddit-browser ├── Source.cpp ├── importer │ ├── Source.cpp │ ├── json │ │ ├── json-forwards.h │ │ └── json.h │ └── jsoncpp.cpp ├── reddit-browser.vcxproj ├── reddit-browser.vcxproj.filters └── sqlite3.c ├── sqlite3.h ├── sqlite3ext.h ├── sqltorrent.cpp ├── sqltorrent.h ├── sqltorrent.sln ├── sqltorrent.vcxproj └── sqltorrent.vcxproj.filters /Jamroot.jam: -------------------------------------------------------------------------------- 1 | import modules ; 2 | import feature : feature ; 3 | import virtual-target ; 4 | 5 | BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ; 6 | TORRENT_ROOT = [ modules.peek : TORRENT_ROOT ] ; 7 | 8 | if $(BOOST_ROOT) 9 | { 10 | use-project /boost : $(BOOST_ROOT) ; 11 | } 12 | 13 | if $(TORRENT_ROOT) 14 | { 15 | use-project /torrent : $(TORRENT_ROOT) ; 16 | } 17 | 18 | feature use-boost : system source : composite ; 19 | feature use-torrent : system source : composite ; 20 | 21 | lib torrent-rasterbar : : torrent-rasterbar shared ; 22 | 23 | lib sqltorrent 24 | : #sources 25 | sqltorrent.cpp 26 | 27 | : #requirements 28 | gcc:-std=c++11 29 | source:/torrent//torrent 30 | system:torrent-rasterbar 31 | source:$(BOOST_ROOT) 32 | 33 | # disable bogus deprecation warnings on msvc8 34 | msvc:_SCL_SECURE_NO_DEPRECATE 35 | msvc:_CRT_SECURE_NO_DEPRECATE 36 | 37 | : # default build 38 | : # usage requirements 39 | 40 | ; 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sqltorrent 2 | 3 | Sqltorrent is a custom VFS for sqlite which allows applications to query an sqlite database contained within a torrent. 4 | Queries can be processed immediately after the database has been opened, even though the database file is still being downloaded. 5 | Pieces of the file which are required to complete a query are prioritized so that queries complete reasonably quickly even if only a small fraction of the whole database has been downloaded. 6 | 7 | # Building 8 | 9 | The Visual Studio projects expect Boost and libtorrent to be available in the "boost" and "libtorrent-rasterbar" directories adjacent to the sqltorrent directory. 10 | The Boost Build jam file can be configured to build against the installed versions of Boost and libtorrent (the default) or to look for them in the directories indicated by the environment variables BOOST_ROOT and TORRENT_ROOT by setting the use-boost and use-torrent build parameters to source. 11 | 12 | # Using 13 | 14 | WARNING: sqltorrent is currently NOT thread safe. Only one query may be outstanding to any database using sqltorrent. 15 | 16 | If your application is using sqlite directly via the C/C++ interface you can call sqltorrent_init(0) to register the VFS. You can then use the VFS by calling sqlite3_open_v2 and passing the path to the .torrent file as the filename and "torrent" as the zVfs name. 17 | 18 | If your application is using sqlite via bindings which expose the sqlite3_load_extension function you can use that to load sqltorrent built as a shared library. 19 | Because loading an extension at runtime requires an open database, you will need to open an empty in-memory database and use that to load sqltorrent. 20 | Once loaded sqltorrent will become the default VFS so any non-torrented databases you want to use must be opened before you load the extension. 21 | The in-memory database you use to load sqltorrent must be kept open for as long as you have open databases using sqltorrent. 22 | 23 | # Creating torrents 24 | 25 | Sqltorrent currently only supports torrents containing a single sqlite database file. 26 | For efficiency the piece size of the torrent should be kept fairly small, around 32KB. 27 | It is also recommended to set the page size equal to the piece size when creating the sqlite database. 28 | -------------------------------------------------------------------------------- /dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | BOOL APIENTRY DllMain( HMODULE hModule, 7 | DWORD ul_reason_for_call, 8 | LPVOID lpReserved 9 | ) 10 | { 11 | switch (ul_reason_for_call) 12 | { 13 | case DLL_PROCESS_ATTACH: 14 | case DLL_THREAD_ATTACH: 15 | case DLL_THREAD_DETACH: 16 | case DLL_PROCESS_DETACH: 17 | break; 18 | } 19 | return TRUE; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /reddit-browser/Source.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 BitTorrent Inc 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "sqlite3.h" 23 | 24 | static const char by_subreddit_stmt[] = "SELECT name, author, score, parent_id, body FROM comments WHERE subreddit = ?1 LIMIT 50 OFFSET ?2"; 25 | static const char by_author_stmt[] = "SELECT name, author, score, parent_id, body FROM comments WHERE author = ?1 LIMIT 50 OFFSET ?2"; 26 | static const char by_parent_stmt[] = "SELECT name, author, score, parent_id, body FROM comments WHERE parent_id = ?1"; 27 | static const char by_name_stmt[] = "SELECT name, author, score, parent_id, body FROM comments WHERE name = ?1"; 28 | 29 | struct comment 30 | { 31 | std::string name; 32 | std::string author; 33 | std::string parent; 34 | std::string body; 35 | int score; 36 | }; 37 | 38 | void print_comment(sqlite3_stmt* q) 39 | { 40 | std::cout << sqlite3_column_text(q, 0) << " Author: " << sqlite3_column_text(q, 1) << " Score: " << sqlite3_column_int(q, 2) << " Parent: " << sqlite3_column_text(q, 3) << std::endl << sqlite3_column_text(q, 4) << std::endl << std::endl; 41 | } 42 | 43 | void print_comment_html(std::ostream& out, comment const& c) 44 | { 45 | out << "
  • " << "
    Permalink" << " Author: " << c.author << " Score: " << c.score << " Parent
    " 46 | << c.body << "
  • \n"; 47 | } 48 | 49 | void print_comments(sqlite3_stmt* q) 50 | { 51 | int rc; 52 | do 53 | { 54 | rc = sqlite3_step(q); 55 | if (rc != SQLITE_ROW) continue; 56 | print_comment(q); 57 | } while (rc == SQLITE_ROW); 58 | sqlite3_reset(q); 59 | } 60 | 61 | void print_comment_tree(sqlite3_stmt* by_parent, std::string name, int depth) 62 | { 63 | std::vector comments; 64 | sqlite3_bind_text(by_parent, 1, name.c_str(), name.size(), SQLITE_STATIC); 65 | int rc; 66 | do 67 | { 68 | rc = sqlite3_step(by_parent); 69 | if (rc != SQLITE_ROW) continue; 70 | comment c; 71 | c.name = (const char *)sqlite3_column_text(by_parent, 0); 72 | c.author = (const char *)sqlite3_column_text(by_parent, 1); 73 | c.score = sqlite3_column_int(by_parent, 2); 74 | c.parent = (const char *)sqlite3_column_text(by_parent, 3); 75 | c.body = (const char *)sqlite3_column_text(by_parent, 4); 76 | comments.push_back(c); 77 | } while (rc == SQLITE_ROW); 78 | sqlite3_reset(by_parent); 79 | 80 | for (auto const& c : comments) 81 | { 82 | std::cout << std::string(depth, ' ') << c.name << " Author: " << c.author << " Score: " << c.score << std::endl << std::string(depth, ' ') << c.body << std::endl << std::endl; 83 | print_comment_tree(by_parent, c.name, depth+1); 84 | } 85 | } 86 | 87 | void print_comment_tree_html(std::ostream& out, sqlite3_stmt* by_parent, std::string name, int depth) 88 | { 89 | std::vector comments; 90 | sqlite3_bind_text(by_parent, 1, name.c_str(), name.size(), SQLITE_STATIC); 91 | int rc; 92 | do 93 | { 94 | rc = sqlite3_step(by_parent); 95 | if (rc != SQLITE_ROW) continue; 96 | comment c; 97 | c.name = (const char *)sqlite3_column_text(by_parent, 0); 98 | c.author = (const char *)sqlite3_column_text(by_parent, 1); 99 | c.score = sqlite3_column_int(by_parent, 2); 100 | c.parent = (const char *)sqlite3_column_text(by_parent, 3); 101 | c.body = (const char *)sqlite3_column_text(by_parent, 4); 102 | comments.push_back(c); 103 | } while (rc == SQLITE_ROW); 104 | sqlite3_reset(by_parent); 105 | 106 | if (!comments.empty()) 107 | { 108 | out << "
      \n"; 109 | for (auto const& c : comments) 110 | { 111 | print_comment_html(out, c); 112 | print_comment_tree_html(out, by_parent, c.name, depth+1); 113 | } 114 | out << "
    \n"; 115 | } 116 | } 117 | 118 | void print_comments_html(std::ostream& out, sqlite3_stmt* q) 119 | { 120 | out << "
      \n"; 121 | int rc; 122 | do 123 | { 124 | rc = sqlite3_step(q); 125 | if (rc != SQLITE_ROW) continue; 126 | comment c; 127 | c.name = (const char *)sqlite3_column_text(q, 0); 128 | c.author = (const char *)sqlite3_column_text(q, 1); 129 | c.score = sqlite3_column_int(q, 2); 130 | c.parent = (const char *)sqlite3_column_text(q, 3); 131 | c.body = (const char *)sqlite3_column_text(q, 4); 132 | print_comment_html(out, c); 133 | } while (rc == SQLITE_ROW); 134 | sqlite3_reset(q); 135 | out << "
    \n"; 136 | } 137 | 138 | 139 | int main() 140 | { 141 | std::remove("data.sqlite3"); 142 | 143 | // loading VFS extensions at runtime is a little awkward 144 | // we need a database connection to load the extension but we 145 | // can't open the database with the extended VFS until it is loaded 146 | // as a kludge open an in-memory database and use it to load the 147 | // extension 148 | sqlite3* dummy_db; 149 | int rc = sqlite3_open(":memory:", &dummy_db); 150 | assert(rc == SQLITE_OK); 151 | rc = sqlite3_enable_load_extension(dummy_db, 1); 152 | assert(rc == SQLITE_OK); 153 | char* err_msg; 154 | rc = sqlite3_load_extension(dummy_db, "sqltorrent.dll", "sqlite3_sqltorrent_init", &err_msg); 155 | if (rc != SQLITE_OK) 156 | { 157 | std::cerr << "Error loading sqltorrent extension: " << err_msg << std::endl; 158 | return -1; 159 | } 160 | 161 | sqlite3* db; 162 | rc = sqlite3_open_v2("data.sqlite3.torrent", &db, SQLITE_OPEN_READONLY, NULL); 163 | assert(rc == SQLITE_OK); 164 | 165 | sqlite3_stmt* by_subreddit; 166 | rc = sqlite3_prepare_v2(db, by_subreddit_stmt, -1, &by_subreddit, NULL); 167 | assert(rc == SQLITE_OK); 168 | 169 | sqlite3_stmt* by_author; 170 | rc = sqlite3_prepare_v2(db, by_author_stmt, -1, &by_author, NULL); 171 | assert(rc == SQLITE_OK); 172 | 173 | sqlite3_stmt* by_parent; 174 | rc = sqlite3_prepare_v2(db, by_parent_stmt, -1, &by_parent, NULL); 175 | assert(rc == SQLITE_OK); 176 | 177 | sqlite3_stmt* by_name; 178 | rc = sqlite3_prepare_v2(db, by_name_stmt, -1, &by_name, NULL); 179 | assert(rc == SQLITE_OK); 180 | 181 | #if 0 182 | namespace http = boost::network::http; 183 | 184 | struct handler; 185 | typedef http::server http_server; 186 | 187 | struct handler 188 | { 189 | void operator() (http_server::request const &request, 190 | http_server::response &response) 191 | { 192 | std::vector parts; 193 | boost::split(parts, request.destination, boost::is_any_of("/")); 194 | std::stringstream out; 195 | 196 | out << "\n"; 197 | 198 | if (parts[1] == "r") 199 | { 200 | out << "\n"; 201 | sqlite3_bind_text(by_subreddit, 1, parts[2].c_str(), parts[2].size(), SQLITE_STATIC); 202 | sqlite3_bind_int(by_subreddit, 2, 0); 203 | print_comments_html(out, by_subreddit); 204 | out << "\n"; 205 | } 206 | else if (parts[1] == "u") 207 | { 208 | out << "\n"; 209 | sqlite3_bind_text(by_author, 1, parts[2].c_str(), parts[2].size(), SQLITE_STATIC); 210 | sqlite3_bind_int(by_author, 2, 0); 211 | print_comments_html(out, by_author); 212 | out << "\n"; 213 | } 214 | else if (parts[1] == "c") 215 | { 216 | sqlite3_bind_text(by_name, 1, parts[2].c_str(), parts[2].size(), SQLITE_STATIC); 217 | int rc = sqlite3_step(by_name); 218 | assert(rc = SQLITE_ROW); 219 | out << "
      "; 220 | comment c; 221 | c.name = (const char *)sqlite3_column_text(by_name, 0); 222 | c.author = (const char *)sqlite3_column_text(by_name, 1); 223 | c.score = sqlite3_column_int(by_name, 2); 224 | c.parent = (const char *)sqlite3_column_text(by_name, 3); 225 | c.body = (const char *)sqlite3_column_text(by_name, 4); 226 | print_comment_html(out, c); 227 | sqlite3_reset(by_name); 228 | print_comment_tree_html(out, by_parent, parts[2], 1); 229 | out << "
    \n"; 230 | } 231 | 232 | out << ""; 233 | 234 | response = http_server::response::stock_reply(http_server::response::ok, out.str()); 235 | } 236 | 237 | void log(http_server::string_type const& info) 238 | { 239 | std::cerr << "cpp-netlib: " << info << std::endl; 240 | } 241 | 242 | sqlite3_stmt* by_subreddit; 243 | sqlite3_stmt* by_author; 244 | sqlite3_stmt* by_parent; 245 | sqlite3_stmt* by_name; 246 | }; 247 | 248 | handler handler_; 249 | handler_.by_subreddit = by_subreddit; 250 | handler_.by_author = by_author; 251 | handler_.by_parent = by_parent; 252 | handler_.by_name = by_name; 253 | http_server::options options(handler_); 254 | http_server server_(options.address("127.0.0.1").port("8080")); 255 | server_.run(); 256 | #endif 257 | 258 | std::string cmd; 259 | do 260 | { 261 | std::cout << "$ "; 262 | std::cin >> cmd; 263 | std::vector parts; 264 | boost::split(parts, cmd, boost::is_any_of("/")); 265 | 266 | if (parts[0] == "r") 267 | { 268 | sqlite3_bind_text(by_subreddit, 1, parts[1].c_str(), parts[1].size(), SQLITE_STATIC); 269 | sqlite3_bind_int(by_subreddit, 2, 0); 270 | print_comments(by_subreddit); 271 | } 272 | else if (parts[0] == "u") 273 | { 274 | sqlite3_bind_text(by_author, 1, parts[1].c_str(), parts[1].size(), SQLITE_STATIC); 275 | sqlite3_bind_int(by_author, 2, 0); 276 | print_comments(by_author); 277 | } 278 | else if (parts[0] == "c") 279 | { 280 | sqlite3_bind_text(by_name, 1, parts[1].c_str(), parts[1].size(), SQLITE_STATIC); 281 | rc = sqlite3_step(by_name); 282 | assert(rc = SQLITE_ROW); 283 | print_comment(by_name); 284 | sqlite3_reset(by_name); 285 | print_comment_tree(by_parent, parts[1], 1); 286 | } 287 | 288 | } while (cmd != "quit"); 289 | 290 | sqlite3_close(db); 291 | sqlite3_close(dummy_db); 292 | } 293 | -------------------------------------------------------------------------------- /reddit-browser/importer/Source.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 BitTorrent Inc 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "sqlite3.h" 23 | #include "json/json.h" 24 | 25 | const static char schema[] = 26 | "PRAGMA page_size = 32768;" 27 | "PRAGMA journal_mode = OFF;" 28 | "PRAGMA synchronous = OFF;" 29 | "CREATE TABLE comments (" 30 | "name TEXT PRIMARY KEY NOT NULL," 31 | "link_id TEXT NOT NULL," 32 | "created_utc INTEGER NOT NULL," 33 | "ups INTEGER NOT NULL," 34 | "downs INTEGER NOT NULL," 35 | "gilded INTEGER NOT NULL," 36 | "author TEXT NOT NULL," 37 | "score INTEGER NOT NULL," 38 | "subreddit TEXT NOT NULL," 39 | "subreddit_id TEXT NOT NULL," 40 | "parent_id TEXT," 41 | "author_flair TEXT," 42 | "body TEXT NOT NULL);"; 43 | 44 | const static char insert_stmt[] = "INSERT INTO comments VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)"; 45 | 46 | static void bind_text(sqlite3_stmt* s, int idx, Json::Value& root, std::string name, Json::Value def = "none") 47 | { 48 | std::string tests = root.get(name, def).asString(); 49 | sqlite3_bind_text(s, idx, tests.data(), tests.size(), SQLITE_TRANSIENT); 50 | } 51 | 52 | std::set read_pages; 53 | extern "C" void count_page_read(sqlite3_int64 pagenum) 54 | { 55 | read_pages.insert(pagenum); 56 | } 57 | 58 | int callback(void* a, int b, char** c, char** d) 59 | { 60 | return 0; 61 | } 62 | 63 | int main() 64 | { 65 | std::ifstream in("data/data.json"); 66 | sqlite3* db; 67 | 68 | // std::remove("data.sqlite3"); 69 | 70 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); 71 | 72 | int rc; 73 | rc = sqlite3_open("data.sqlite3", &db); 74 | assert(rc == SQLITE_OK); 75 | 76 | rc = sqlite3_exec(db, schema, NULL, NULL, NULL); 77 | assert(rc == SQLITE_OK); 78 | 79 | sqlite3_stmt* insert; 80 | rc = sqlite3_prepare_v2(db, insert_stmt, -1, &insert, NULL); 81 | while (!in.eof()) 82 | { 83 | Json::Value root; 84 | char comment[512000]; 85 | in.getline(comment, 512000); 86 | size_t clen = std::strlen(comment); 87 | //comment[clen++] = '}'; 88 | //comment[clen] = 0; 89 | char* cstart = comment; 90 | while (cstart != comment + clen && *cstart != '{') ++cstart; 91 | if (cstart == comment + clen) continue; 92 | //std::cout << cstart << std::endl; 93 | std::stringstream cstream(cstart); 94 | cstream >> root; 95 | assert(root.type() == Json::ValueType::objectValue); 96 | bind_text(insert, 1, root, "name", Json::nullValue); 97 | bind_text(insert, 2, root, "link_id"); 98 | bind_text(insert, 3, root, "created_utc"); 99 | sqlite3_bind_int64(insert, 4, root.get("ups", 0).asInt64()); 100 | sqlite3_bind_int64(insert, 5, root.get("downs", 0).asInt64()); 101 | sqlite3_bind_int64(insert, 6, root.get("gilded", 0).asInt64()); 102 | bind_text(insert, 7, root, "author"); 103 | sqlite3_bind_int64(insert, 8, root.get("score", 0).asInt64()); 104 | bind_text(insert, 9, root, "subreddit"); 105 | bind_text(insert, 10, root, "subreddit_id"); 106 | bind_text(insert, 11, root, "parent_id", Json::nullValue); 107 | bind_text(insert, 12, root, "author_flair_text", Json::nullValue); 108 | bind_text(insert, 13, root, "body"); 109 | rc = sqlite3_step(insert); 110 | assert(rc == SQLITE_DONE); 111 | sqlite3_reset(insert); 112 | } 113 | 114 | sqlite3_finalize(insert); 115 | 116 | sqlite3_close(db); 117 | } 118 | -------------------------------------------------------------------------------- /reddit-browser/importer/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) && _MSC_VER <= 1200 // MSVC 6 145 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 146 | // (no conversion from unsigned __int64). 147 | #define JSON_USE_INT64_DOUBLE_CONVERSION 1 148 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 149 | // characters in the debug information) 150 | // All projects I've ever seen with VS6 were using this globally (not bothering 151 | // with pragma push/pop). 152 | #pragma warning(disable : 4786) 153 | #endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 154 | 155 | #if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 156 | /// Indicates that the following function is deprecated. 157 | #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 158 | #elif defined(__clang__) && defined(__has_feature) 159 | #if __has_feature(attribute_deprecated_with_message) 160 | #define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 161 | #endif 162 | #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 163 | #define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 164 | #elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 165 | #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 166 | #endif 167 | 168 | #if !defined(JSONCPP_DEPRECATED) 169 | #define JSONCPP_DEPRECATED(message) 170 | #endif // if !defined(JSONCPP_DEPRECATED) 171 | 172 | namespace Json { 173 | typedef int Int; 174 | typedef unsigned int UInt; 175 | #if defined(JSON_NO_INT64) 176 | typedef int LargestInt; 177 | typedef unsigned int LargestUInt; 178 | #undef JSON_HAS_INT64 179 | #else // if defined(JSON_NO_INT64) 180 | // For Microsoft Visual use specific types as long long is not supported 181 | #if defined(_MSC_VER) // Microsoft Visual Studio 182 | typedef __int64 Int64; 183 | typedef unsigned __int64 UInt64; 184 | #else // if defined(_MSC_VER) // Other platforms, use long long 185 | typedef long long int Int64; 186 | typedef unsigned long long int UInt64; 187 | #endif // if defined(_MSC_VER) 188 | typedef Int64 LargestInt; 189 | typedef UInt64 LargestUInt; 190 | #define JSON_HAS_INT64 191 | #endif // if defined(JSON_NO_INT64) 192 | } // end namespace Json 193 | 194 | #endif // JSON_CONFIG_H_INCLUDED 195 | 196 | // ////////////////////////////////////////////////////////////////////// 197 | // End of content of file: include/json/config.h 198 | // ////////////////////////////////////////////////////////////////////// 199 | 200 | 201 | 202 | 203 | 204 | 205 | // ////////////////////////////////////////////////////////////////////// 206 | // Beginning of content of file: include/json/forwards.h 207 | // ////////////////////////////////////////////////////////////////////// 208 | 209 | // Copyright 2007-2010 Baptiste Lepilleur 210 | // Distributed under MIT license, or public domain if desired and 211 | // recognized in your jurisdiction. 212 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 213 | 214 | #ifndef JSON_FORWARDS_H_INCLUDED 215 | #define JSON_FORWARDS_H_INCLUDED 216 | 217 | #if !defined(JSON_IS_AMALGAMATION) 218 | #include "config.h" 219 | #endif // if !defined(JSON_IS_AMALGAMATION) 220 | 221 | namespace Json { 222 | 223 | // writer.h 224 | class FastWriter; 225 | class StyledWriter; 226 | 227 | // reader.h 228 | class Reader; 229 | 230 | // features.h 231 | class Features; 232 | 233 | // value.h 234 | typedef unsigned int ArrayIndex; 235 | class StaticString; 236 | class Path; 237 | class PathArgument; 238 | class Value; 239 | class ValueIteratorBase; 240 | class ValueIterator; 241 | class ValueConstIterator; 242 | 243 | } // namespace Json 244 | 245 | #endif // JSON_FORWARDS_H_INCLUDED 246 | 247 | // ////////////////////////////////////////////////////////////////////// 248 | // End of content of file: include/json/forwards.h 249 | // ////////////////////////////////////////////////////////////////////// 250 | 251 | 252 | 253 | 254 | 255 | #endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED 256 | -------------------------------------------------------------------------------- /reddit-browser/importer/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 is generated by CMake from "version" 86 | // and "version.h.in" files. 87 | // Run CMake configure step to update it. 88 | #ifndef JSON_VERSION_H_INCLUDED 89 | # define JSON_VERSION_H_INCLUDED 90 | 91 | # define JSONCPP_VERSION_STRING "0.10.4" 92 | # define JSONCPP_VERSION_MAJOR 0 93 | # define JSONCPP_VERSION_MINOR 10 94 | # define JSONCPP_VERSION_PATCH 4 95 | # define JSONCPP_VERSION_QUALIFIER 96 | # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) 97 | 98 | #endif // JSON_VERSION_H_INCLUDED 99 | 100 | // ////////////////////////////////////////////////////////////////////// 101 | // End of content of file: include/json/version.h 102 | // ////////////////////////////////////////////////////////////////////// 103 | 104 | 105 | 106 | 107 | 108 | 109 | // ////////////////////////////////////////////////////////////////////// 110 | // Beginning of content of file: include/json/config.h 111 | // ////////////////////////////////////////////////////////////////////// 112 | 113 | // Copyright 2007-2010 Baptiste Lepilleur 114 | // Distributed under MIT license, or public domain if desired and 115 | // recognized in your jurisdiction. 116 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 117 | 118 | #ifndef JSON_CONFIG_H_INCLUDED 119 | #define JSON_CONFIG_H_INCLUDED 120 | 121 | /// If defined, indicates that json library is embedded in CppTL library. 122 | //# define JSON_IN_CPPTL 1 123 | 124 | /// If defined, indicates that json may leverage CppTL library 125 | //# define JSON_USE_CPPTL 1 126 | /// If defined, indicates that cpptl vector based map should be used instead of 127 | /// std::map 128 | /// as Value container. 129 | //# define JSON_USE_CPPTL_SMALLMAP 1 130 | 131 | // If non-zero, the library uses exceptions to report bad input instead of C 132 | // assertion macros. The default is to use exceptions. 133 | #ifndef JSON_USE_EXCEPTION 134 | #define JSON_USE_EXCEPTION 1 135 | #endif 136 | 137 | /// If defined, indicates that the source file is amalgated 138 | /// to prevent private header inclusion. 139 | /// Remarks: it is automatically defined in the generated amalgated header. 140 | // #define JSON_IS_AMALGAMATION 141 | 142 | #ifdef JSON_IN_CPPTL 143 | #include 144 | #ifndef JSON_USE_CPPTL 145 | #define JSON_USE_CPPTL 1 146 | #endif 147 | #endif 148 | 149 | #ifdef JSON_IN_CPPTL 150 | #define JSON_API CPPTL_API 151 | #elif defined(JSON_DLL_BUILD) 152 | #if defined(_MSC_VER) 153 | #define JSON_API __declspec(dllexport) 154 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 155 | #endif // if defined(_MSC_VER) 156 | #elif defined(JSON_DLL) 157 | #if defined(_MSC_VER) 158 | #define JSON_API __declspec(dllimport) 159 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 160 | #endif // if defined(_MSC_VER) 161 | #endif // ifdef JSON_IN_CPPTL 162 | #if !defined(JSON_API) 163 | #define JSON_API 164 | #endif 165 | 166 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 167 | // integer 168 | // Storages, and 64 bits integer support is disabled. 169 | // #define JSON_NO_INT64 1 170 | 171 | #if defined(_MSC_VER) && _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 // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 181 | 182 | #if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 183 | /// Indicates that the following function is deprecated. 184 | #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 185 | #elif defined(__clang__) && defined(__has_feature) 186 | #if __has_feature(attribute_deprecated_with_message) 187 | #define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 188 | #endif 189 | #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 190 | #define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 191 | #elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 192 | #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 193 | #endif 194 | 195 | #if !defined(JSONCPP_DEPRECATED) 196 | #define JSONCPP_DEPRECATED(message) 197 | #endif // if !defined(JSONCPP_DEPRECATED) 198 | 199 | namespace Json { 200 | typedef int Int; 201 | typedef unsigned int UInt; 202 | #if defined(JSON_NO_INT64) 203 | typedef int LargestInt; 204 | typedef unsigned int LargestUInt; 205 | #undef JSON_HAS_INT64 206 | #else // if defined(JSON_NO_INT64) 207 | // For Microsoft Visual use specific types as long long is not supported 208 | #if defined(_MSC_VER) // Microsoft Visual Studio 209 | typedef __int64 Int64; 210 | typedef unsigned __int64 UInt64; 211 | #else // if defined(_MSC_VER) // Other platforms, use long long 212 | typedef long long int Int64; 213 | typedef unsigned long long int UInt64; 214 | #endif // if defined(_MSC_VER) 215 | typedef Int64 LargestInt; 216 | typedef UInt64 LargestUInt; 217 | #define JSON_HAS_INT64 218 | #endif // if defined(JSON_NO_INT64) 219 | } // end namespace Json 220 | 221 | #endif // JSON_CONFIG_H_INCLUDED 222 | 223 | // ////////////////////////////////////////////////////////////////////// 224 | // End of content of file: include/json/config.h 225 | // ////////////////////////////////////////////////////////////////////// 226 | 227 | 228 | 229 | 230 | 231 | 232 | // ////////////////////////////////////////////////////////////////////// 233 | // Beginning of content of file: include/json/forwards.h 234 | // ////////////////////////////////////////////////////////////////////// 235 | 236 | // Copyright 2007-2010 Baptiste Lepilleur 237 | // Distributed under MIT license, or public domain if desired and 238 | // recognized in your jurisdiction. 239 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 240 | 241 | #ifndef JSON_FORWARDS_H_INCLUDED 242 | #define JSON_FORWARDS_H_INCLUDED 243 | 244 | #if !defined(JSON_IS_AMALGAMATION) 245 | #include "config.h" 246 | #endif // if !defined(JSON_IS_AMALGAMATION) 247 | 248 | namespace Json { 249 | 250 | // writer.h 251 | class FastWriter; 252 | class StyledWriter; 253 | 254 | // reader.h 255 | class Reader; 256 | 257 | // features.h 258 | class Features; 259 | 260 | // value.h 261 | typedef unsigned int ArrayIndex; 262 | class StaticString; 263 | class Path; 264 | class PathArgument; 265 | class Value; 266 | class ValueIteratorBase; 267 | class ValueIterator; 268 | class ValueConstIterator; 269 | 270 | } // namespace Json 271 | 272 | #endif // JSON_FORWARDS_H_INCLUDED 273 | 274 | // ////////////////////////////////////////////////////////////////////// 275 | // End of content of file: include/json/forwards.h 276 | // ////////////////////////////////////////////////////////////////////// 277 | 278 | 279 | 280 | 281 | 282 | 283 | // ////////////////////////////////////////////////////////////////////// 284 | // Beginning of content of file: include/json/features.h 285 | // ////////////////////////////////////////////////////////////////////// 286 | 287 | // Copyright 2007-2010 Baptiste Lepilleur 288 | // Distributed under MIT license, or public domain if desired and 289 | // recognized in your jurisdiction. 290 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 291 | 292 | #ifndef CPPTL_JSON_FEATURES_H_INCLUDED 293 | #define CPPTL_JSON_FEATURES_H_INCLUDED 294 | 295 | #if !defined(JSON_IS_AMALGAMATION) 296 | #include "forwards.h" 297 | #endif // if !defined(JSON_IS_AMALGAMATION) 298 | 299 | namespace Json { 300 | 301 | /** \brief Configuration passed to reader and writer. 302 | * This configuration object can be used to force the Reader or Writer 303 | * to behave in a standard conforming way. 304 | */ 305 | class JSON_API Features { 306 | public: 307 | /** \brief A configuration that allows all features and assumes all strings 308 | * are UTF-8. 309 | * - C & C++ comments are allowed 310 | * - Root object can be any JSON value 311 | * - Assumes Value strings are encoded in UTF-8 312 | */ 313 | static Features all(); 314 | 315 | /** \brief A configuration that is strictly compatible with the JSON 316 | * specification. 317 | * - Comments are forbidden. 318 | * - Root object must be either an array or an object value. 319 | * - Assumes Value strings are encoded in UTF-8 320 | */ 321 | static Features strictMode(); 322 | 323 | /** \brief Initialize the configuration like JsonConfig::allFeatures; 324 | */ 325 | Features(); 326 | 327 | /// \c true if comments are allowed. Default: \c true. 328 | bool allowComments_; 329 | 330 | /// \c true if root must be either an array or an object value. Default: \c 331 | /// false. 332 | bool strictRoot_; 333 | }; 334 | 335 | } // namespace Json 336 | 337 | #endif // CPPTL_JSON_FEATURES_H_INCLUDED 338 | 339 | // ////////////////////////////////////////////////////////////////////// 340 | // End of content of file: include/json/features.h 341 | // ////////////////////////////////////////////////////////////////////// 342 | 343 | 344 | 345 | 346 | 347 | 348 | // ////////////////////////////////////////////////////////////////////// 349 | // Beginning of content of file: include/json/value.h 350 | // ////////////////////////////////////////////////////////////////////// 351 | 352 | // Copyright 2007-2010 Baptiste Lepilleur 353 | // Distributed under MIT license, or public domain if desired and 354 | // recognized in your jurisdiction. 355 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 356 | 357 | #ifndef CPPTL_JSON_H_INCLUDED 358 | #define CPPTL_JSON_H_INCLUDED 359 | 360 | #if !defined(JSON_IS_AMALGAMATION) 361 | #include "forwards.h" 362 | #endif // if !defined(JSON_IS_AMALGAMATION) 363 | #include 364 | #include 365 | #include 366 | 367 | #ifndef JSON_USE_CPPTL_SMALLMAP 368 | #include 369 | #else 370 | #include 371 | #endif 372 | #ifdef JSON_USE_CPPTL 373 | #include 374 | #endif 375 | 376 | // Disable warning C4251: : needs to have dll-interface to 377 | // be used by... 378 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 379 | #pragma warning(push) 380 | #pragma warning(disable : 4251) 381 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 382 | 383 | /** \brief JSON (JavaScript Object Notation). 384 | */ 385 | namespace Json { 386 | 387 | /** Base class for all exceptions we throw. 388 | * 389 | * We use nothing but these internally. Of course, STL can throw others. 390 | */ 391 | class JSON_API Exception; 392 | /** Exceptions which the user cannot easily avoid. 393 | * 394 | * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input 395 | * 396 | * \remark derived from Json::Exception 397 | */ 398 | class JSON_API RuntimeError; 399 | /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. 400 | * 401 | * These are precondition-violations (user bugs) and internal errors (our bugs). 402 | * 403 | * \remark derived from Json::Exception 404 | */ 405 | class JSON_API LogicError; 406 | 407 | /// used internally 408 | void throwRuntimeError(std::string const& msg); 409 | /// used internally 410 | void throwLogicError(std::string const& msg); 411 | 412 | /** \brief Type of the value held by a Value object. 413 | */ 414 | enum ValueType { 415 | nullValue = 0, ///< 'null' value 416 | intValue, ///< signed integer value 417 | uintValue, ///< unsigned integer value 418 | realValue, ///< double value 419 | stringValue, ///< UTF-8 string value 420 | booleanValue, ///< bool value 421 | arrayValue, ///< array value (ordered list) 422 | objectValue ///< object value (collection of name/value pairs). 423 | }; 424 | 425 | enum CommentPlacement { 426 | commentBefore = 0, ///< a comment placed on the line before a value 427 | commentAfterOnSameLine, ///< a comment just after a value on the same line 428 | commentAfter, ///< a comment on the line after a value (only make sense for 429 | /// root value) 430 | numberOfCommentPlacement 431 | }; 432 | 433 | //# ifdef JSON_USE_CPPTL 434 | // typedef CppTL::AnyEnumerator EnumMemberNames; 435 | // typedef CppTL::AnyEnumerator EnumValues; 436 | //# endif 437 | 438 | /** \brief Lightweight wrapper to tag static string. 439 | * 440 | * Value constructor and objectValue member assignement takes advantage of the 441 | * StaticString and avoid the cost of string duplication when storing the 442 | * string or the member name. 443 | * 444 | * Example of usage: 445 | * \code 446 | * Json::Value aValue( StaticString("some text") ); 447 | * Json::Value object; 448 | * static const StaticString code("code"); 449 | * object[code] = 1234; 450 | * \endcode 451 | */ 452 | class JSON_API StaticString { 453 | public: 454 | explicit StaticString(const char* czstring) : c_str_(czstring) {} 455 | 456 | operator const char*() const { return c_str_; } 457 | 458 | const char* c_str() const { return c_str_; } 459 | 460 | private: 461 | const char* c_str_; 462 | }; 463 | 464 | /** \brief Represents a JSON value. 465 | * 466 | * This class is a discriminated union wrapper that can represents a: 467 | * - signed integer [range: Value::minInt - Value::maxInt] 468 | * - unsigned integer (range: 0 - Value::maxUInt) 469 | * - double 470 | * - UTF-8 string 471 | * - boolean 472 | * - 'null' 473 | * - an ordered list of Value 474 | * - collection of name/value pairs (javascript object) 475 | * 476 | * The type of the held value is represented by a #ValueType and 477 | * can be obtained using type(). 478 | * 479 | * Values of an #objectValue or #arrayValue can be accessed using operator[]() 480 | * methods. 481 | * Non-const methods will automatically create the a #nullValue element 482 | * if it does not exist. 483 | * The sequence of an #arrayValue will be automatically resized and initialized 484 | * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. 485 | * 486 | * The get() methods can be used to obtain default value in the case the 487 | * required element does not exist. 488 | * 489 | * It is possible to iterate over the list of a #objectValue values using 490 | * the getMemberNames() method. 491 | * 492 | * \note #Value string-length fit in size_t, but keys must be < 2^30. 493 | * (The reason is an implementation detail.) A #CharReader will raise an 494 | * exception if a bound is exceeded to avoid security holes in your app, 495 | * but the Value API does *not* check bounds. That is the responsibility 496 | * of the caller. 497 | */ 498 | class JSON_API Value { 499 | friend class ValueIteratorBase; 500 | public: 501 | typedef std::vector Members; 502 | typedef ValueIterator iterator; 503 | typedef ValueConstIterator const_iterator; 504 | typedef Json::UInt UInt; 505 | typedef Json::Int Int; 506 | #if defined(JSON_HAS_INT64) 507 | typedef Json::UInt64 UInt64; 508 | typedef Json::Int64 Int64; 509 | #endif // defined(JSON_HAS_INT64) 510 | typedef Json::LargestInt LargestInt; 511 | typedef Json::LargestUInt LargestUInt; 512 | typedef Json::ArrayIndex ArrayIndex; 513 | 514 | static const Value& nullRef; 515 | #if !defined(__ARMEL__) 516 | /// \deprecated This exists for binary compatibility only. Use nullRef. 517 | static const Value null; 518 | #endif 519 | /// Minimum signed integer value that can be stored in a Json::Value. 520 | static const LargestInt minLargestInt; 521 | /// Maximum signed integer value that can be stored in a Json::Value. 522 | static const LargestInt maxLargestInt; 523 | /// Maximum unsigned integer value that can be stored in a Json::Value. 524 | static const LargestUInt maxLargestUInt; 525 | 526 | /// Minimum signed int value that can be stored in a Json::Value. 527 | static const Int minInt; 528 | /// Maximum signed int value that can be stored in a Json::Value. 529 | static const Int maxInt; 530 | /// Maximum unsigned int value that can be stored in a Json::Value. 531 | static const UInt maxUInt; 532 | 533 | #if defined(JSON_HAS_INT64) 534 | /// Minimum signed 64 bits int value that can be stored in a Json::Value. 535 | static const Int64 minInt64; 536 | /// Maximum signed 64 bits int value that can be stored in a Json::Value. 537 | static const Int64 maxInt64; 538 | /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. 539 | static const UInt64 maxUInt64; 540 | #endif // defined(JSON_HAS_INT64) 541 | 542 | private: 543 | #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 544 | class CZString { 545 | public: 546 | enum DuplicationPolicy { 547 | noDuplication = 0, 548 | duplicate, 549 | duplicateOnCopy 550 | }; 551 | CZString(ArrayIndex index); 552 | CZString(char const* str, unsigned length, DuplicationPolicy allocate); 553 | CZString(CZString const& other); 554 | ~CZString(); 555 | CZString& operator=(CZString other); 556 | bool operator<(CZString const& other) const; 557 | bool operator==(CZString const& other) const; 558 | ArrayIndex index() const; 559 | //const char* c_str() const; ///< \deprecated 560 | char const* data() const; 561 | unsigned length() const; 562 | bool isStaticString() const; 563 | 564 | private: 565 | void swap(CZString& other); 566 | 567 | struct StringStorage { 568 | unsigned policy_: 2; 569 | unsigned length_: 30; // 1GB max 570 | }; 571 | 572 | char const* cstr_; // actually, a prefixed string, unless policy is noDup 573 | union { 574 | ArrayIndex index_; 575 | StringStorage storage_; 576 | }; 577 | }; 578 | 579 | public: 580 | #ifndef JSON_USE_CPPTL_SMALLMAP 581 | typedef std::map ObjectValues; 582 | #else 583 | typedef CppTL::SmallMap ObjectValues; 584 | #endif // ifndef JSON_USE_CPPTL_SMALLMAP 585 | #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 586 | 587 | public: 588 | /** \brief Create a default Value of the given type. 589 | 590 | This is a very useful constructor. 591 | To create an empty array, pass arrayValue. 592 | To create an empty object, pass objectValue. 593 | Another Value can then be set to this one by assignment. 594 | This is useful since clear() and resize() will not alter types. 595 | 596 | Examples: 597 | \code 598 | Json::Value null_value; // null 599 | Json::Value arr_value(Json::arrayValue); // [] 600 | Json::Value obj_value(Json::objectValue); // {} 601 | \endcode 602 | */ 603 | Value(ValueType type = nullValue); 604 | Value(Int value); 605 | Value(UInt value); 606 | #if defined(JSON_HAS_INT64) 607 | Value(Int64 value); 608 | Value(UInt64 value); 609 | #endif // if defined(JSON_HAS_INT64) 610 | Value(double value); 611 | Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) 612 | Value(const char* beginValue, const char* endValue); ///< Copy all, incl zeroes. 613 | /** \brief Constructs a value from a static string. 614 | 615 | * Like other value string constructor but do not duplicate the string for 616 | * internal storage. The given string must remain alive after the call to this 617 | * constructor. 618 | * \note This works only for null-terminated strings. (We cannot change the 619 | * size of this class, so we have nowhere to store the length, 620 | * which might be computed later for various operations.) 621 | * 622 | * Example of usage: 623 | * \code 624 | * static StaticString foo("some text"); 625 | * Json::Value aValue(foo); 626 | * \endcode 627 | */ 628 | Value(const StaticString& value); 629 | Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too. 630 | #ifdef JSON_USE_CPPTL 631 | Value(const CppTL::ConstString& value); 632 | #endif 633 | Value(bool value); 634 | /// Deep copy. 635 | Value(const Value& other); 636 | ~Value(); 637 | 638 | /// Deep copy, then swap(other). 639 | /// \note Over-write existing comments. To preserve comments, use #swapPayload(). 640 | Value &operator=(const Value &other); 641 | /// Swap everything. 642 | void swap(Value& other); 643 | /// Swap values but leave comments and source offsets in place. 644 | void swapPayload(Value& other); 645 | 646 | ValueType type() const; 647 | 648 | /// Compare payload only, not comments etc. 649 | bool operator<(const Value& other) const; 650 | bool operator<=(const Value& other) const; 651 | bool operator>=(const Value& other) const; 652 | bool operator>(const Value& other) const; 653 | bool operator==(const Value& other) const; 654 | bool operator!=(const Value& other) const; 655 | int compare(const Value& other) const; 656 | 657 | const char* asCString() const; ///< Embedded zeroes could cause you trouble! 658 | std::string asString() const; ///< Embedded zeroes are possible. 659 | /** Get raw char* of string-value. 660 | * \return false if !string. (Seg-fault if str or end are NULL.) 661 | */ 662 | bool getString( 663 | char const** str, char const** end) const; 664 | #ifdef JSON_USE_CPPTL 665 | CppTL::ConstString asConstString() const; 666 | #endif 667 | Int asInt() const; 668 | UInt asUInt() const; 669 | #if defined(JSON_HAS_INT64) 670 | Int64 asInt64() const; 671 | UInt64 asUInt64() const; 672 | #endif // if defined(JSON_HAS_INT64) 673 | LargestInt asLargestInt() const; 674 | LargestUInt asLargestUInt() const; 675 | float asFloat() const; 676 | double asDouble() const; 677 | bool asBool() const; 678 | 679 | bool isNull() const; 680 | bool isBool() const; 681 | bool isInt() const; 682 | bool isInt64() const; 683 | bool isUInt() const; 684 | bool isUInt64() const; 685 | bool isIntegral() const; 686 | bool isDouble() const; 687 | bool isNumeric() const; 688 | bool isString() const; 689 | bool isArray() const; 690 | bool isObject() const; 691 | 692 | bool isConvertibleTo(ValueType other) const; 693 | 694 | /// Number of values in array or object 695 | ArrayIndex size() const; 696 | 697 | /// \brief Return true if empty array, empty object, or null; 698 | /// otherwise, false. 699 | bool empty() const; 700 | 701 | /// Return isNull() 702 | bool operator!() const; 703 | 704 | /// Remove all object members and array elements. 705 | /// \pre type() is arrayValue, objectValue, or nullValue 706 | /// \post type() is unchanged 707 | void clear(); 708 | 709 | /// Resize the array to size elements. 710 | /// New elements are initialized to null. 711 | /// May only be called on nullValue or arrayValue. 712 | /// \pre type() is arrayValue or nullValue 713 | /// \post type() is arrayValue 714 | void resize(ArrayIndex size); 715 | 716 | /// Access an array element (zero based index ). 717 | /// If the array contains less than index element, then null value are 718 | /// inserted 719 | /// in the array so that its size is index+1. 720 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 721 | /// this from the operator[] which takes a string.) 722 | Value& operator[](ArrayIndex index); 723 | 724 | /// Access an array element (zero based index ). 725 | /// If the array contains less than index element, then null value are 726 | /// inserted 727 | /// in the array so that its size is index+1. 728 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 729 | /// this from the operator[] which takes a string.) 730 | Value& operator[](int index); 731 | 732 | /// Access an array element (zero based index ) 733 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 734 | /// this from the operator[] which takes a string.) 735 | const Value& operator[](ArrayIndex index) const; 736 | 737 | /// Access an array element (zero based index ) 738 | /// (You may need to say 'value[0u]' to get your compiler to distinguish 739 | /// this from the operator[] which takes a string.) 740 | const Value& operator[](int index) const; 741 | 742 | /// If the array contains at least index+1 elements, returns the element 743 | /// value, 744 | /// otherwise returns defaultValue. 745 | Value get(ArrayIndex index, const Value& defaultValue) const; 746 | /// Return true if index < size(). 747 | bool isValidIndex(ArrayIndex index) const; 748 | /// \brief Append value to array at the end. 749 | /// 750 | /// Equivalent to jsonvalue[jsonvalue.size()] = value; 751 | Value& append(const Value& value); 752 | 753 | /// Access an object value by name, create a null member if it does not exist. 754 | /// \note Because of our implementation, keys are limited to 2^30 -1 chars. 755 | /// Exceeding that will cause an exception. 756 | Value& operator[](const char* key); 757 | /// Access an object value by name, returns null if there is no member with 758 | /// that name. 759 | const Value& operator[](const char* key) const; 760 | /// Access an object value by name, create a null member if it does not exist. 761 | /// \param key may contain embedded nulls. 762 | Value& operator[](const std::string& key); 763 | /// Access an object value by name, returns null if there is no member with 764 | /// that name. 765 | /// \param key may contain embedded nulls. 766 | const Value& operator[](const std::string& key) const; 767 | /** \brief Access an object value by name, create a null member if it does not 768 | exist. 769 | 770 | * If the object has no entry for that name, then the member name used to store 771 | * the new entry is not duplicated. 772 | * Example of use: 773 | * \code 774 | * Json::Value object; 775 | * static const StaticString code("code"); 776 | * object[code] = 1234; 777 | * \endcode 778 | */ 779 | Value& operator[](const StaticString& key); 780 | #ifdef JSON_USE_CPPTL 781 | /// Access an object value by name, create a null member if it does not exist. 782 | Value& operator[](const CppTL::ConstString& key); 783 | /// Access an object value by name, returns null if there is no member with 784 | /// that name. 785 | const Value& operator[](const CppTL::ConstString& key) const; 786 | #endif 787 | /// Return the member named key if it exist, defaultValue otherwise. 788 | /// \note deep copy 789 | Value get(const char* key, const Value& defaultValue) const; 790 | /// Return the member named key if it exist, defaultValue otherwise. 791 | /// \note deep copy 792 | /// \param key may contain embedded nulls. 793 | Value get(const char* key, const char* end, const Value& defaultValue) const; 794 | /// Return the member named key if it exist, defaultValue otherwise. 795 | /// \note deep copy 796 | /// \param key may contain embedded nulls. 797 | Value get(const std::string& key, const Value& defaultValue) const; 798 | #ifdef JSON_USE_CPPTL 799 | /// Return the member named key if it exist, defaultValue otherwise. 800 | /// \note deep copy 801 | Value get(const CppTL::ConstString& key, const Value& defaultValue) const; 802 | #endif 803 | /// Most general and efficient version of isMember()const, get()const, 804 | /// and operator[]const 805 | /// \note As stated elsewhere, behavior is undefined if (end-key) >= 2^30 806 | Value const* find(char const* key, char const* end) const; 807 | /// Most general and efficient version of object-mutators. 808 | /// \note As stated elsewhere, behavior is undefined if (end-key) >= 2^30 809 | /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. 810 | Value const* demand(char const* key, char const* end); 811 | /// \brief Remove and return the named member. 812 | /// 813 | /// Do nothing if it did not exist. 814 | /// \return the removed Value, or null. 815 | /// \pre type() is objectValue or nullValue 816 | /// \post type() is unchanged 817 | /// \deprecated 818 | Value removeMember(const char* key); 819 | /// Same as removeMember(const char*) 820 | /// \param key may contain embedded nulls. 821 | /// \deprecated 822 | Value removeMember(const std::string& key); 823 | /// Same as removeMember(const char* key, const char* end, Value* removed), 824 | /// but 'key' is null-terminated. 825 | bool removeMember(const char* key, Value* removed); 826 | /** \brief Remove the named map member. 827 | 828 | Update 'removed' iff removed. 829 | \param key may contain embedded nulls. 830 | \return true iff removed (no exceptions) 831 | */ 832 | bool removeMember(std::string const& key, Value* removed); 833 | /// Same as removeMember(std::string const& key, Value* removed) 834 | bool removeMember(const char* key, const char* end, Value* removed); 835 | /** \brief Remove the indexed array element. 836 | 837 | O(n) expensive operations. 838 | Update 'removed' iff removed. 839 | \return true iff removed (no exceptions) 840 | */ 841 | bool removeIndex(ArrayIndex i, Value* removed); 842 | 843 | /// Return true if the object has a member named key. 844 | /// \note 'key' must be null-terminated. 845 | bool isMember(const char* key) const; 846 | /// Return true if the object has a member named key. 847 | /// \param key may contain embedded nulls. 848 | bool isMember(const std::string& key) const; 849 | /// Same as isMember(std::string const& key)const 850 | bool isMember(const char* key, const char* end) const; 851 | #ifdef JSON_USE_CPPTL 852 | /// Return true if the object has a member named key. 853 | bool isMember(const CppTL::ConstString& key) const; 854 | #endif 855 | 856 | /// \brief Return a list of the member names. 857 | /// 858 | /// If null, return an empty list. 859 | /// \pre type() is objectValue or nullValue 860 | /// \post if type() was nullValue, it remains nullValue 861 | Members getMemberNames() const; 862 | 863 | //# ifdef JSON_USE_CPPTL 864 | // EnumMemberNames enumMemberNames() const; 865 | // EnumValues enumValues() const; 866 | //# endif 867 | 868 | /// \deprecated Always pass len. 869 | JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.") 870 | void setComment(const char* comment, CommentPlacement placement); 871 | /// Comments must be //... or /* ... */ 872 | void setComment(const char* comment, size_t len, CommentPlacement placement); 873 | /// Comments must be //... or /* ... */ 874 | void setComment(const std::string& comment, CommentPlacement placement); 875 | bool hasComment(CommentPlacement placement) const; 876 | /// Include delimiters and embedded newlines. 877 | std::string getComment(CommentPlacement placement) const; 878 | 879 | std::string toStyledString() const; 880 | 881 | const_iterator begin() const; 882 | const_iterator end() const; 883 | 884 | iterator begin(); 885 | iterator end(); 886 | 887 | private: 888 | void initBasic(ValueType type, bool allocated = false); 889 | 890 | Value& resolveReference(const char* key); 891 | Value& resolveReference(const char* key, const char* end); 892 | 893 | struct CommentInfo { 894 | CommentInfo(); 895 | ~CommentInfo(); 896 | 897 | void setComment(const char* text, size_t len); 898 | 899 | char* comment_; 900 | }; 901 | 902 | // struct MemberNamesTransform 903 | //{ 904 | // typedef const char *result_type; 905 | // const char *operator()( const CZString &name ) const 906 | // { 907 | // return name.c_str(); 908 | // } 909 | //}; 910 | 911 | union ValueHolder { 912 | LargestInt int_; 913 | LargestUInt uint_; 914 | double real_; 915 | bool bool_; 916 | char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ 917 | ObjectValues* map_; 918 | } value_; 919 | ValueType type_ : 8; 920 | unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. 921 | // If not allocated_, string_ must be null-terminated. 922 | CommentInfo* comments_; 923 | }; 924 | 925 | /** \brief Experimental and untested: represents an element of the "path" to 926 | * access a node. 927 | */ 928 | class JSON_API PathArgument { 929 | public: 930 | friend class Path; 931 | 932 | PathArgument(); 933 | PathArgument(ArrayIndex index); 934 | PathArgument(const char* key); 935 | PathArgument(const std::string& key); 936 | 937 | private: 938 | enum Kind { 939 | kindNone = 0, 940 | kindIndex, 941 | kindKey 942 | }; 943 | std::string key_; 944 | ArrayIndex index_; 945 | Kind kind_; 946 | }; 947 | 948 | /** \brief Experimental and untested: represents a "path" to access a node. 949 | * 950 | * Syntax: 951 | * - "." => root node 952 | * - ".[n]" => elements at index 'n' of root node (an array value) 953 | * - ".name" => member named 'name' of root node (an object value) 954 | * - ".name1.name2.name3" 955 | * - ".[0][1][2].name1[3]" 956 | * - ".%" => member name is provided as parameter 957 | * - ".[%]" => index is provied as parameter 958 | */ 959 | class JSON_API Path { 960 | public: 961 | Path(const std::string& path, 962 | const PathArgument& a1 = PathArgument(), 963 | const PathArgument& a2 = PathArgument(), 964 | const PathArgument& a3 = PathArgument(), 965 | const PathArgument& a4 = PathArgument(), 966 | const PathArgument& a5 = PathArgument()); 967 | 968 | const Value& resolve(const Value& root) const; 969 | Value resolve(const Value& root, const Value& defaultValue) const; 970 | /// Creates the "path" to access the specified node and returns a reference on 971 | /// the node. 972 | Value& make(Value& root) const; 973 | 974 | private: 975 | typedef std::vector InArgs; 976 | typedef std::vector Args; 977 | 978 | void makePath(const std::string& path, const InArgs& in); 979 | void addPathInArg(const std::string& path, 980 | const InArgs& in, 981 | InArgs::const_iterator& itInArg, 982 | PathArgument::Kind kind); 983 | void invalidPath(const std::string& path, int location); 984 | 985 | Args args_; 986 | }; 987 | 988 | /** \brief base class for Value iterators. 989 | * 990 | */ 991 | class JSON_API ValueIteratorBase { 992 | public: 993 | typedef std::bidirectional_iterator_tag iterator_category; 994 | typedef unsigned int size_t; 995 | typedef int difference_type; 996 | typedef ValueIteratorBase SelfType; 997 | 998 | bool operator==(const SelfType& other) const { return isEqual(other); } 999 | 1000 | bool operator!=(const SelfType& other) const { return !isEqual(other); } 1001 | 1002 | difference_type operator-(const SelfType& other) const { 1003 | return other.computeDistance(*this); 1004 | } 1005 | 1006 | /// Return either the index or the member name of the referenced value as a 1007 | /// Value. 1008 | Value key() const; 1009 | 1010 | /// Return the index of the referenced Value, or -1 if it is not an arrayValue. 1011 | UInt index() const; 1012 | 1013 | /// Return the member name of the referenced Value, or "" if it is not an 1014 | /// objectValue. 1015 | /// \note Avoid `c_str()` on result, as embedded zeroes are possible. 1016 | std::string name() const; 1017 | 1018 | /// Return the member name of the referenced Value. "" if it is not an 1019 | /// objectValue. 1020 | /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. 1021 | JSONCPP_DEPRECATED("Use `key = name();` instead.") 1022 | char const* memberName() const; 1023 | /// Return the member name of the referenced Value, or NULL if it is not an 1024 | /// objectValue. 1025 | /// \note Better version than memberName(). Allows embedded nulls. 1026 | char const* memberName(char const** end) const; 1027 | 1028 | protected: 1029 | Value& deref() const; 1030 | 1031 | void increment(); 1032 | 1033 | void decrement(); 1034 | 1035 | difference_type computeDistance(const SelfType& other) const; 1036 | 1037 | bool isEqual(const SelfType& other) const; 1038 | 1039 | void copy(const SelfType& other); 1040 | 1041 | private: 1042 | Value::ObjectValues::iterator current_; 1043 | // Indicates that iterator is for a null value. 1044 | bool isNull_; 1045 | 1046 | public: 1047 | // For some reason, BORLAND needs these at the end, rather 1048 | // than earlier. No idea why. 1049 | ValueIteratorBase(); 1050 | explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); 1051 | }; 1052 | 1053 | /** \brief const iterator for object and array value. 1054 | * 1055 | */ 1056 | class JSON_API ValueConstIterator : public ValueIteratorBase { 1057 | friend class Value; 1058 | 1059 | public: 1060 | typedef const Value value_type; 1061 | //typedef unsigned int size_t; 1062 | //typedef int difference_type; 1063 | typedef const Value& reference; 1064 | typedef const Value* pointer; 1065 | typedef ValueConstIterator SelfType; 1066 | 1067 | ValueConstIterator(); 1068 | 1069 | private: 1070 | /*! \internal Use by Value to create an iterator. 1071 | */ 1072 | explicit ValueConstIterator(const Value::ObjectValues::iterator& current); 1073 | public: 1074 | SelfType& operator=(const ValueIteratorBase& other); 1075 | 1076 | SelfType operator++(int) { 1077 | SelfType temp(*this); 1078 | ++*this; 1079 | return temp; 1080 | } 1081 | 1082 | SelfType operator--(int) { 1083 | SelfType temp(*this); 1084 | --*this; 1085 | return temp; 1086 | } 1087 | 1088 | SelfType& operator--() { 1089 | decrement(); 1090 | return *this; 1091 | } 1092 | 1093 | SelfType& operator++() { 1094 | increment(); 1095 | return *this; 1096 | } 1097 | 1098 | reference operator*() const { return deref(); } 1099 | 1100 | pointer operator->() const { return &deref(); } 1101 | }; 1102 | 1103 | /** \brief Iterator for object and array value. 1104 | */ 1105 | class JSON_API ValueIterator : public ValueIteratorBase { 1106 | friend class Value; 1107 | 1108 | public: 1109 | typedef Value value_type; 1110 | typedef unsigned int size_t; 1111 | typedef int difference_type; 1112 | typedef Value& reference; 1113 | typedef Value* pointer; 1114 | typedef ValueIterator SelfType; 1115 | 1116 | ValueIterator(); 1117 | ValueIterator(const ValueConstIterator& other); 1118 | ValueIterator(const ValueIterator& other); 1119 | 1120 | private: 1121 | /*! \internal Use by Value to create an iterator. 1122 | */ 1123 | explicit ValueIterator(const Value::ObjectValues::iterator& current); 1124 | public: 1125 | SelfType& operator=(const SelfType& other); 1126 | 1127 | SelfType operator++(int) { 1128 | SelfType temp(*this); 1129 | ++*this; 1130 | return temp; 1131 | } 1132 | 1133 | SelfType operator--(int) { 1134 | SelfType temp(*this); 1135 | --*this; 1136 | return temp; 1137 | } 1138 | 1139 | SelfType& operator--() { 1140 | decrement(); 1141 | return *this; 1142 | } 1143 | 1144 | SelfType& operator++() { 1145 | increment(); 1146 | return *this; 1147 | } 1148 | 1149 | reference operator*() const { return deref(); } 1150 | 1151 | pointer operator->() const { return &deref(); } 1152 | }; 1153 | 1154 | } // namespace Json 1155 | 1156 | 1157 | namespace std { 1158 | /// Specialize std::swap() for Json::Value. 1159 | template<> 1160 | inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } 1161 | } 1162 | 1163 | 1164 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1165 | #pragma warning(pop) 1166 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1167 | 1168 | #endif // CPPTL_JSON_H_INCLUDED 1169 | 1170 | // ////////////////////////////////////////////////////////////////////// 1171 | // End of content of file: include/json/value.h 1172 | // ////////////////////////////////////////////////////////////////////// 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | // ////////////////////////////////////////////////////////////////////// 1180 | // Beginning of content of file: include/json/reader.h 1181 | // ////////////////////////////////////////////////////////////////////// 1182 | 1183 | // Copyright 2007-2010 Baptiste Lepilleur 1184 | // Distributed under MIT license, or public domain if desired and 1185 | // recognized in your jurisdiction. 1186 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1187 | 1188 | #ifndef CPPTL_JSON_READER_H_INCLUDED 1189 | #define CPPTL_JSON_READER_H_INCLUDED 1190 | 1191 | #if !defined(JSON_IS_AMALGAMATION) 1192 | #include "features.h" 1193 | #include "value.h" 1194 | #endif // if !defined(JSON_IS_AMALGAMATION) 1195 | #include 1196 | #include 1197 | #include 1198 | #include 1199 | #include 1200 | 1201 | // Disable warning C4251: : needs to have dll-interface to 1202 | // be used by... 1203 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1204 | #pragma warning(push) 1205 | #pragma warning(disable : 4251) 1206 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1207 | 1208 | namespace Json { 1209 | 1210 | /** \brief Unserialize a JSON document into a 1211 | *Value. 1212 | * 1213 | * \deprecated Use CharReader and CharReaderBuilder. 1214 | */ 1215 | class JSON_API Reader { 1216 | public: 1217 | typedef char Char; 1218 | typedef const Char* Location; 1219 | 1220 | /** \brief Constructs a Reader allowing all features 1221 | * for parsing. 1222 | */ 1223 | Reader(); 1224 | 1225 | /** \brief Constructs a Reader allowing the specified feature set 1226 | * for parsing. 1227 | */ 1228 | Reader(const Features& features); 1229 | 1230 | /** \brief Read a Value from a JSON 1231 | * document. 1232 | * \param document UTF-8 encoded string containing the document to read. 1233 | * \param root [out] Contains the root value of the document if it was 1234 | * successfully parsed. 1235 | * \param collectComments \c true to collect comment and allow writing them 1236 | * back during 1237 | * serialization, \c false to discard comments. 1238 | * This parameter is ignored if 1239 | * Features::allowComments_ 1240 | * is \c false. 1241 | * \return \c true if the document was successfully parsed, \c false if an 1242 | * error occurred. 1243 | */ 1244 | bool 1245 | parse(const std::string& document, Value& root, bool collectComments = true); 1246 | 1247 | /** \brief Read a Value from a JSON 1248 | document. 1249 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1250 | document to read. 1251 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1252 | document to read. 1253 | * Must be >= beginDoc. 1254 | * \param root [out] Contains the root value of the document if it was 1255 | * successfully parsed. 1256 | * \param collectComments \c true to collect comment and allow writing them 1257 | back during 1258 | * serialization, \c false to discard comments. 1259 | * This parameter is ignored if 1260 | Features::allowComments_ 1261 | * is \c false. 1262 | * \return \c true if the document was successfully parsed, \c false if an 1263 | error occurred. 1264 | */ 1265 | bool parse(const char* beginDoc, 1266 | const char* endDoc, 1267 | Value& root, 1268 | bool collectComments = true); 1269 | 1270 | /// \brief Parse from input stream. 1271 | /// \see Json::operator>>(std::istream&, Json::Value&). 1272 | bool parse(std::istream& is, Value& root, bool collectComments = true); 1273 | 1274 | /** \brief Returns a user friendly string that list errors in the parsed 1275 | * document. 1276 | * \return Formatted error message with the list of errors with their location 1277 | * in 1278 | * the parsed document. An empty string is returned if no error 1279 | * occurred 1280 | * during parsing. 1281 | * \deprecated Use getFormattedErrorMessages() instead (typo fix). 1282 | */ 1283 | JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") 1284 | std::string getFormatedErrorMessages() const; 1285 | 1286 | /** \brief Returns a user friendly string that list errors in the parsed 1287 | * document. 1288 | * \return Formatted error message with the list of errors with their location 1289 | * in 1290 | * the parsed document. An empty string is returned if no error 1291 | * occurred 1292 | * during parsing. 1293 | */ 1294 | std::string getFormattedErrorMessages() const; 1295 | 1296 | private: 1297 | enum TokenType { 1298 | tokenEndOfStream = 0, 1299 | tokenObjectBegin, 1300 | tokenObjectEnd, 1301 | tokenArrayBegin, 1302 | tokenArrayEnd, 1303 | tokenString, 1304 | tokenNumber, 1305 | tokenTrue, 1306 | tokenFalse, 1307 | tokenNull, 1308 | tokenArraySeparator, 1309 | tokenMemberSeparator, 1310 | tokenComment, 1311 | tokenError 1312 | }; 1313 | 1314 | class Token { 1315 | public: 1316 | TokenType type_; 1317 | Location start_; 1318 | Location end_; 1319 | }; 1320 | 1321 | class ErrorInfo { 1322 | public: 1323 | Token token_; 1324 | std::string message_; 1325 | Location extra_; 1326 | }; 1327 | 1328 | typedef std::deque Errors; 1329 | 1330 | bool readToken(Token& token); 1331 | void skipSpaces(); 1332 | bool match(Location pattern, int patternLength); 1333 | bool readComment(); 1334 | bool readCStyleComment(); 1335 | bool readCppStyleComment(); 1336 | bool readString(); 1337 | void readNumber(); 1338 | bool readValue(); 1339 | bool readObject(Token& token); 1340 | bool readArray(Token& token); 1341 | bool decodeNumber(Token& token); 1342 | bool decodeNumber(Token& token, Value& decoded); 1343 | bool decodeString(Token& token); 1344 | bool decodeString(Token& token, std::string& decoded); 1345 | bool decodeDouble(Token& token); 1346 | bool decodeDouble(Token& token, Value& decoded); 1347 | bool decodeUnicodeCodePoint(Token& token, 1348 | Location& current, 1349 | Location end, 1350 | unsigned int& unicode); 1351 | bool decodeUnicodeEscapeSequence(Token& token, 1352 | Location& current, 1353 | Location end, 1354 | unsigned int& unicode); 1355 | bool addError(const std::string& message, Token& token, Location extra = 0); 1356 | bool recoverFromError(TokenType skipUntilToken); 1357 | bool addErrorAndRecover(const std::string& message, 1358 | Token& token, 1359 | TokenType skipUntilToken); 1360 | void skipUntilSpace(); 1361 | Value& currentValue(); 1362 | Char getNextChar(); 1363 | void 1364 | getLocationLineAndColumn(Location location, int& line, int& column) const; 1365 | std::string getLocationLineAndColumn(Location location) const; 1366 | void addComment(Location begin, Location end, CommentPlacement placement); 1367 | void skipCommentTokens(Token& token); 1368 | 1369 | typedef std::stack Nodes; 1370 | Nodes nodes_; 1371 | Errors errors_; 1372 | std::string document_; 1373 | Location begin_; 1374 | Location end_; 1375 | Location current_; 1376 | Location lastValueEnd_; 1377 | Value* lastValue_; 1378 | std::string commentsBefore_; 1379 | Features features_; 1380 | bool collectComments_; 1381 | }; // Reader 1382 | 1383 | /** Interface for reading JSON from a char array. 1384 | */ 1385 | class JSON_API CharReader { 1386 | public: 1387 | virtual ~CharReader() {} 1388 | /** \brief Read a Value from a JSON 1389 | document. 1390 | * The document must be a UTF-8 encoded string containing the document to read. 1391 | * 1392 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 1393 | document to read. 1394 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the 1395 | document to read. 1396 | * Must be >= beginDoc. 1397 | * \param root [out] Contains the root value of the document if it was 1398 | * successfully parsed. 1399 | * \param errs [out] Formatted error messages (if not NULL) 1400 | * a user friendly string that lists errors in the parsed 1401 | * document. 1402 | * \return \c true if the document was successfully parsed, \c false if an 1403 | error occurred. 1404 | */ 1405 | virtual bool parse( 1406 | char const* beginDoc, char const* endDoc, 1407 | Value* root, std::string* errs) = 0; 1408 | 1409 | class Factory { 1410 | public: 1411 | virtual ~Factory() {} 1412 | /** \brief Allocate a CharReader via operator new(). 1413 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1414 | */ 1415 | virtual CharReader* newCharReader() const = 0; 1416 | }; // Factory 1417 | }; // CharReader 1418 | 1419 | /** \brief Build a CharReader implementation. 1420 | 1421 | Usage: 1422 | \code 1423 | using namespace Json; 1424 | CharReaderBuilder builder; 1425 | builder["collectComments"] = false; 1426 | Value value; 1427 | std::string errs; 1428 | bool ok = parseFromStream(builder, std::cin, &value, &errs); 1429 | \endcode 1430 | */ 1431 | class JSON_API CharReaderBuilder : public CharReader::Factory { 1432 | public: 1433 | // Note: We use a Json::Value so that we can add data-members to this class 1434 | // without a major version bump. 1435 | /** Configuration of this builder. 1436 | These are case-sensitive. 1437 | Available settings (case-sensitive): 1438 | - `"collectComments": false or true` 1439 | - true to collect comment and allow writing them 1440 | back during serialization, false to discard comments. 1441 | This parameter is ignored if allowComments is false. 1442 | - `"allowComments": false or true` 1443 | - true if comments are allowed. 1444 | - `"strictRoot": false or true` 1445 | - true if root must be either an array or an object value 1446 | - `"allowDroppedNullPlaceholders": false or true` 1447 | - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) 1448 | - `"allowNumericKeys": false or true` 1449 | - true if numeric object keys are allowed. 1450 | - `"allowSingleQuotes": false or true` 1451 | - true if '' are allowed for strings (both keys and values) 1452 | - `"stackLimit": integer` 1453 | - Exceeding stackLimit (recursive depth of `readValue()`) will 1454 | cause an exception. 1455 | - This is a security issue (seg-faults caused by deeply nested JSON), 1456 | so the default is low. 1457 | - `"failIfExtra": false or true` 1458 | - If true, `parse()` returns false when extra non-whitespace trails 1459 | the JSON value in the input string. 1460 | - `"rejectDupKeys": false or true` 1461 | - If true, `parse()` returns false when a key is duplicated within an object. 1462 | 1463 | You can examine 'settings_` yourself 1464 | to see the defaults. You can also write and read them just like any 1465 | JSON Value. 1466 | \sa setDefaults() 1467 | */ 1468 | Json::Value settings_; 1469 | 1470 | CharReaderBuilder(); 1471 | virtual ~CharReaderBuilder(); 1472 | 1473 | virtual CharReader* newCharReader() const; 1474 | 1475 | /** \return true if 'settings' are legal and consistent; 1476 | * otherwise, indicate bad settings via 'invalid'. 1477 | */ 1478 | bool validate(Json::Value* invalid) const; 1479 | 1480 | /** A simple way to update a specific setting. 1481 | */ 1482 | Value& operator[](std::string key); 1483 | 1484 | /** Called by ctor, but you can use this to reset settings_. 1485 | * \pre 'settings' != NULL (but Json::null is fine) 1486 | * \remark Defaults: 1487 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults 1488 | */ 1489 | static void setDefaults(Json::Value* settings); 1490 | /** Same as old Features::strictMode(). 1491 | * \pre 'settings' != NULL (but Json::null is fine) 1492 | * \remark Defaults: 1493 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode 1494 | */ 1495 | static void strictMode(Json::Value* settings); 1496 | }; 1497 | 1498 | /** Consume entire stream and use its begin/end. 1499 | * Someday we might have a real StreamReader, but for now this 1500 | * is convenient. 1501 | */ 1502 | bool JSON_API parseFromStream( 1503 | CharReader::Factory const&, 1504 | std::istream&, 1505 | Value* root, std::string* errs); 1506 | 1507 | /** \brief Read from 'sin' into 'root'. 1508 | 1509 | Always keep comments from the input JSON. 1510 | 1511 | This can be used to read a file into a particular sub-object. 1512 | For example: 1513 | \code 1514 | Json::Value root; 1515 | cin >> root["dir"]["file"]; 1516 | cout << root; 1517 | \endcode 1518 | Result: 1519 | \verbatim 1520 | { 1521 | "dir": { 1522 | "file": { 1523 | // The input stream JSON would be nested here. 1524 | } 1525 | } 1526 | } 1527 | \endverbatim 1528 | \throw std::exception on parse error. 1529 | \see Json::operator<<() 1530 | */ 1531 | JSON_API std::istream& operator>>(std::istream&, Value&); 1532 | 1533 | } // namespace Json 1534 | 1535 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1536 | #pragma warning(pop) 1537 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1538 | 1539 | #endif // CPPTL_JSON_READER_H_INCLUDED 1540 | 1541 | // ////////////////////////////////////////////////////////////////////// 1542 | // End of content of file: include/json/reader.h 1543 | // ////////////////////////////////////////////////////////////////////// 1544 | 1545 | 1546 | 1547 | 1548 | 1549 | 1550 | // ////////////////////////////////////////////////////////////////////// 1551 | // Beginning of content of file: include/json/writer.h 1552 | // ////////////////////////////////////////////////////////////////////// 1553 | 1554 | // Copyright 2007-2010 Baptiste Lepilleur 1555 | // Distributed under MIT license, or public domain if desired and 1556 | // recognized in your jurisdiction. 1557 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1558 | 1559 | #ifndef JSON_WRITER_H_INCLUDED 1560 | #define JSON_WRITER_H_INCLUDED 1561 | 1562 | #if !defined(JSON_IS_AMALGAMATION) 1563 | #include "value.h" 1564 | #endif // if !defined(JSON_IS_AMALGAMATION) 1565 | #include 1566 | #include 1567 | #include 1568 | 1569 | // Disable warning C4251: : needs to have dll-interface to 1570 | // be used by... 1571 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1572 | #pragma warning(push) 1573 | #pragma warning(disable : 4251) 1574 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1575 | 1576 | namespace Json { 1577 | 1578 | class Value; 1579 | 1580 | /** 1581 | 1582 | Usage: 1583 | \code 1584 | using namespace Json; 1585 | void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { 1586 | std::unique_ptr const writer( 1587 | factory.newStreamWriter()); 1588 | writer->write(value, &std::cout); 1589 | std::cout << std::endl; // add lf and flush 1590 | } 1591 | \endcode 1592 | */ 1593 | class JSON_API StreamWriter { 1594 | protected: 1595 | std::ostream* sout_; // not owned; will not delete 1596 | public: 1597 | StreamWriter(); 1598 | virtual ~StreamWriter(); 1599 | /** Write Value into document as configured in sub-class. 1600 | Do not take ownership of sout, but maintain a reference during function. 1601 | \pre sout != NULL 1602 | \return zero on success (For now, we always return zero, so check the stream instead.) 1603 | \throw std::exception possibly, depending on configuration 1604 | */ 1605 | virtual int write(Value const& root, std::ostream* sout) = 0; 1606 | 1607 | /** \brief A simple abstract factory. 1608 | */ 1609 | class JSON_API Factory { 1610 | public: 1611 | virtual ~Factory(); 1612 | /** \brief Allocate a CharReader via operator new(). 1613 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1614 | */ 1615 | virtual StreamWriter* newStreamWriter() const = 0; 1616 | }; // Factory 1617 | }; // StreamWriter 1618 | 1619 | /** \brief Write into stringstream, then return string, for convenience. 1620 | * A StreamWriter will be created from the factory, used, and then deleted. 1621 | */ 1622 | std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); 1623 | 1624 | 1625 | /** \brief Build a StreamWriter implementation. 1626 | 1627 | Usage: 1628 | \code 1629 | using namespace Json; 1630 | Value value = ...; 1631 | StreamWriterBuilder builder; 1632 | builder["commentStyle"] = "None"; 1633 | builder["indentation"] = " "; // or whatever you like 1634 | std::unique_ptr writer( 1635 | builder.newStreamWriter()); 1636 | writer->write(value, &std::cout); 1637 | std::cout << std::endl; // add lf and flush 1638 | \endcode 1639 | */ 1640 | class JSON_API StreamWriterBuilder : public StreamWriter::Factory { 1641 | public: 1642 | // Note: We use a Json::Value so that we can add data-members to this class 1643 | // without a major version bump. 1644 | /** Configuration of this builder. 1645 | Available settings (case-sensitive): 1646 | - "commentStyle": "None" or "All" 1647 | - "indentation": "" 1648 | - "enableYAMLCompatibility": false or true 1649 | - slightly change the whitespace around colons 1650 | - "dropNullPlaceholders": false or true 1651 | - Drop the "null" string from the writer's output for nullValues. 1652 | Strictly speaking, this is not valid JSON. But when the output is being 1653 | fed to a browser's Javascript, it makes for smaller output and the 1654 | browser can handle the output just fine. 1655 | 1656 | You can examine 'settings_` yourself 1657 | to see the defaults. You can also write and read them just like any 1658 | JSON Value. 1659 | \sa setDefaults() 1660 | */ 1661 | Json::Value settings_; 1662 | 1663 | StreamWriterBuilder(); 1664 | virtual ~StreamWriterBuilder(); 1665 | 1666 | /** 1667 | * \throw std::exception if something goes wrong (e.g. invalid settings) 1668 | */ 1669 | virtual StreamWriter* newStreamWriter() const; 1670 | 1671 | /** \return true if 'settings' are legal and consistent; 1672 | * otherwise, indicate bad settings via 'invalid'. 1673 | */ 1674 | bool validate(Json::Value* invalid) const; 1675 | /** A simple way to update a specific setting. 1676 | */ 1677 | Value& operator[](std::string key); 1678 | 1679 | /** Called by ctor, but you can use this to reset settings_. 1680 | * \pre 'settings' != NULL (but Json::null is fine) 1681 | * \remark Defaults: 1682 | * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults 1683 | */ 1684 | static void setDefaults(Json::Value* settings); 1685 | }; 1686 | 1687 | /** \brief Abstract class for writers. 1688 | * \deprecated Use StreamWriter. (And really, this is an implementation detail.) 1689 | */ 1690 | class JSON_API Writer { 1691 | public: 1692 | virtual ~Writer(); 1693 | 1694 | virtual std::string write(const Value& root) = 0; 1695 | }; 1696 | 1697 | /** \brief Outputs a Value in JSON format 1698 | *without formatting (not human friendly). 1699 | * 1700 | * The JSON document is written in a single line. It is not intended for 'human' 1701 | *consumption, 1702 | * but may be usefull to support feature such as RPC where bandwith is limited. 1703 | * \sa Reader, Value 1704 | * \deprecated Use StreamWriterBuilder. 1705 | */ 1706 | class JSON_API FastWriter : public Writer { 1707 | 1708 | public: 1709 | FastWriter(); 1710 | virtual ~FastWriter() {} 1711 | 1712 | void enableYAMLCompatibility(); 1713 | 1714 | public: // overridden from Writer 1715 | virtual std::string write(const Value& root); 1716 | 1717 | private: 1718 | void writeValue(const Value& value); 1719 | 1720 | std::string document_; 1721 | bool yamlCompatiblityEnabled_; 1722 | }; 1723 | 1724 | /** \brief Writes a Value in JSON format in a 1725 | *human friendly way. 1726 | * 1727 | * The rules for line break and indent are as follow: 1728 | * - Object value: 1729 | * - if empty then print {} without indent and line break 1730 | * - if not empty the print '{', line break & indent, print one value per 1731 | *line 1732 | * and then unindent and line break and print '}'. 1733 | * - Array value: 1734 | * - if empty then print [] without indent and line break 1735 | * - if the array contains no object value, empty array or some other value 1736 | *types, 1737 | * and all the values fit on one lines, then print the array on a single 1738 | *line. 1739 | * - otherwise, it the values do not fit on one line, or the array contains 1740 | * object or non empty array, then print one value per line. 1741 | * 1742 | * If the Value have comments then they are outputed according to their 1743 | *#CommentPlacement. 1744 | * 1745 | * \sa Reader, Value, Value::setComment() 1746 | * \deprecated Use StreamWriterBuilder. 1747 | */ 1748 | class JSON_API StyledWriter : public Writer { 1749 | public: 1750 | StyledWriter(); 1751 | virtual ~StyledWriter() {} 1752 | 1753 | public: // overridden from Writer 1754 | /** \brief Serialize a Value in JSON format. 1755 | * \param root Value to serialize. 1756 | * \return String containing the JSON document that represents the root value. 1757 | */ 1758 | virtual std::string write(const Value& root); 1759 | 1760 | private: 1761 | void writeValue(const Value& value); 1762 | void writeArrayValue(const Value& value); 1763 | bool isMultineArray(const Value& value); 1764 | void pushValue(const std::string& value); 1765 | void writeIndent(); 1766 | void writeWithIndent(const std::string& value); 1767 | void indent(); 1768 | void unindent(); 1769 | void writeCommentBeforeValue(const Value& root); 1770 | void writeCommentAfterValueOnSameLine(const Value& root); 1771 | bool hasCommentForValue(const Value& value); 1772 | static std::string normalizeEOL(const std::string& text); 1773 | 1774 | typedef std::vector ChildValues; 1775 | 1776 | ChildValues childValues_; 1777 | std::string document_; 1778 | std::string indentString_; 1779 | int rightMargin_; 1780 | int indentSize_; 1781 | bool addChildValues_; 1782 | }; 1783 | 1784 | /** \brief Writes a Value in JSON format in a 1785 | human friendly way, 1786 | to a stream rather than to a string. 1787 | * 1788 | * The rules for line break and indent are as follow: 1789 | * - Object value: 1790 | * - if empty then print {} without indent and line break 1791 | * - if not empty the print '{', line break & indent, print one value per 1792 | line 1793 | * and then unindent and line break and print '}'. 1794 | * - Array value: 1795 | * - if empty then print [] without indent and line break 1796 | * - if the array contains no object value, empty array or some other value 1797 | types, 1798 | * and all the values fit on one lines, then print the array on a single 1799 | line. 1800 | * - otherwise, it the values do not fit on one line, or the array contains 1801 | * object or non empty array, then print one value per line. 1802 | * 1803 | * If the Value have comments then they are outputed according to their 1804 | #CommentPlacement. 1805 | * 1806 | * \param indentation Each level will be indented by this amount extra. 1807 | * \sa Reader, Value, Value::setComment() 1808 | * \deprecated Use StreamWriterBuilder. 1809 | */ 1810 | class JSON_API StyledStreamWriter { 1811 | public: 1812 | StyledStreamWriter(std::string indentation = "\t"); 1813 | ~StyledStreamWriter() {} 1814 | 1815 | public: 1816 | /** \brief Serialize a Value in JSON format. 1817 | * \param out Stream to write to. (Can be ostringstream, e.g.) 1818 | * \param root Value to serialize. 1819 | * \note There is no point in deriving from Writer, since write() should not 1820 | * return a value. 1821 | */ 1822 | void write(std::ostream& out, const Value& root); 1823 | 1824 | private: 1825 | void writeValue(const Value& value); 1826 | void writeArrayValue(const Value& value); 1827 | bool isMultineArray(const Value& value); 1828 | void pushValue(const std::string& value); 1829 | void writeIndent(); 1830 | void writeWithIndent(const std::string& value); 1831 | void indent(); 1832 | void unindent(); 1833 | void writeCommentBeforeValue(const Value& root); 1834 | void writeCommentAfterValueOnSameLine(const Value& root); 1835 | bool hasCommentForValue(const Value& value); 1836 | static std::string normalizeEOL(const std::string& text); 1837 | 1838 | typedef std::vector ChildValues; 1839 | 1840 | ChildValues childValues_; 1841 | std::ostream* document_; 1842 | std::string indentString_; 1843 | int rightMargin_; 1844 | std::string indentation_; 1845 | bool addChildValues_ : 1; 1846 | bool indented_ : 1; 1847 | }; 1848 | 1849 | #if defined(JSON_HAS_INT64) 1850 | std::string JSON_API valueToString(Int value); 1851 | std::string JSON_API valueToString(UInt value); 1852 | #endif // if defined(JSON_HAS_INT64) 1853 | std::string JSON_API valueToString(LargestInt value); 1854 | std::string JSON_API valueToString(LargestUInt value); 1855 | std::string JSON_API valueToString(double value); 1856 | std::string JSON_API valueToString(bool value); 1857 | std::string JSON_API valueToQuotedString(const char* value); 1858 | 1859 | /// \brief Output using the StyledStreamWriter. 1860 | /// \see Json::operator>>() 1861 | JSON_API std::ostream& operator<<(std::ostream&, const Value& root); 1862 | 1863 | } // namespace Json 1864 | 1865 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1866 | #pragma warning(pop) 1867 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 1868 | 1869 | #endif // JSON_WRITER_H_INCLUDED 1870 | 1871 | // ////////////////////////////////////////////////////////////////////// 1872 | // End of content of file: include/json/writer.h 1873 | // ////////////////////////////////////////////////////////////////////// 1874 | 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | // ////////////////////////////////////////////////////////////////////// 1881 | // Beginning of content of file: include/json/assertions.h 1882 | // ////////////////////////////////////////////////////////////////////// 1883 | 1884 | // Copyright 2007-2010 Baptiste Lepilleur 1885 | // Distributed under MIT license, or public domain if desired and 1886 | // recognized in your jurisdiction. 1887 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 1888 | 1889 | #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED 1890 | #define CPPTL_JSON_ASSERTIONS_H_INCLUDED 1891 | 1892 | #include 1893 | #include 1894 | 1895 | #if !defined(JSON_IS_AMALGAMATION) 1896 | #include "config.h" 1897 | #endif // if !defined(JSON_IS_AMALGAMATION) 1898 | 1899 | /** It should not be possible for a maliciously designed file to 1900 | * cause an abort() or seg-fault, so these macros are used only 1901 | * for pre-condition violations and internal logic errors. 1902 | */ 1903 | #if JSON_USE_EXCEPTION 1904 | 1905 | // @todo <= add detail about condition in exception 1906 | # define JSON_ASSERT(condition) \ 1907 | {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} 1908 | 1909 | # define JSON_FAIL_MESSAGE(message) \ 1910 | { \ 1911 | std::ostringstream oss; oss << message; \ 1912 | Json::throwLogicError(oss.str()); \ 1913 | abort(); \ 1914 | } 1915 | 1916 | #else // JSON_USE_EXCEPTION 1917 | 1918 | # define JSON_ASSERT(condition) assert(condition) 1919 | 1920 | // The call to assert() will show the failure message in debug builds. In 1921 | // release builds we abort, for a core-dump or debugger. 1922 | # define JSON_FAIL_MESSAGE(message) \ 1923 | { \ 1924 | std::ostringstream oss; oss << message; \ 1925 | assert(false && oss.str().c_str()); \ 1926 | abort(); \ 1927 | } 1928 | 1929 | 1930 | #endif 1931 | 1932 | #define JSON_ASSERT_MESSAGE(condition, message) \ 1933 | if (!(condition)) { \ 1934 | JSON_FAIL_MESSAGE(message); \ 1935 | } 1936 | 1937 | #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED 1938 | 1939 | // ////////////////////////////////////////////////////////////////////// 1940 | // End of content of file: include/json/assertions.h 1941 | // ////////////////////////////////////////////////////////////////////// 1942 | 1943 | 1944 | 1945 | 1946 | 1947 | #endif //ifndef JSON_AMALGATED_H_INCLUDED 1948 | -------------------------------------------------------------------------------- /reddit-browser/reddit-browser.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {2F53BC6B-DF32-4EEB-8F2B-378C2B670ED4} 15 | Win32Proj 16 | redditbrowser 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | ..\..\boost;..;$(IncludePath) 45 | 46 | 47 | false 48 | ..\..\boost;..;$(IncludePath) 49 | 50 | 51 | 52 | 53 | 54 | Level3 55 | Disabled 56 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 57 | 58 | 59 | Console 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | 67 | 68 | MaxSpeed 69 | true 70 | true 71 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 72 | 73 | 74 | Console 75 | true 76 | true 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /reddit-browser/reddit-browser.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | -------------------------------------------------------------------------------- /sqlite3ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2006 June 7 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This header file defines the SQLite interface for use by 13 | ** shared libraries that want to be imported as extensions into 14 | ** an SQLite instance. Shared libraries that intend to be loaded 15 | ** as extensions by SQLite should #include this file instead of 16 | ** sqlite3.h. 17 | */ 18 | #ifndef _SQLITE3EXT_H_ 19 | #define _SQLITE3EXT_H_ 20 | #include "sqlite3.h" 21 | 22 | typedef struct sqlite3_api_routines sqlite3_api_routines; 23 | 24 | /* 25 | ** The following structure holds pointers to all of the SQLite API 26 | ** routines. 27 | ** 28 | ** WARNING: In order to maintain backwards compatibility, add new 29 | ** interfaces to the end of this structure only. If you insert new 30 | ** interfaces in the middle of this structure, then older different 31 | ** versions of SQLite will not be able to load each other's shared 32 | ** libraries! 33 | */ 34 | struct sqlite3_api_routines { 35 | void * (*aggregate_context)(sqlite3_context*,int nBytes); 36 | int (*aggregate_count)(sqlite3_context*); 37 | int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); 38 | int (*bind_double)(sqlite3_stmt*,int,double); 39 | int (*bind_int)(sqlite3_stmt*,int,int); 40 | int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); 41 | int (*bind_null)(sqlite3_stmt*,int); 42 | int (*bind_parameter_count)(sqlite3_stmt*); 43 | int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); 44 | const char * (*bind_parameter_name)(sqlite3_stmt*,int); 45 | int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); 46 | int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); 47 | int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); 48 | int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); 49 | int (*busy_timeout)(sqlite3*,int ms); 50 | int (*changes)(sqlite3*); 51 | int (*close)(sqlite3*); 52 | int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, 53 | int eTextRep,const char*)); 54 | int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, 55 | int eTextRep,const void*)); 56 | const void * (*column_blob)(sqlite3_stmt*,int iCol); 57 | int (*column_bytes)(sqlite3_stmt*,int iCol); 58 | int (*column_bytes16)(sqlite3_stmt*,int iCol); 59 | int (*column_count)(sqlite3_stmt*pStmt); 60 | const char * (*column_database_name)(sqlite3_stmt*,int); 61 | const void * (*column_database_name16)(sqlite3_stmt*,int); 62 | const char * (*column_decltype)(sqlite3_stmt*,int i); 63 | const void * (*column_decltype16)(sqlite3_stmt*,int); 64 | double (*column_double)(sqlite3_stmt*,int iCol); 65 | int (*column_int)(sqlite3_stmt*,int iCol); 66 | sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); 67 | const char * (*column_name)(sqlite3_stmt*,int); 68 | const void * (*column_name16)(sqlite3_stmt*,int); 69 | const char * (*column_origin_name)(sqlite3_stmt*,int); 70 | const void * (*column_origin_name16)(sqlite3_stmt*,int); 71 | const char * (*column_table_name)(sqlite3_stmt*,int); 72 | const void * (*column_table_name16)(sqlite3_stmt*,int); 73 | const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); 74 | const void * (*column_text16)(sqlite3_stmt*,int iCol); 75 | int (*column_type)(sqlite3_stmt*,int iCol); 76 | sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); 77 | void * (*commit_hook)(sqlite3*,int(*)(void*),void*); 78 | int (*complete)(const char*sql); 79 | int (*complete16)(const void*sql); 80 | int (*create_collation)(sqlite3*,const char*,int,void*, 81 | int(*)(void*,int,const void*,int,const void*)); 82 | int (*create_collation16)(sqlite3*,const void*,int,void*, 83 | int(*)(void*,int,const void*,int,const void*)); 84 | int (*create_function)(sqlite3*,const char*,int,int,void*, 85 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 86 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 87 | void (*xFinal)(sqlite3_context*)); 88 | int (*create_function16)(sqlite3*,const void*,int,int,void*, 89 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 90 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 91 | void (*xFinal)(sqlite3_context*)); 92 | int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); 93 | int (*data_count)(sqlite3_stmt*pStmt); 94 | sqlite3 * (*db_handle)(sqlite3_stmt*); 95 | int (*declare_vtab)(sqlite3*,const char*); 96 | int (*enable_shared_cache)(int); 97 | int (*errcode)(sqlite3*db); 98 | const char * (*errmsg)(sqlite3*); 99 | const void * (*errmsg16)(sqlite3*); 100 | int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); 101 | int (*expired)(sqlite3_stmt*); 102 | int (*finalize)(sqlite3_stmt*pStmt); 103 | void (*free)(void*); 104 | void (*free_table)(char**result); 105 | int (*get_autocommit)(sqlite3*); 106 | void * (*get_auxdata)(sqlite3_context*,int); 107 | int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); 108 | int (*global_recover)(void); 109 | void (*interruptx)(sqlite3*); 110 | sqlite_int64 (*last_insert_rowid)(sqlite3*); 111 | const char * (*libversion)(void); 112 | int (*libversion_number)(void); 113 | void *(*malloc)(int); 114 | char * (*mprintf)(const char*,...); 115 | int (*open)(const char*,sqlite3**); 116 | int (*open16)(const void*,sqlite3**); 117 | int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); 118 | int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); 119 | void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); 120 | void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); 121 | void *(*realloc)(void*,int); 122 | int (*reset)(sqlite3_stmt*pStmt); 123 | void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); 124 | void (*result_double)(sqlite3_context*,double); 125 | void (*result_error)(sqlite3_context*,const char*,int); 126 | void (*result_error16)(sqlite3_context*,const void*,int); 127 | void (*result_int)(sqlite3_context*,int); 128 | void (*result_int64)(sqlite3_context*,sqlite_int64); 129 | void (*result_null)(sqlite3_context*); 130 | void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); 131 | void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); 132 | void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); 133 | void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); 134 | void (*result_value)(sqlite3_context*,sqlite3_value*); 135 | void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); 136 | int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, 137 | const char*,const char*),void*); 138 | void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); 139 | char * (*snprintf)(int,char*,const char*,...); 140 | int (*step)(sqlite3_stmt*); 141 | int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, 142 | char const**,char const**,int*,int*,int*); 143 | void (*thread_cleanup)(void); 144 | int (*total_changes)(sqlite3*); 145 | void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); 146 | int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); 147 | void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, 148 | sqlite_int64),void*); 149 | void * (*user_data)(sqlite3_context*); 150 | const void * (*value_blob)(sqlite3_value*); 151 | int (*value_bytes)(sqlite3_value*); 152 | int (*value_bytes16)(sqlite3_value*); 153 | double (*value_double)(sqlite3_value*); 154 | int (*value_int)(sqlite3_value*); 155 | sqlite_int64 (*value_int64)(sqlite3_value*); 156 | int (*value_numeric_type)(sqlite3_value*); 157 | const unsigned char * (*value_text)(sqlite3_value*); 158 | const void * (*value_text16)(sqlite3_value*); 159 | const void * (*value_text16be)(sqlite3_value*); 160 | const void * (*value_text16le)(sqlite3_value*); 161 | int (*value_type)(sqlite3_value*); 162 | char *(*vmprintf)(const char*,va_list); 163 | /* Added ??? */ 164 | int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); 165 | /* Added by 3.3.13 */ 166 | int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); 167 | int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); 168 | int (*clear_bindings)(sqlite3_stmt*); 169 | /* Added by 3.4.1 */ 170 | int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, 171 | void (*xDestroy)(void *)); 172 | /* Added by 3.5.0 */ 173 | int (*bind_zeroblob)(sqlite3_stmt*,int,int); 174 | int (*blob_bytes)(sqlite3_blob*); 175 | int (*blob_close)(sqlite3_blob*); 176 | int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, 177 | int,sqlite3_blob**); 178 | int (*blob_read)(sqlite3_blob*,void*,int,int); 179 | int (*blob_write)(sqlite3_blob*,const void*,int,int); 180 | int (*create_collation_v2)(sqlite3*,const char*,int,void*, 181 | int(*)(void*,int,const void*,int,const void*), 182 | void(*)(void*)); 183 | int (*file_control)(sqlite3*,const char*,int,void*); 184 | sqlite3_int64 (*memory_highwater)(int); 185 | sqlite3_int64 (*memory_used)(void); 186 | sqlite3_mutex *(*mutex_alloc)(int); 187 | void (*mutex_enter)(sqlite3_mutex*); 188 | void (*mutex_free)(sqlite3_mutex*); 189 | void (*mutex_leave)(sqlite3_mutex*); 190 | int (*mutex_try)(sqlite3_mutex*); 191 | int (*open_v2)(const char*,sqlite3**,int,const char*); 192 | int (*release_memory)(int); 193 | void (*result_error_nomem)(sqlite3_context*); 194 | void (*result_error_toobig)(sqlite3_context*); 195 | int (*sleep)(int); 196 | void (*soft_heap_limit)(int); 197 | sqlite3_vfs *(*vfs_find)(const char*); 198 | int (*vfs_register)(sqlite3_vfs*,int); 199 | int (*vfs_unregister)(sqlite3_vfs*); 200 | int (*xthreadsafe)(void); 201 | void (*result_zeroblob)(sqlite3_context*,int); 202 | void (*result_error_code)(sqlite3_context*,int); 203 | int (*test_control)(int, ...); 204 | void (*randomness)(int,void*); 205 | sqlite3 *(*context_db_handle)(sqlite3_context*); 206 | int (*extended_result_codes)(sqlite3*,int); 207 | int (*limit)(sqlite3*,int,int); 208 | sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); 209 | const char *(*sql)(sqlite3_stmt*); 210 | int (*status)(int,int*,int*,int); 211 | int (*backup_finish)(sqlite3_backup*); 212 | sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); 213 | int (*backup_pagecount)(sqlite3_backup*); 214 | int (*backup_remaining)(sqlite3_backup*); 215 | int (*backup_step)(sqlite3_backup*,int); 216 | const char *(*compileoption_get)(int); 217 | int (*compileoption_used)(const char*); 218 | int (*create_function_v2)(sqlite3*,const char*,int,int,void*, 219 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 220 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 221 | void (*xFinal)(sqlite3_context*), 222 | void(*xDestroy)(void*)); 223 | int (*db_config)(sqlite3*,int,...); 224 | sqlite3_mutex *(*db_mutex)(sqlite3*); 225 | int (*db_status)(sqlite3*,int,int*,int*,int); 226 | int (*extended_errcode)(sqlite3*); 227 | void (*log)(int,const char*,...); 228 | sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); 229 | const char *(*sourceid)(void); 230 | int (*stmt_status)(sqlite3_stmt*,int,int); 231 | int (*strnicmp)(const char*,const char*,int); 232 | int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); 233 | int (*wal_autocheckpoint)(sqlite3*,int); 234 | int (*wal_checkpoint)(sqlite3*,const char*); 235 | void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); 236 | int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); 237 | int (*vtab_config)(sqlite3*,int op,...); 238 | int (*vtab_on_conflict)(sqlite3*); 239 | /* Version 3.7.16 and later */ 240 | int (*close_v2)(sqlite3*); 241 | const char *(*db_filename)(sqlite3*,const char*); 242 | int (*db_readonly)(sqlite3*,const char*); 243 | int (*db_release_memory)(sqlite3*); 244 | const char *(*errstr)(int); 245 | int (*stmt_busy)(sqlite3_stmt*); 246 | int (*stmt_readonly)(sqlite3_stmt*); 247 | int (*stricmp)(const char*,const char*); 248 | int (*uri_boolean)(const char*,const char*,int); 249 | sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); 250 | const char *(*uri_parameter)(const char*,const char*); 251 | char *(*vsnprintf)(int,char*,const char*,va_list); 252 | int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); 253 | /* Version 3.8.7 and later */ 254 | int (*auto_extension)(void(*)(void)); 255 | int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, 256 | void(*)(void*)); 257 | int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, 258 | void(*)(void*),unsigned char); 259 | int (*cancel_auto_extension)(void(*)(void)); 260 | int (*load_extension)(sqlite3*,const char*,const char*,char**); 261 | void *(*malloc64)(sqlite3_uint64); 262 | sqlite3_uint64 (*msize)(void*); 263 | void *(*realloc64)(void*,sqlite3_uint64); 264 | void (*reset_auto_extension)(void); 265 | void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, 266 | void(*)(void*)); 267 | void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, 268 | void(*)(void*), unsigned char); 269 | int (*strglob)(const char*,const char*); 270 | /* Version 3.8.11 and later */ 271 | sqlite3_value *(*value_dup)(const sqlite3_value*); 272 | void (*value_free)(sqlite3_value*); 273 | int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); 274 | int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); 275 | /* Version 3.9.0 and later */ 276 | unsigned int (*value_subtype)(sqlite3_value*); 277 | void (*result_subtype)(sqlite3_context*,unsigned int); 278 | /* Version 3.10.0 and later */ 279 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); 280 | int (*strlike)(const char*,const char*,unsigned int); 281 | int (*db_cacheflush)(sqlite3*); 282 | }; 283 | 284 | /* 285 | ** The following macros redefine the API routines so that they are 286 | ** redirected through the global sqlite3_api structure. 287 | ** 288 | ** This header file is also used by the loadext.c source file 289 | ** (part of the main SQLite library - not an extension) so that 290 | ** it can get access to the sqlite3_api_routines structure 291 | ** definition. But the main library does not want to redefine 292 | ** the API. So the redefinition macros are only valid if the 293 | ** SQLITE_CORE macros is undefined. 294 | */ 295 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) 296 | #define sqlite3_aggregate_context sqlite3_api->aggregate_context 297 | #ifndef SQLITE_OMIT_DEPRECATED 298 | #define sqlite3_aggregate_count sqlite3_api->aggregate_count 299 | #endif 300 | #define sqlite3_bind_blob sqlite3_api->bind_blob 301 | #define sqlite3_bind_double sqlite3_api->bind_double 302 | #define sqlite3_bind_int sqlite3_api->bind_int 303 | #define sqlite3_bind_int64 sqlite3_api->bind_int64 304 | #define sqlite3_bind_null sqlite3_api->bind_null 305 | #define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count 306 | #define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index 307 | #define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name 308 | #define sqlite3_bind_text sqlite3_api->bind_text 309 | #define sqlite3_bind_text16 sqlite3_api->bind_text16 310 | #define sqlite3_bind_value sqlite3_api->bind_value 311 | #define sqlite3_busy_handler sqlite3_api->busy_handler 312 | #define sqlite3_busy_timeout sqlite3_api->busy_timeout 313 | #define sqlite3_changes sqlite3_api->changes 314 | #define sqlite3_close sqlite3_api->close 315 | #define sqlite3_collation_needed sqlite3_api->collation_needed 316 | #define sqlite3_collation_needed16 sqlite3_api->collation_needed16 317 | #define sqlite3_column_blob sqlite3_api->column_blob 318 | #define sqlite3_column_bytes sqlite3_api->column_bytes 319 | #define sqlite3_column_bytes16 sqlite3_api->column_bytes16 320 | #define sqlite3_column_count sqlite3_api->column_count 321 | #define sqlite3_column_database_name sqlite3_api->column_database_name 322 | #define sqlite3_column_database_name16 sqlite3_api->column_database_name16 323 | #define sqlite3_column_decltype sqlite3_api->column_decltype 324 | #define sqlite3_column_decltype16 sqlite3_api->column_decltype16 325 | #define sqlite3_column_double sqlite3_api->column_double 326 | #define sqlite3_column_int sqlite3_api->column_int 327 | #define sqlite3_column_int64 sqlite3_api->column_int64 328 | #define sqlite3_column_name sqlite3_api->column_name 329 | #define sqlite3_column_name16 sqlite3_api->column_name16 330 | #define sqlite3_column_origin_name sqlite3_api->column_origin_name 331 | #define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 332 | #define sqlite3_column_table_name sqlite3_api->column_table_name 333 | #define sqlite3_column_table_name16 sqlite3_api->column_table_name16 334 | #define sqlite3_column_text sqlite3_api->column_text 335 | #define sqlite3_column_text16 sqlite3_api->column_text16 336 | #define sqlite3_column_type sqlite3_api->column_type 337 | #define sqlite3_column_value sqlite3_api->column_value 338 | #define sqlite3_commit_hook sqlite3_api->commit_hook 339 | #define sqlite3_complete sqlite3_api->complete 340 | #define sqlite3_complete16 sqlite3_api->complete16 341 | #define sqlite3_create_collation sqlite3_api->create_collation 342 | #define sqlite3_create_collation16 sqlite3_api->create_collation16 343 | #define sqlite3_create_function sqlite3_api->create_function 344 | #define sqlite3_create_function16 sqlite3_api->create_function16 345 | #define sqlite3_create_module sqlite3_api->create_module 346 | #define sqlite3_create_module_v2 sqlite3_api->create_module_v2 347 | #define sqlite3_data_count sqlite3_api->data_count 348 | #define sqlite3_db_handle sqlite3_api->db_handle 349 | #define sqlite3_declare_vtab sqlite3_api->declare_vtab 350 | #define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache 351 | #define sqlite3_errcode sqlite3_api->errcode 352 | #define sqlite3_errmsg sqlite3_api->errmsg 353 | #define sqlite3_errmsg16 sqlite3_api->errmsg16 354 | #define sqlite3_exec sqlite3_api->exec 355 | #ifndef SQLITE_OMIT_DEPRECATED 356 | #define sqlite3_expired sqlite3_api->expired 357 | #endif 358 | #define sqlite3_finalize sqlite3_api->finalize 359 | #define sqlite3_free sqlite3_api->free 360 | #define sqlite3_free_table sqlite3_api->free_table 361 | #define sqlite3_get_autocommit sqlite3_api->get_autocommit 362 | #define sqlite3_get_auxdata sqlite3_api->get_auxdata 363 | #define sqlite3_get_table sqlite3_api->get_table 364 | #ifndef SQLITE_OMIT_DEPRECATED 365 | #define sqlite3_global_recover sqlite3_api->global_recover 366 | #endif 367 | #define sqlite3_interrupt sqlite3_api->interruptx 368 | #define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid 369 | #define sqlite3_libversion sqlite3_api->libversion 370 | #define sqlite3_libversion_number sqlite3_api->libversion_number 371 | #define sqlite3_malloc sqlite3_api->malloc 372 | #define sqlite3_mprintf sqlite3_api->mprintf 373 | #define sqlite3_open sqlite3_api->open 374 | #define sqlite3_open16 sqlite3_api->open16 375 | #define sqlite3_prepare sqlite3_api->prepare 376 | #define sqlite3_prepare16 sqlite3_api->prepare16 377 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 378 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 379 | #define sqlite3_profile sqlite3_api->profile 380 | #define sqlite3_progress_handler sqlite3_api->progress_handler 381 | #define sqlite3_realloc sqlite3_api->realloc 382 | #define sqlite3_reset sqlite3_api->reset 383 | #define sqlite3_result_blob sqlite3_api->result_blob 384 | #define sqlite3_result_double sqlite3_api->result_double 385 | #define sqlite3_result_error sqlite3_api->result_error 386 | #define sqlite3_result_error16 sqlite3_api->result_error16 387 | #define sqlite3_result_int sqlite3_api->result_int 388 | #define sqlite3_result_int64 sqlite3_api->result_int64 389 | #define sqlite3_result_null sqlite3_api->result_null 390 | #define sqlite3_result_text sqlite3_api->result_text 391 | #define sqlite3_result_text16 sqlite3_api->result_text16 392 | #define sqlite3_result_text16be sqlite3_api->result_text16be 393 | #define sqlite3_result_text16le sqlite3_api->result_text16le 394 | #define sqlite3_result_value sqlite3_api->result_value 395 | #define sqlite3_rollback_hook sqlite3_api->rollback_hook 396 | #define sqlite3_set_authorizer sqlite3_api->set_authorizer 397 | #define sqlite3_set_auxdata sqlite3_api->set_auxdata 398 | #define sqlite3_snprintf sqlite3_api->snprintf 399 | #define sqlite3_step sqlite3_api->step 400 | #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata 401 | #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup 402 | #define sqlite3_total_changes sqlite3_api->total_changes 403 | #define sqlite3_trace sqlite3_api->trace 404 | #ifndef SQLITE_OMIT_DEPRECATED 405 | #define sqlite3_transfer_bindings sqlite3_api->transfer_bindings 406 | #endif 407 | #define sqlite3_update_hook sqlite3_api->update_hook 408 | #define sqlite3_user_data sqlite3_api->user_data 409 | #define sqlite3_value_blob sqlite3_api->value_blob 410 | #define sqlite3_value_bytes sqlite3_api->value_bytes 411 | #define sqlite3_value_bytes16 sqlite3_api->value_bytes16 412 | #define sqlite3_value_double sqlite3_api->value_double 413 | #define sqlite3_value_int sqlite3_api->value_int 414 | #define sqlite3_value_int64 sqlite3_api->value_int64 415 | #define sqlite3_value_numeric_type sqlite3_api->value_numeric_type 416 | #define sqlite3_value_text sqlite3_api->value_text 417 | #define sqlite3_value_text16 sqlite3_api->value_text16 418 | #define sqlite3_value_text16be sqlite3_api->value_text16be 419 | #define sqlite3_value_text16le sqlite3_api->value_text16le 420 | #define sqlite3_value_type sqlite3_api->value_type 421 | #define sqlite3_vmprintf sqlite3_api->vmprintf 422 | #define sqlite3_vsnprintf sqlite3_api->vsnprintf 423 | #define sqlite3_overload_function sqlite3_api->overload_function 424 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 425 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 426 | #define sqlite3_clear_bindings sqlite3_api->clear_bindings 427 | #define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob 428 | #define sqlite3_blob_bytes sqlite3_api->blob_bytes 429 | #define sqlite3_blob_close sqlite3_api->blob_close 430 | #define sqlite3_blob_open sqlite3_api->blob_open 431 | #define sqlite3_blob_read sqlite3_api->blob_read 432 | #define sqlite3_blob_write sqlite3_api->blob_write 433 | #define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 434 | #define sqlite3_file_control sqlite3_api->file_control 435 | #define sqlite3_memory_highwater sqlite3_api->memory_highwater 436 | #define sqlite3_memory_used sqlite3_api->memory_used 437 | #define sqlite3_mutex_alloc sqlite3_api->mutex_alloc 438 | #define sqlite3_mutex_enter sqlite3_api->mutex_enter 439 | #define sqlite3_mutex_free sqlite3_api->mutex_free 440 | #define sqlite3_mutex_leave sqlite3_api->mutex_leave 441 | #define sqlite3_mutex_try sqlite3_api->mutex_try 442 | #define sqlite3_open_v2 sqlite3_api->open_v2 443 | #define sqlite3_release_memory sqlite3_api->release_memory 444 | #define sqlite3_result_error_nomem sqlite3_api->result_error_nomem 445 | #define sqlite3_result_error_toobig sqlite3_api->result_error_toobig 446 | #define sqlite3_sleep sqlite3_api->sleep 447 | #define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit 448 | #define sqlite3_vfs_find sqlite3_api->vfs_find 449 | #define sqlite3_vfs_register sqlite3_api->vfs_register 450 | #define sqlite3_vfs_unregister sqlite3_api->vfs_unregister 451 | #define sqlite3_threadsafe sqlite3_api->xthreadsafe 452 | #define sqlite3_result_zeroblob sqlite3_api->result_zeroblob 453 | #define sqlite3_result_error_code sqlite3_api->result_error_code 454 | #define sqlite3_test_control sqlite3_api->test_control 455 | #define sqlite3_randomness sqlite3_api->randomness 456 | #define sqlite3_context_db_handle sqlite3_api->context_db_handle 457 | #define sqlite3_extended_result_codes sqlite3_api->extended_result_codes 458 | #define sqlite3_limit sqlite3_api->limit 459 | #define sqlite3_next_stmt sqlite3_api->next_stmt 460 | #define sqlite3_sql sqlite3_api->sql 461 | #define sqlite3_status sqlite3_api->status 462 | #define sqlite3_backup_finish sqlite3_api->backup_finish 463 | #define sqlite3_backup_init sqlite3_api->backup_init 464 | #define sqlite3_backup_pagecount sqlite3_api->backup_pagecount 465 | #define sqlite3_backup_remaining sqlite3_api->backup_remaining 466 | #define sqlite3_backup_step sqlite3_api->backup_step 467 | #define sqlite3_compileoption_get sqlite3_api->compileoption_get 468 | #define sqlite3_compileoption_used sqlite3_api->compileoption_used 469 | #define sqlite3_create_function_v2 sqlite3_api->create_function_v2 470 | #define sqlite3_db_config sqlite3_api->db_config 471 | #define sqlite3_db_mutex sqlite3_api->db_mutex 472 | #define sqlite3_db_status sqlite3_api->db_status 473 | #define sqlite3_extended_errcode sqlite3_api->extended_errcode 474 | #define sqlite3_log sqlite3_api->log 475 | #define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 476 | #define sqlite3_sourceid sqlite3_api->sourceid 477 | #define sqlite3_stmt_status sqlite3_api->stmt_status 478 | #define sqlite3_strnicmp sqlite3_api->strnicmp 479 | #define sqlite3_unlock_notify sqlite3_api->unlock_notify 480 | #define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint 481 | #define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint 482 | #define sqlite3_wal_hook sqlite3_api->wal_hook 483 | #define sqlite3_blob_reopen sqlite3_api->blob_reopen 484 | #define sqlite3_vtab_config sqlite3_api->vtab_config 485 | #define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict 486 | /* Version 3.7.16 and later */ 487 | #define sqlite3_close_v2 sqlite3_api->close_v2 488 | #define sqlite3_db_filename sqlite3_api->db_filename 489 | #define sqlite3_db_readonly sqlite3_api->db_readonly 490 | #define sqlite3_db_release_memory sqlite3_api->db_release_memory 491 | #define sqlite3_errstr sqlite3_api->errstr 492 | #define sqlite3_stmt_busy sqlite3_api->stmt_busy 493 | #define sqlite3_stmt_readonly sqlite3_api->stmt_readonly 494 | #define sqlite3_stricmp sqlite3_api->stricmp 495 | #define sqlite3_uri_boolean sqlite3_api->uri_boolean 496 | #define sqlite3_uri_int64 sqlite3_api->uri_int64 497 | #define sqlite3_uri_parameter sqlite3_api->uri_parameter 498 | #define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf 499 | #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 500 | /* Version 3.8.7 and later */ 501 | #define sqlite3_auto_extension sqlite3_api->auto_extension 502 | #define sqlite3_bind_blob64 sqlite3_api->bind_blob64 503 | #define sqlite3_bind_text64 sqlite3_api->bind_text64 504 | #define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension 505 | #define sqlite3_load_extension sqlite3_api->load_extension 506 | #define sqlite3_malloc64 sqlite3_api->malloc64 507 | #define sqlite3_msize sqlite3_api->msize 508 | #define sqlite3_realloc64 sqlite3_api->realloc64 509 | #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension 510 | #define sqlite3_result_blob64 sqlite3_api->result_blob64 511 | #define sqlite3_result_text64 sqlite3_api->result_text64 512 | #define sqlite3_strglob sqlite3_api->strglob 513 | /* Version 3.8.11 and later */ 514 | #define sqlite3_value_dup sqlite3_api->value_dup 515 | #define sqlite3_value_free sqlite3_api->value_free 516 | #define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 517 | #define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 518 | /* Version 3.9.0 and later */ 519 | #define sqlite3_value_subtype sqlite3_api->value_subtype 520 | #define sqlite3_result_subtype sqlite3_api->result_subtype 521 | /* Version 3.10.0 and later */ 522 | #define sqlite3_status64 sqlite3_api->status64 523 | #define sqlite3_strlike sqlite3_api->strlike 524 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush 525 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ 526 | 527 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) 528 | /* This case when the file really is being compiled as a loadable 529 | ** extension */ 530 | # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; 531 | # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; 532 | # define SQLITE_EXTENSION_INIT3 \ 533 | extern const sqlite3_api_routines *sqlite3_api; 534 | #else 535 | /* This case when the file is being statically linked into the 536 | ** application */ 537 | # define SQLITE_EXTENSION_INIT1 /*no-op*/ 538 | # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ 539 | # define SQLITE_EXTENSION_INIT3 /*no-op*/ 540 | #endif 541 | 542 | #endif /* _SQLITE3EXT_H_ */ 543 | -------------------------------------------------------------------------------- /sqltorrent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 BitTorrent Inc 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "sqlite3ext.h" 18 | 19 | SQLITE_EXTENSION_INIT1 20 | 21 | #define BOOST_ASIO_SEPARATE_COMPILATION 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace { 29 | 30 | struct context 31 | { 32 | context() 33 | : base(NULL), session(libtorrent::fingerprint("SL", 0, 1, 0, 0)) 34 | {} 35 | 36 | sqlite3_vfs* base; 37 | libtorrent::session session; 38 | }; 39 | 40 | struct torrent_vfs_file 41 | { 42 | sqlite3_file base; 43 | libtorrent::session* session; 44 | libtorrent::torrent_handle torrent; 45 | }; 46 | 47 | int vfs_close(sqlite3_file* file) 48 | { 49 | torrent_vfs_file* f = (torrent_vfs_file*)file; 50 | f->session->remove_torrent(f->torrent); 51 | return SQLITE_OK; 52 | } 53 | 54 | int vfs_write(sqlite3_file* file, const void* buffer, int iAmt, sqlite3_int64 iOfst) 55 | { 56 | assert(false); 57 | return SQLITE_OK; 58 | } 59 | 60 | int vfs_truncate(sqlite3_file* file, sqlite3_int64 size) 61 | { 62 | assert(false); 63 | return SQLITE_ERROR; 64 | } 65 | 66 | int vfs_sync(sqlite3_file*, int flags) 67 | { 68 | return SQLITE_OK; 69 | } 70 | 71 | int vfs_file_size(sqlite3_file* file, sqlite3_int64 *pSize) 72 | { 73 | torrent_vfs_file* f = (torrent_vfs_file*)file; 74 | *pSize = f->torrent.torrent_file()->total_size(); 75 | return SQLITE_OK; 76 | } 77 | 78 | int vfs_lock(sqlite3_file*, int) 79 | { 80 | return SQLITE_OK; 81 | } 82 | 83 | int vfs_unlock(sqlite3_file*, int) 84 | { 85 | return SQLITE_OK; 86 | } 87 | 88 | int vfs_check_reserved_lock(sqlite3_file*, int *pResOut) 89 | { 90 | return SQLITE_OK; 91 | } 92 | 93 | int vfs_file_control(sqlite3_file*, int op, void *pArg) 94 | { 95 | return SQLITE_OK; 96 | } 97 | 98 | int vfs_sector_size(sqlite3_file* file) 99 | { 100 | torrent_vfs_file* f = (torrent_vfs_file*)file; 101 | return f->torrent.torrent_file()->piece_length(); 102 | } 103 | 104 | int vfs_device_characteristics(sqlite3_file*) 105 | { 106 | return SQLITE_IOCAP_IMMUTABLE; 107 | } 108 | 109 | int vfs_read(sqlite3_file* file, void* buffer, int const iAmt, sqlite3_int64 const iOfst) 110 | { 111 | using namespace libtorrent; 112 | 113 | torrent_vfs_file* f = (torrent_vfs_file*)file; 114 | int const piece_size = vfs_sector_size(file); 115 | int piece_idx = int(iOfst / piece_size); 116 | int piece_offset = iOfst % piece_size; 117 | int residue = iAmt; 118 | std::uint8_t* b = (std::uint8_t*)buffer; 119 | 120 | do 121 | { 122 | f->torrent.set_piece_deadline(piece_idx, 0, torrent_handle::alert_when_available); 123 | 124 | for (;;) 125 | { 126 | alert const* a = f->session->wait_for_alert(seconds(10)); 127 | if (!a) continue; 128 | 129 | if (a->type() != read_piece_alert::alert_type) 130 | { 131 | f->session->pop_alert(); 132 | continue; 133 | } 134 | 135 | read_piece_alert const* pa = static_cast(a); 136 | if (pa->piece != piece_idx) 137 | { 138 | f->session->pop_alert(); 139 | continue; 140 | } 141 | 142 | 143 | assert(piece_offset < pa->size); 144 | assert(pa->size == piece_size); 145 | std::memcpy(b, pa->buffer.get() + piece_offset, (std::min)(pa->size - piece_offset, residue)); 146 | b += pa->size - piece_offset; 147 | residue -= pa->size - piece_offset; 148 | 149 | f->session->pop_alert(); 150 | break; 151 | } 152 | 153 | ++piece_idx; 154 | piece_offset = 0; 155 | } while (residue > 0); 156 | 157 | return SQLITE_OK; 158 | } 159 | 160 | sqlite3_io_methods torrent_vfs_io_methods = { 161 | 1, 162 | vfs_close, 163 | vfs_read, 164 | vfs_write, 165 | vfs_truncate, 166 | vfs_sync, 167 | vfs_file_size, 168 | vfs_lock, 169 | vfs_unlock, 170 | vfs_check_reserved_lock, 171 | vfs_file_control, 172 | vfs_sector_size, 173 | vfs_device_characteristics 174 | }; 175 | 176 | int torrent_vfs_open(sqlite3_vfs* vfs, const char *zName, sqlite3_file* file, int flags, int *pOutFlags) 177 | { 178 | using namespace libtorrent; 179 | 180 | assert(zName); 181 | context* ctx = (context*)vfs->pAppData; 182 | torrent_vfs_file* f = (torrent_vfs_file*)file; 183 | 184 | std::memset(f, 0, sizeof(torrent_vfs_file)); 185 | f->base.pMethods = &torrent_vfs_io_methods; 186 | f->session = &ctx->session; 187 | 188 | ctx->session.set_alert_mask(alert::status_notification); 189 | 190 | { 191 | session_settings s = ctx->session.settings(); 192 | s.enable_incoming_utp = false; 193 | s.enable_outgoing_utp = false; 194 | s.max_out_request_queue = 4; 195 | 196 | ctx->session.set_settings(s); 197 | } 198 | 199 | { 200 | pe_settings pes = ctx->session.get_pe_settings(); 201 | pes.in_enc_policy = pes.out_enc_policy = pe_settings::disabled; 202 | ctx->session.set_pe_settings(pes); 203 | } 204 | 205 | add_torrent_params p; 206 | p.save_path = "."; 207 | error_code ec; 208 | #if LIBTORRENT_VERSION_NUM < 10100 209 | p.ti = new torrent_info(zName, ec); 210 | #else 211 | p.ti = boost::make_shared(zName, ec); 212 | #endif 213 | assert(!ec); 214 | try { 215 | f->torrent = ctx->session.add_torrent(p); 216 | } catch (libtorrent_exception e) { 217 | return SQLITE_CANTOPEN; 218 | } 219 | 220 | // I'm sad to say libtorrent has a bug where it incorrectly thinks a torrent is seeding 221 | // when it is in the checking_resume_data state. Wait here for the resume data to be checked 222 | // to avoid the bug. 223 | for (;;) 224 | { 225 | alert const* a = f->session->wait_for_alert(seconds(10)); 226 | if (!a) continue; 227 | 228 | if (a->type() != torrent_checked_alert::alert_type) 229 | { 230 | f->session->pop_alert(); 231 | continue; 232 | } 233 | 234 | break; 235 | } 236 | 237 | *pOutFlags |= SQLITE_OPEN_READONLY | SQLITE_OPEN_EXCLUSIVE; 238 | 239 | return SQLITE_OK; 240 | } 241 | 242 | int torrent_vfs_access(sqlite3_vfs* vfs, const char *zName, int flags, int *pResOut) 243 | { 244 | context* ctx = (context*)vfs->pAppData; 245 | int rc = ctx->base->xAccess(ctx->base, zName, flags, pResOut); 246 | if (rc != SQLITE_OK) return rc; 247 | *pResOut &= ~SQLITE_ACCESS_READWRITE; 248 | return SQLITE_OK; 249 | } 250 | 251 | } 252 | 253 | extern "C" { 254 | 255 | #if defined(_WIN32) && !defined(SQLITE_CORE) 256 | __declspec(dllexport) 257 | #endif 258 | int sqltorrent_init(int make_default) 259 | { 260 | static context ctx; 261 | static sqlite3_vfs vfs; 262 | if (!ctx.base) 263 | { 264 | ctx.base = sqlite3_vfs_find(nullptr); 265 | vfs = *ctx.base; 266 | vfs.zName = "torrent"; 267 | vfs.pAppData = &ctx; 268 | vfs.szOsFile = sizeof(torrent_vfs_file); 269 | vfs.xOpen = torrent_vfs_open; 270 | vfs.xAccess = torrent_vfs_access; 271 | } 272 | 273 | sqlite3_vfs_register(&vfs, make_default); 274 | 275 | return SQLITE_OK; 276 | } 277 | 278 | #if defined(_WIN32) && !defined(SQLITE_CORE) 279 | __declspec(dllexport) 280 | #endif 281 | int sqlite3_sqltorrent_init( 282 | sqlite3 *db, 283 | char **pzErrMsg, 284 | const sqlite3_api_routines *pApi) 285 | { 286 | int rc = SQLITE_OK; 287 | SQLITE_EXTENSION_INIT2(pApi); 288 | 289 | rc = sqltorrent_init(1); 290 | 291 | return rc; 292 | } 293 | 294 | } 295 | -------------------------------------------------------------------------------- /sqltorrent.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLTORRENT_H_INCLUDED 2 | #define SQLTORRENT_H_INCLUDED 3 | 4 | #if defined(_WIN32) && !defined(SQLITE_CORE) 5 | __declspec(dllimport) 6 | #endif 7 | int sqltorrent_init(int make_default); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /sqltorrent.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqltorrent", "sqltorrent.vcxproj", "{941A6C45-4732-4F1B-BAA3-0B6979F9EDBE}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reddit-browser", "reddit-browser\reddit-browser.vcxproj", "{2F53BC6B-DF32-4EEB-8F2B-378C2B670ED4}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Release|Win32 = Release|Win32 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {941A6C45-4732-4F1B-BAA3-0B6979F9EDBE}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {941A6C45-4732-4F1B-BAA3-0B6979F9EDBE}.Debug|Win32.Build.0 = Debug|Win32 18 | {941A6C45-4732-4F1B-BAA3-0B6979F9EDBE}.Release|Win32.ActiveCfg = Release|Win32 19 | {941A6C45-4732-4F1B-BAA3-0B6979F9EDBE}.Release|Win32.Build.0 = Release|Win32 20 | {2F53BC6B-DF32-4EEB-8F2B-378C2B670ED4}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {2F53BC6B-DF32-4EEB-8F2B-378C2B670ED4}.Debug|Win32.Build.0 = Debug|Win32 22 | {2F53BC6B-DF32-4EEB-8F2B-378C2B670ED4}.Release|Win32.ActiveCfg = Release|Win32 23 | {2F53BC6B-DF32-4EEB-8F2B-378C2B670ED4}.Release|Win32.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /sqltorrent.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {941A6C45-4732-4F1B-BAA3-0B6979F9EDBE} 15 | Win32Proj 16 | sqltorrent 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | DynamicLibrary 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | ..\libtorrent-rasterbar\include;..\boost;$(IncludePath) 45 | ..\libtorrent-rasterbar;..\boost\stage\lib;$(LibraryPath) 46 | 47 | 48 | false 49 | ..\libtorrent-rasterbar\include;..\boost;$(IncludePath) 50 | ..\libtorrent-rasterbar;..\boost\stage\lib;$(LibraryPath) 51 | 52 | 53 | 54 | NotUsing 55 | Level3 56 | Disabled 57 | WIN32;_DEBUG;_WINDOWS;_USRDLL;SQLTORRENT_EXPORTS;%(PreprocessorDefinitions) 58 | 59 | 60 | Windows 61 | true 62 | libtorrent.lib;%(AdditionalDependencies) 63 | 64 | 65 | 66 | 67 | Level3 68 | NotUsing 69 | MaxSpeed 70 | true 71 | true 72 | WIN32;NDEBUG;_WINDOWS;_USRDLL;SQLTORRENT_EXPORTS;%(PreprocessorDefinitions) 73 | 74 | 75 | Windows 76 | true 77 | true 78 | true 79 | torrent.lib;%(AdditionalDependencies) 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | false 88 | 89 | 90 | false 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /sqltorrent.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | --------------------------------------------------------------------------------