├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── autoAdjust.hpp ├── cli-miner.cpp ├── config.txt ├── console.cpp ├── console.h ├── crypto ├── c_blake256.c ├── c_blake256.h ├── c_groestl.c ├── c_groestl.h ├── c_jh.c ├── c_jh.h ├── c_keccak.c ├── c_keccak.h ├── c_skein.c ├── c_skein.h ├── cryptonight.h ├── cryptonight_aesni.h ├── cryptonight_common.cpp ├── groestl_tables.h ├── hash.h ├── int-util.h ├── skein_port.h └── soft_aes.c ├── donate-level.h ├── executor.cpp ├── executor.h ├── httpd.cpp ├── httpd.h ├── jconf.cpp ├── jconf.h ├── jext.h ├── jpsock.cpp ├── jpsock.h ├── libmicrohttpd └── microhttpd.h ├── minethd.cpp ├── minethd.h ├── msgstruct.h ├── nvcc_code ├── cryptonight.h ├── cuda_aes.hpp ├── cuda_blake.hpp ├── cuda_core.cu ├── cuda_device.hpp ├── cuda_extra.cu ├── cuda_extra.h ├── cuda_groestl.hpp ├── cuda_jh.hpp ├── cuda_keccak.hpp └── cuda_skein.hpp ├── rapidjson ├── allocators.h ├── document.h ├── encodedstream.h ├── encodings.h ├── error │ ├── en.h │ └── error.h ├── filereadstream.h ├── filewritestream.h ├── fwd.h ├── internal │ ├── biginteger.h │ ├── diyfp.h │ ├── dtoa.h │ ├── ieee754.h │ ├── itoa.h │ ├── meta.h │ ├── pow10.h │ ├── regex.h │ ├── stack.h │ ├── strfunc.h │ ├── strtod.h │ └── swap.h ├── istreamwrapper.h ├── memorybuffer.h ├── memorystream.h ├── msinttypes │ ├── inttypes.h │ └── stdint.h ├── ostreamwrapper.h ├── pointer.h ├── prettywriter.h ├── rapidjson.h ├── reader.h ├── schema.h ├── stream.h ├── stringbuffer.h └── writer.h ├── socket.cpp ├── socket.h ├── socks.h ├── thdq.hpp ├── webdesign.cpp └── webdesign.h /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | build/ 4 | xmr-stak-cpu.layout 5 | xmr-stak-cpu.depend 6 | config-debug.txt 7 | 8 | # netbeans project files 9 | /nbproject/ 10 | 11 | # tmp files 12 | *~ 13 | 14 | # merge original backup files 15 | *.orig 16 | -------------------------------------------------------------------------------- /autoAdjust.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "autoAdjust.hpp" 5 | 6 | #include "nvcc_code/cryptonight.h" 7 | #include "jconf.h" 8 | #include "console.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | class autoAdjust 15 | { 16 | public: 17 | 18 | autoAdjust() 19 | { 20 | int deviceCount = 0; 21 | if(cuda_get_devicecount(&deviceCount) == 0) 22 | std::exit(0); 23 | // evaluate config parameter for if auto adjustment is needed 24 | for(int i = 0; i < deviceCount; i++) 25 | { 26 | jconf::thd_cfg cfg; 27 | jconf::inst()->GetThreadConfig(i, cfg); 28 | cfg.cpu_aff = 0; 29 | cfgVec.push_back(cfg); 30 | } 31 | } 32 | 33 | /** print the adjusted values if needed 34 | * 35 | * Routine exit the application and print the adjusted values if needed else 36 | * nothing is happened. 37 | */ 38 | void printConfig() 39 | { 40 | printer::inst()->print_str("\nThe configuration for `gpu_threads_conf` in your config file is `null`.\n"); 41 | printer::inst()->print_str("The miner evaluates your system and prints a suggestion for the section `gpu_threads_conf` to the terminal.\n"); 42 | printer::inst()->print_str("The values are not optimal, please try to tweak the values based on the suggestion.\n"); 43 | printer::inst()->print_str("Please copy past the block within the asterisks to your config.\n"); 44 | printer::inst()->print_str("\n**************** Copy&Paste ****************\n\n"); 45 | int i = 0; 46 | // evaluate config parameter for if auto adjustment is needed 47 | for(auto& cfg : cfgVec) 48 | { 49 | nvid_ctx ctx; 50 | 51 | ctx.device_id = i; 52 | // -1 trigger auto adjustment 53 | ctx.device_blocks = -1; 54 | ctx.device_threads = -1; 55 | 56 | // set all evice option those marked as auto (-1) to a valid value 57 | #ifndef _WIN32 58 | ctx.device_bfactor = 0; 59 | ctx.device_bsleep = 0; 60 | #else 61 | // windows pass, try to avoid that windows kills the miner if the gpu is blocked for 2 seconds 62 | ctx.device_bfactor = 6; 63 | ctx.device_bsleep = 25; 64 | #endif 65 | if( cuda_get_deviceinfo(&ctx) != 1 ) 66 | { 67 | printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", cfg.id); 68 | std::exit(0); 69 | } 70 | nvidCtxVec.push_back(ctx); 71 | ++i; 72 | } 73 | 74 | printThreadConfig(); 75 | printer::inst()->print_str("\n**************** Copy&Paste ****************\n"); 76 | 77 | } 78 | 79 | private: 80 | 81 | void printThreadConfig() 82 | { 83 | printer::inst()->print_str("\"gpu_threads_conf\" : [\n"); 84 | int i = 0; 85 | for(auto& ctx : nvidCtxVec) 86 | { 87 | std::stringstream conf; 88 | conf << " { \"index\" : " << ctx.device_id << ",\n" << 89 | " \"threads\" : " << ctx.device_threads << ", \"blocks\" : " << ctx.device_blocks << ",\n" << 90 | " \"bfactor\" : " << ctx.device_bfactor << ", \"bsleep\" : " << ctx.device_bsleep << ",\n" << 91 | " \"affine_to_cpu\" : " << ( cfgVec[i].cpu_aff ? "true" : "false" ) << ",\n" << 92 | " },\n"; 93 | printer::inst()->print_str(conf.str().c_str()); 94 | ++i; 95 | } 96 | printer::inst()->print_str("],\n"); 97 | } 98 | 99 | std::vector cfgVec; 100 | std::vector nvidCtxVec; 101 | }; 102 | -------------------------------------------------------------------------------- /cli-miner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program. If not, see . 14 | * 15 | * Additional permission under GNU GPL version 3 section 7 16 | * 17 | * If you modify this Program, or any covered work, by linking or combining 18 | * it with OpenSSL (or a modified version of that library), containing parts 19 | * covered by the terms of OpenSSL License and SSLeay License, the licensors 20 | * of this Program grant you additional permission to convey the resulting work. 21 | * 22 | */ 23 | 24 | #include "autoAdjust.hpp" 25 | #include "executor.h" 26 | #include "minethd.h" 27 | #include "jconf.h" 28 | #include "console.h" 29 | #include "donate-level.h" 30 | 31 | #ifndef CONF_NO_HTTPD 32 | # include "httpd.h" 33 | #endif 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #ifndef CONF_NO_TLS 40 | #include 41 | #include 42 | #endif 43 | 44 | //Do a press any key for the windows folk. *insert any key joke here* 45 | #ifdef _WIN32 46 | void win_exit() 47 | { 48 | printer::inst()->print_str("Press any key to exit."); 49 | get_key(); 50 | return; 51 | } 52 | 53 | #define strcasecmp _stricmp 54 | 55 | #else 56 | void win_exit() { return; } 57 | #endif // _WIN32 58 | 59 | void do_benchmark(); 60 | 61 | int main(int argc, char *argv[]) 62 | { 63 | #ifndef CONF_NO_TLS 64 | SSL_library_init(); 65 | SSL_load_error_strings(); 66 | ERR_load_BIO_strings(); 67 | ERR_load_crypto_strings(); 68 | SSL_load_error_strings(); 69 | OpenSSL_add_all_digests(); 70 | #endif 71 | 72 | const char* sFilename = "config.txt"; 73 | bool benchmark_mode = false; 74 | 75 | if(argc >= 2) 76 | { 77 | if(strcmp(argv[1], "-h") == 0) 78 | { 79 | printer::inst()->print_msg(L0, "Usage %s [CONFIG FILE]", argv[0]); 80 | win_exit(); 81 | return 0; 82 | } 83 | 84 | if(argc >= 3 && strcasecmp(argv[1], "-c") == 0) 85 | { 86 | sFilename = argv[2]; 87 | } 88 | else if(argc >= 3 && strcasecmp(argv[1], "benchmark_mode") == 0) 89 | { 90 | sFilename = argv[2]; 91 | benchmark_mode = true; 92 | } 93 | else 94 | sFilename = argv[1]; 95 | } 96 | 97 | if(!jconf::inst()->parse_config(sFilename)) 98 | { 99 | win_exit(); 100 | return 0; 101 | } 102 | 103 | if(jconf::inst()->NeedsAutoconf()) 104 | { 105 | autoAdjust adjust; 106 | adjust.printConfig(); 107 | win_exit(); 108 | return 0; 109 | } 110 | 111 | if (!minethd::self_test()) 112 | { 113 | win_exit(); 114 | return 0; 115 | } 116 | 117 | if(benchmark_mode) 118 | { 119 | do_benchmark(); 120 | win_exit(); 121 | return 0; 122 | } 123 | 124 | #ifndef CONF_NO_HTTPD 125 | if(jconf::inst()->GetHttpdPort() != 0) 126 | { 127 | if (!httpd::inst()->start_daemon()) 128 | { 129 | win_exit(); 130 | return 0; 131 | } 132 | } 133 | #endif 134 | 135 | printer::inst()->print_str("-------------------------------------------------------------------\n"); 136 | printer::inst()->print_str("XMR-Stak-NVIDIA mining software, NVIDIA Version.\n"); 137 | printer::inst()->print_str("NVIDIA mining code was written by KlausT and psychocrypt.\n"); 138 | printer::inst()->print_str("Brought to you by fireice_uk under GPLv3.\n\n"); 139 | char buffer[64]; 140 | snprintf(buffer, sizeof(buffer), "Configurable dev donation level is set to %.1f %%\n\n", fDevDonationLevel * 100.0); 141 | printer::inst()->print_str(buffer); 142 | printer::inst()->print_str("You can use following keys to display reports:\n"); 143 | printer::inst()->print_str("'h' - hashrate\n"); 144 | printer::inst()->print_str("'r' - results\n"); 145 | printer::inst()->print_str("'c' - connection\n"); 146 | printer::inst()->print_str("-------------------------------------------------------------------\n"); 147 | 148 | if(strlen(jconf::inst()->GetOutputFile()) != 0) 149 | printer::inst()->open_logfile(jconf::inst()->GetOutputFile()); 150 | 151 | executor::inst()->ex_start(); 152 | 153 | int key; 154 | while(true) 155 | { 156 | key = get_key(); 157 | 158 | switch(key) 159 | { 160 | case 'h': 161 | executor::inst()->push_event(ex_event(EV_USR_HASHRATE)); 162 | break; 163 | case 'r': 164 | executor::inst()->push_event(ex_event(EV_USR_RESULTS)); 165 | break; 166 | case 'c': 167 | executor::inst()->push_event(ex_event(EV_USR_CONNSTAT)); 168 | break; 169 | default: 170 | break; 171 | } 172 | } 173 | 174 | return 0; 175 | } 176 | 177 | void do_benchmark() 178 | { 179 | using namespace std::chrono; 180 | std::vector* pvThreads; 181 | 182 | printer::inst()->print_msg(L0, "Running a 60 second benchmark..."); 183 | 184 | uint8_t work[76] = {0}; 185 | minethd::miner_work oWork = minethd::miner_work("", work, sizeof(work), 0, 0, 0); 186 | pvThreads = minethd::thread_starter(oWork); 187 | 188 | uint64_t iStartStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); 189 | 190 | std::this_thread::sleep_for(std::chrono::seconds(60)); 191 | 192 | oWork = minethd::miner_work(); 193 | minethd::switch_work(oWork); 194 | 195 | double fTotalHps = 0.0; 196 | for (uint32_t i = 0; i < pvThreads->size(); i++) 197 | { 198 | double fHps = pvThreads->at(i)->iHashCount; 199 | fHps /= (pvThreads->at(i)->iTimestamp - iStartStamp) / 1000.0; 200 | 201 | printer::inst()->print_msg(L0, "Thread %u: %.1f H/S", i, fHps); 202 | fTotalHps += fHps; 203 | } 204 | 205 | printer::inst()->print_msg(L0, "Total: %.1f H/S", fTotalHps); 206 | } 207 | -------------------------------------------------------------------------------- /config.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * GPU configuration. You should play around with threads and blocks as the fastest settings will vary. 3 | * index - GPU index number usually starts from 0. 4 | * threads - Number of GPU threads (nothing to do with CPU threads). 5 | * blocks - Number of GPU blocks (nothing to do with CPU threads). 6 | * bfactor - Enables running the Cryptonight kernel in smaller pieces. 7 | * Increase if you want to reduce GPU lag. Recommended setting on GUI systems - 8 8 | * bsleep - Insert a delay of X microseconds between kernel launches. 9 | * Increase if you want to reduce GPU lag. Recommended setting on GUI systems - 100 10 | * affine_to_cpu - This will affine the thread to a CPU. This can make a GPU miner play along nicer with a CPU miner. 11 | * 12 | * On the first run the miner will look at your system and suggest a basic configuration that will work, 13 | * you can try to tweak it from there to get the best performance. 14 | * 15 | * A filled out configuration should look like this: 16 | * "gpu_threads_conf" : 17 | * [ 18 | * { "index" : 0, "threads" : 17, "blocks" : 60, "bfactor" : 0, "bsleep" : 0, "affine_to_cpu" : false}, 19 | * ], 20 | */ 21 | "gpu_threads_conf" : 22 | null, 23 | 24 | /* 25 | * TLS Settings 26 | * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption 27 | * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. 28 | * 29 | * use_tls - This option will make us connect using Transport Layer Security. 30 | * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo. 31 | * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it. 32 | */ 33 | "use_tls" : false, 34 | "tls_secure_algo" : true, 35 | "tls_fingerprint" : "", 36 | 37 | /* 38 | * pool_address - Pool address should be in the form "pool.supportxmr.com:3333". Only stratum pools are supported. 39 | * wallet_address - Your wallet, or pool login. 40 | * pool_password - Can be empty in most cases or "x". 41 | */ 42 | "pool_address" : "pool.supportxmr.com:3333", 43 | "wallet_address" : "", 44 | "pool_password" : "", 45 | 46 | /* 47 | * Network timeouts. 48 | * Because of the way this client is written it doesn't need to constantly talk (keep-alive) to the server to make 49 | * sure it is there. We detect a buggy / overloaded server by the call timeout. The default values will be ok for 50 | * nearly all cases. If they aren't the pool has most likely overload issues. Low call timeout values are preferable - 51 | * long timeouts mean that we waste hashes on potentially stale jobs. Connection report will tell you how long the 52 | * server usually takes to process our calls. 53 | * 54 | * call_timeout - How long should we wait for a response from the server before we assume it is dead and drop the connection. 55 | * retry_time - How long should we wait before another connection attempt. 56 | * Both values are in seconds. 57 | * giveup_limit - Limit how many times we try to reconnect to the pool. Zero means no limit. Note that stak miners 58 | * don't mine while the connection is lost, so your computer's power usage goes down to idle. 59 | */ 60 | "call_timeout" : 10, 61 | "retry_time" : 10, 62 | "giveup_limit" : 0, 63 | 64 | /* 65 | * Output control. 66 | * Since most people are used to miners printing all the time, that's what we do by default too. This is suboptimal 67 | * really, since you cannot see errors under pages and pages of text and performance stats. Given that we have internal 68 | * performance monitors, there is very little reason to spew out pages of text instead of concise reports. 69 | * Press 'h' (hashrate), 'r' (results) or 'c' (connection) to print reports. 70 | * 71 | * verbose_level - 0 - Don't print anything. 72 | * 1 - Print intro, connection event, disconnect event 73 | * 2 - All of level 1, and new job (block) event if the difficulty is different from the last job 74 | * 3 - All of level 1, and new job (block) event in all cases, result submission event. 75 | * 4 - All of level 3, and automatic hashrate report printing 76 | */ 77 | "verbose_level" : 3, 78 | 79 | /* 80 | * Automatic hashrate report 81 | * 82 | * h_print_time - How often, in seconds, should we print a hashrate report if verbose_level is set to 4. 83 | * This option has no effect if verbose_level is not 4. 84 | */ 85 | "h_print_time" : 60, 86 | 87 | /* 88 | * Output file 89 | * 90 | * output_file - This option will log all output to a file. 91 | * 92 | */ 93 | "output_file" : "", 94 | 95 | /* 96 | * Built-in web server 97 | * I like checking my hashrate on my phone. Don't you? 98 | * Keep in mind that you will need to set up port forwarding on your router if you want to access it from 99 | * outside of your home network. Ports lower than 1024 on Linux systems will require root. 100 | * 101 | * httpd_port - Port we should listen on. Default, 0, will switch off the server. 102 | */ 103 | "httpd_port" : 0, 104 | 105 | /* 106 | * prefer_ipv4 - IPv6 preference. If the host is available on both IPv4 and IPv6 net, which one should be choose? 107 | * This setting will only be needed in 2020's. No need to worry about it now. 108 | */ 109 | "prefer_ipv4" : true, 110 | -------------------------------------------------------------------------------- /console.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program. If not, see . 14 | * 15 | * Additional permission under GNU GPL version 3 section 7 16 | * 17 | * If you modify this Program, or any covered work, by linking or combining 18 | * it with OpenSSL (or a modified version of that library), containing parts 19 | * covered by the terms of OpenSSL License and SSLeay License, the licensors 20 | * of this Program grant you additional permission to convey the resulting work. 21 | * 22 | */ 23 | 24 | #include "console.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef _WIN32 31 | #include 32 | 33 | int get_key() 34 | { 35 | DWORD mode, rd; 36 | HANDLE h; 37 | 38 | if ((h = GetStdHandle(STD_INPUT_HANDLE)) == NULL) 39 | return -1; 40 | 41 | GetConsoleMode( h, &mode ); 42 | SetConsoleMode( h, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT) ); 43 | 44 | int c = 0; 45 | ReadConsole( h, &c, 1, &rd, NULL ); 46 | SetConsoleMode( h, mode ); 47 | 48 | return c; 49 | } 50 | 51 | void set_colour(out_colours cl) 52 | { 53 | WORD attr = 0; 54 | 55 | switch(cl) 56 | { 57 | case K_RED: 58 | attr = FOREGROUND_RED | FOREGROUND_INTENSITY; 59 | break; 60 | case K_GREEN: 61 | attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; 62 | break; 63 | case K_BLUE: 64 | attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY; 65 | break; 66 | case K_YELLOW: 67 | attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; 68 | break; 69 | case K_CYAN: 70 | attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY; 71 | break; 72 | case K_MAGENTA: 73 | attr = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY; 74 | break; 75 | case K_WHITE: 76 | attr = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; 77 | break; 78 | default: 79 | break; 80 | } 81 | 82 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr); 83 | } 84 | 85 | void reset_colour() 86 | { 87 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 88 | } 89 | 90 | #else 91 | #include 92 | #include 93 | #include 94 | 95 | int get_key() 96 | { 97 | struct termios oldattr, newattr; 98 | int ch; 99 | tcgetattr( STDIN_FILENO, &oldattr ); 100 | newattr = oldattr; 101 | newattr.c_lflag &= ~( ICANON | ECHO ); 102 | tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); 103 | ch = getchar(); 104 | tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); 105 | return ch; 106 | } 107 | 108 | void set_colour(out_colours cl) 109 | { 110 | switch(cl) 111 | { 112 | case K_RED: 113 | fputs("\x1B[1;31m", stdout); 114 | break; 115 | case K_GREEN: 116 | fputs("\x1B[1;32m", stdout); 117 | break; 118 | case K_BLUE: 119 | fputs("\x1B[1;34m", stdout); 120 | break; 121 | case K_YELLOW: 122 | fputs("\x1B[1;33m", stdout); 123 | break; 124 | case K_CYAN: 125 | fputs("\x1B[1;36m", stdout); 126 | break; 127 | case K_MAGENTA: 128 | fputs("\x1B[1;35m", stdout); 129 | break; 130 | case K_WHITE: 131 | fputs("\x1B[1;37m", stdout); 132 | break; 133 | default: 134 | break; 135 | } 136 | } 137 | 138 | void reset_colour() 139 | { 140 | fputs("\x1B[0m", stdout); 141 | } 142 | #endif // _WIN32 143 | 144 | inline void comp_localtime(const time_t* ctime, tm* stime) 145 | { 146 | #ifdef _WIN32 147 | localtime_s(stime, ctime); 148 | #else 149 | localtime_r(ctime, stime); 150 | #endif // __WIN32 151 | } 152 | 153 | printer* printer::oInst = nullptr; 154 | 155 | printer::printer() 156 | { 157 | verbose_level = LINF; 158 | logfile = nullptr; 159 | } 160 | 161 | bool printer::open_logfile(const char* file) 162 | { 163 | logfile = fopen(file, "ab+"); 164 | return logfile != nullptr; 165 | } 166 | 167 | void printer::print_msg(verbosity verbose, const char* fmt, ...) 168 | { 169 | if(verbose > verbose_level) 170 | return; 171 | 172 | char buf[1024]; 173 | size_t bpos; 174 | tm stime; 175 | 176 | time_t now = time(nullptr); 177 | comp_localtime(&now, &stime); 178 | strftime(buf, sizeof(buf), "[%F %T] : ", &stime); 179 | bpos = strlen(buf); 180 | 181 | va_list args; 182 | va_start(args, fmt); 183 | vsnprintf(buf+bpos, sizeof(buf)-bpos, fmt, args); 184 | va_end(args); 185 | bpos = strlen(buf); 186 | 187 | if(bpos+2 >= sizeof(buf)) 188 | return; 189 | 190 | buf[bpos] = '\n'; 191 | buf[bpos+1] = '\0'; 192 | 193 | std::unique_lock lck(print_mutex); 194 | fputs(buf, stdout); 195 | 196 | if(logfile != nullptr) 197 | { 198 | fputs(buf, logfile); 199 | fflush(logfile); 200 | } 201 | } 202 | 203 | void printer::print_str(const char* str) 204 | { 205 | std::unique_lock lck(print_mutex); 206 | fputs(str, stdout); 207 | 208 | if(logfile != nullptr) 209 | { 210 | fputs(str, logfile); 211 | fflush(logfile); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | enum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, K_WHITE, K_NONE }; 5 | 6 | // Warning - on Linux get_key will detect control keys, but not on Windows. 7 | // We will only use it for alphanum keys anyway. 8 | int get_key(); 9 | 10 | void set_colour(out_colours cl); 11 | void reset_colour(); 12 | 13 | // on MSVC sizeof(long int) = 4, gcc sizeof(long int) = 8, this is the workaround 14 | // now we can use %llu on both compilers 15 | inline long long unsigned int int_port(size_t i) 16 | { 17 | return i; 18 | } 19 | 20 | enum verbosity : size_t { L0 = 0, L1 = 1, L2 = 2, L3 = 3, L4 = 4, LINF = 100}; 21 | 22 | class printer 23 | { 24 | public: 25 | static inline printer* inst() 26 | { 27 | if (oInst == nullptr) oInst = new printer; 28 | return oInst; 29 | }; 30 | 31 | inline void set_verbose_level(size_t level) { verbose_level = (verbosity)level; } 32 | void print_msg(verbosity verbose, const char* fmt, ...); 33 | void print_str(const char* str); 34 | bool open_logfile(const char* file); 35 | 36 | private: 37 | printer(); 38 | static printer* oInst; 39 | 40 | std::mutex print_mutex; 41 | verbosity verbose_level; 42 | FILE* logfile; 43 | }; 44 | -------------------------------------------------------------------------------- /crypto/c_blake256.h: -------------------------------------------------------------------------------- 1 | #ifndef _BLAKE256_H_ 2 | #define _BLAKE256_H_ 3 | 4 | #include 5 | 6 | typedef struct { 7 | uint32_t h[8], s[4], t[2]; 8 | int buflen, nullt; 9 | uint8_t buf[64]; 10 | } state; 11 | 12 | typedef struct { 13 | state inner; 14 | state outer; 15 | } hmac_state; 16 | 17 | void blake256_init(state *); 18 | void blake224_init(state *); 19 | 20 | void blake256_update(state *, const uint8_t *, uint64_t); 21 | void blake224_update(state *, const uint8_t *, uint64_t); 22 | 23 | void blake256_final(state *, uint8_t *); 24 | void blake224_final(state *, uint8_t *); 25 | 26 | void blake256_hash(uint8_t *, const uint8_t *, uint64_t); 27 | void blake224_hash(uint8_t *, const uint8_t *, uint64_t); 28 | 29 | /* HMAC functions: */ 30 | 31 | void hmac_blake256_init(hmac_state *, const uint8_t *, uint64_t); 32 | void hmac_blake224_init(hmac_state *, const uint8_t *, uint64_t); 33 | 34 | void hmac_blake256_update(hmac_state *, const uint8_t *, uint64_t); 35 | void hmac_blake224_update(hmac_state *, const uint8_t *, uint64_t); 36 | 37 | void hmac_blake256_final(hmac_state *, uint8_t *); 38 | void hmac_blake224_final(hmac_state *, uint8_t *); 39 | 40 | void hmac_blake256_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t); 41 | void hmac_blake224_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t); 42 | 43 | #endif /* _BLAKE256_H_ */ 44 | -------------------------------------------------------------------------------- /crypto/c_groestl.h: -------------------------------------------------------------------------------- 1 | #ifndef __hash_h 2 | #define __hash_h 3 | /* 4 | #include "crypto_uint8.h" 5 | #include "crypto_uint32.h" 6 | #include "crypto_uint64.h" 7 | #include "crypto_hash.h" 8 | 9 | typedef crypto_uint8 uint8_t; 10 | typedef crypto_uint32 uint32_t; 11 | typedef crypto_uint64 uint64_t; 12 | */ 13 | #include 14 | 15 | #include "hash.h" 16 | 17 | /* some sizes (number of bytes) */ 18 | #define ROWS 8 19 | #define LENGTHFIELDLEN ROWS 20 | #define COLS512 8 21 | 22 | #define SIZE512 (ROWS*COLS512) 23 | 24 | #define ROUNDS512 10 25 | #define HASH_BIT_LEN 256 26 | 27 | #define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff)) 28 | 29 | 30 | #define li_32(h) 0x##h##u 31 | #define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n))) 32 | #define u32BIG(a) \ 33 | ((ROTL32(a,8) & li_32(00FF00FF)) | \ 34 | (ROTL32(a,24) & li_32(FF00FF00))) 35 | 36 | 37 | /* NIST API begin */ 38 | typedef struct { 39 | uint32_t chaining[SIZE512/sizeof(uint32_t)]; /* actual state */ 40 | uint32_t block_counter1, 41 | block_counter2; /* message block counter(s) */ 42 | BitSequence buffer[SIZE512]; /* data buffer */ 43 | int buf_ptr; /* data buffer pointer */ 44 | int bits_in_last_byte; /* no. of message bits in last byte of 45 | data buffer */ 46 | } groestlHashState; 47 | 48 | /*void Init(hashState*); 49 | void Update(hashState*, const BitSequence*, DataLength); 50 | void Final(hashState*, BitSequence*); */ 51 | void groestl(const BitSequence*, DataLength, BitSequence*); 52 | /* NIST API end */ 53 | 54 | /* 55 | int crypto_hash(unsigned char *out, 56 | const unsigned char *in, 57 | unsigned long long len); 58 | */ 59 | 60 | #endif /* __hash_h */ 61 | -------------------------------------------------------------------------------- /crypto/c_jh.h: -------------------------------------------------------------------------------- 1 | /*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C 2 | 3 | -------------------------------- 4 | Performance 5 | 6 | Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz) 7 | Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic) 8 | Speed for long message: 9 | 1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2 10 | 2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3 11 | 12 | -------------------------------- 13 | Last Modified: January 16, 2011 14 | */ 15 | #pragma once 16 | 17 | #include "hash.h" 18 | 19 | HashReturn jh_hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); 20 | -------------------------------------------------------------------------------- /crypto/c_keccak.c: -------------------------------------------------------------------------------- 1 | // keccak.c 2 | // 19-Nov-11 Markku-Juhani O. Saarinen 3 | // A baseline Keccak (3rd round) implementation. 4 | 5 | #include 6 | #include 7 | 8 | #define HASH_DATA_AREA 136 9 | #define KECCAK_ROUNDS 24 10 | 11 | #ifndef ROTL64 12 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 13 | #endif 14 | 15 | const uint64_t keccakf_rndc[24] = 16 | { 17 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 18 | 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, 19 | 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 20 | 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, 21 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 22 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 23 | 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, 24 | 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 25 | }; 26 | 27 | const int keccakf_rotc[24] = 28 | { 29 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 30 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 31 | }; 32 | 33 | const int keccakf_piln[24] = 34 | { 35 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 36 | 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 37 | }; 38 | 39 | // update the state with given number of rounds 40 | 41 | void keccakf(uint64_t st[25], int rounds) 42 | { 43 | int i, j, round; 44 | uint64_t t, bc[5]; 45 | 46 | for (round = 0; round < rounds; ++round) { 47 | 48 | // Theta 49 | bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; 50 | bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21]; 51 | bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22]; 52 | bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23]; 53 | bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24]; 54 | 55 | for (i = 0; i < 5; ++i) { 56 | t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); 57 | st[i ] ^= t; 58 | st[i + 5] ^= t; 59 | st[i + 10] ^= t; 60 | st[i + 15] ^= t; 61 | st[i + 20] ^= t; 62 | } 63 | 64 | // Rho Pi 65 | t = st[1]; 66 | for (i = 0; i < 24; ++i) { 67 | bc[0] = st[keccakf_piln[i]]; 68 | st[keccakf_piln[i]] = ROTL64(t, keccakf_rotc[i]); 69 | t = bc[0]; 70 | } 71 | 72 | // Chi 73 | for (j = 0; j < 25; j += 5) { 74 | bc[0] = st[j ]; 75 | bc[1] = st[j + 1]; 76 | bc[2] = st[j + 2]; 77 | bc[3] = st[j + 3]; 78 | bc[4] = st[j + 4]; 79 | st[j ] ^= (~bc[1]) & bc[2]; 80 | st[j + 1] ^= (~bc[2]) & bc[3]; 81 | st[j + 2] ^= (~bc[3]) & bc[4]; 82 | st[j + 3] ^= (~bc[4]) & bc[0]; 83 | st[j + 4] ^= (~bc[0]) & bc[1]; 84 | } 85 | 86 | // Iota 87 | st[0] ^= keccakf_rndc[round]; 88 | } 89 | } 90 | 91 | // compute a keccak hash (md) of given byte length from "in" 92 | typedef uint64_t state_t[25]; 93 | 94 | void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) 95 | { 96 | state_t st; 97 | uint8_t temp[144]; 98 | int i, rsiz, rsizw; 99 | 100 | rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; 101 | rsizw = rsiz / 8; 102 | 103 | memset(st, 0, sizeof(st)); 104 | 105 | for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { 106 | for (i = 0; i < rsizw; i++) 107 | st[i] ^= ((uint64_t *) in)[i]; 108 | keccakf(st, KECCAK_ROUNDS); 109 | } 110 | 111 | // last block and padding 112 | memcpy(temp, in, inlen); 113 | temp[inlen++] = 1; 114 | memset(temp + inlen, 0, rsiz - inlen); 115 | temp[rsiz - 1] |= 0x80; 116 | 117 | for (i = 0; i < rsizw; i++) 118 | st[i] ^= ((uint64_t *) temp)[i]; 119 | 120 | keccakf(st, KECCAK_ROUNDS); 121 | 122 | memcpy(md, st, mdlen); 123 | } 124 | 125 | void keccak1600(const uint8_t *in, int inlen, uint8_t *md) 126 | { 127 | keccak(in, inlen, md, sizeof(state_t)); 128 | } -------------------------------------------------------------------------------- /crypto/c_keccak.h: -------------------------------------------------------------------------------- 1 | // keccak.h 2 | // 19-Nov-11 Markku-Juhani O. Saarinen 3 | 4 | #ifndef KECCAK_H 5 | #define KECCAK_H 6 | 7 | #include 8 | #include 9 | 10 | #ifndef KECCAK_ROUNDS 11 | #define KECCAK_ROUNDS 24 12 | #endif 13 | 14 | #ifndef ROTL64 15 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 16 | #endif 17 | 18 | // compute a keccak hash (md) of given byte length from "in" 19 | int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen); 20 | 21 | // update the state 22 | void keccakf(uint64_t st[25], int norounds); 23 | 24 | void keccak1600(const uint8_t *in, int inlen, uint8_t *md); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /crypto/c_skein.h: -------------------------------------------------------------------------------- 1 | #ifndef _SKEIN_H_ 2 | #define _SKEIN_H_ 1 3 | /************************************************************************** 4 | ** 5 | ** Interface declarations and internal definitions for Skein hashing. 6 | ** 7 | ** Source code author: Doug Whiting, 2008. 8 | ** 9 | ** This algorithm and source code is released to the public domain. 10 | ** 11 | *************************************************************************** 12 | ** 13 | ** The following compile-time switches may be defined to control some 14 | ** tradeoffs between speed, code size, error checking, and security. 15 | ** 16 | ** The "default" note explains what happens when the switch is not defined. 17 | ** 18 | ** SKEIN_DEBUG -- make callouts from inside Skein code 19 | ** to examine/display intermediate values. 20 | ** [default: no callouts (no overhead)] 21 | ** 22 | ** SKEIN_ERR_CHECK -- how error checking is handled inside Skein 23 | ** code. If not defined, most error checking 24 | ** is disabled (for performance). Otherwise, 25 | ** the switch value is interpreted as: 26 | ** 0: use assert() to flag errors 27 | ** 1: return SKEIN_FAIL to flag errors 28 | ** 29 | ***************************************************************************/ 30 | #include "skein_port.h" /* get platform-specific definitions */ 31 | 32 | typedef enum 33 | { 34 | SKEIN_SUCCESS = 0, /* return codes from Skein calls */ 35 | SKEIN_FAIL = 1, 36 | SKEIN_BAD_HASHLEN = 2 37 | } 38 | SkeinHashReturn; 39 | 40 | typedef size_t SkeinDataLength; /* bit count type */ 41 | typedef u08b_t SkeinBitSequence; /* bit stream type */ 42 | 43 | /* "all-in-one" call */ 44 | SkeinHashReturn skein_hash(int hashbitlen, const SkeinBitSequence *data, 45 | SkeinDataLength databitlen, SkeinBitSequence *hashval); 46 | 47 | #endif /* ifndef _SKEIN_H_ */ 48 | -------------------------------------------------------------------------------- /crypto/cryptonight.h: -------------------------------------------------------------------------------- 1 | #ifndef __CRYPTONIGHT_H_INCLUDED 2 | #define __CRYPTONIGHT_H_INCLUDED 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | #define MEMORY 2097152 12 | 13 | typedef struct { 14 | uint8_t hash_state[224]; // Need only 200, explicit align 15 | uint8_t long_state[MEMORY]; 16 | } cryptonight_ctx; 17 | 18 | void cryptonight_hash_ctx(const void* input, size_t len, void* output, cryptonight_ctx* ctx); 19 | void cryptonight_hash_ctx_soft(const void* input, size_t len, void* output, cryptonight_ctx* ctx); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /crypto/cryptonight_common.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program. If not, see . 14 | * 15 | * Additional permission under GNU GPL version 3 section 7 16 | * 17 | * If you modify this Program, or any covered work, by linking or combining 18 | * it with OpenSSL (or a modified version of that library), containing parts 19 | * covered by the terms of OpenSSL License and SSLeay License, the licensors 20 | * of this Program grant you additional permission to convey the resulting work. 21 | * 22 | */ 23 | 24 | extern "C" 25 | { 26 | #include "c_groestl.h" 27 | #include "c_blake256.h" 28 | #include "c_jh.h" 29 | #include "c_skein.h" 30 | } 31 | #include "cryptonight.h" 32 | #include "cryptonight_aesni.h" 33 | #include 34 | #include 35 | 36 | #ifdef __GNUC__ 37 | #include 38 | #else 39 | #include 40 | #endif // __GNUC__ 41 | 42 | #ifdef _WIN32 43 | #include 44 | #else 45 | #include 46 | #include 47 | #include 48 | #endif // _WIN32 49 | 50 | void do_blake_hash(const void* input, size_t len, char* output) { 51 | blake256_hash((uint8_t*)output, (const uint8_t*)input, len); 52 | } 53 | 54 | void do_groestl_hash(const void* input, size_t len, char* output) { 55 | groestl((const uint8_t*)input, len * 8, (uint8_t*)output); 56 | } 57 | 58 | void do_jh_hash(const void* input, size_t len, char* output) { 59 | jh_hash(32 * 8, (const uint8_t*)input, 8 * len, (uint8_t*)output); 60 | } 61 | 62 | void do_skein_hash(const void* input, size_t len, char* output) { 63 | skein_hash(8 * 32, (const uint8_t*)input, 8 * len, (uint8_t*)output); 64 | } 65 | 66 | void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; 67 | 68 | 69 | void cryptonight_hash_ctx(const void* input, size_t len, void* output, cryptonight_ctx* ctx) 70 | { 71 | cryptonight_hash<0x80000, MEMORY, true, false>(input, len, output, ctx); 72 | } 73 | 74 | void cryptonight_hash_ctx_soft(const void* input, size_t len, void* output, cryptonight_ctx* ctx) 75 | { 76 | cryptonight_hash<0x80000, MEMORY, true, true>(input, len, output, ctx); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /crypto/groestl_tables.h: -------------------------------------------------------------------------------- 1 | #ifndef __tables_h 2 | #define __tables_h 3 | 4 | 5 | const uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc 6 | , 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5 7 | , 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d 8 | , 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded 9 | , 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1 10 | , 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441 11 | , 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4 12 | , 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba 13 | , 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616 14 | , 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2 15 | , 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c 16 | , 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de 17 | , 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7 18 | , 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e 19 | , 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c 20 | , 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7 21 | , 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b 22 | , 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4 23 | , 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e 24 | , 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a 25 | , 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37 26 | , 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86 27 | , 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b 28 | , 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028 29 | , 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3 30 | , 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94 31 | , 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836 32 | , 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0 33 | , 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2 34 | , 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e 35 | , 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3 36 | , 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e}; 37 | 38 | #endif /* __tables_h */ 39 | -------------------------------------------------------------------------------- /crypto/hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef unsigned char BitSequence; 4 | typedef unsigned long long DataLength; 5 | typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn; 6 | -------------------------------------------------------------------------------- /crypto/int-util.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2012 - 2013 The Cryptonote developers 2 | // Distributed under the MIT/X11 software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #if defined(_MSC_VER) 13 | #include 14 | 15 | static inline uint32_t rol32(uint32_t x, int r) { 16 | static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers"); 17 | return _rotl(x, r); 18 | } 19 | 20 | static inline uint64_t rol64(uint64_t x, int r) { 21 | return _rotl64(x, r); 22 | } 23 | 24 | #else 25 | 26 | static inline uint32_t rol32(uint32_t x, int r) { 27 | return (x << (r & 31)) | (x >> (-r & 31)); 28 | } 29 | 30 | static inline uint64_t rol64(uint64_t x, int r) { 31 | return (x << (r & 63)) | (x >> (-r & 63)); 32 | } 33 | 34 | #endif 35 | 36 | static inline uint64_t hi_dword(uint64_t val) { 37 | return val >> 32; 38 | } 39 | 40 | static inline uint64_t lo_dword(uint64_t val) { 41 | return val & 0xFFFFFFFF; 42 | } 43 | 44 | static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) { 45 | dividend |= ((uint64_t)*remainder) << 32; 46 | *remainder = dividend % divisor; 47 | return dividend / divisor; 48 | } 49 | 50 | // Long division with 2^32 base 51 | static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) { 52 | uint64_t dividend_dwords[4]; 53 | uint32_t remainder = 0; 54 | 55 | dividend_dwords[3] = hi_dword(dividend_hi); 56 | dividend_dwords[2] = lo_dword(dividend_hi); 57 | dividend_dwords[1] = hi_dword(dividend_lo); 58 | dividend_dwords[0] = lo_dword(dividend_lo); 59 | 60 | *quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32; 61 | *quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder); 62 | *quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32; 63 | *quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder); 64 | 65 | return remainder; 66 | } 67 | 68 | #define IDENT32(x) ((uint32_t) (x)) 69 | #define IDENT64(x) ((uint64_t) (x)) 70 | 71 | #define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \ 72 | (((uint32_t) (x) & 0x0000ff00) << 8) | \ 73 | (((uint32_t) (x) & 0x00ff0000) >> 8) | \ 74 | (((uint32_t) (x) & 0xff000000) >> 24)) 75 | #define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \ 76 | (((uint64_t) (x) & 0x000000000000ff00) << 40) | \ 77 | (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \ 78 | (((uint64_t) (x) & 0x00000000ff000000) << 8) | \ 79 | (((uint64_t) (x) & 0x000000ff00000000) >> 8) | \ 80 | (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \ 81 | (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \ 82 | (((uint64_t) (x) & 0xff00000000000000) >> 56)) 83 | 84 | static inline uint32_t ident32(uint32_t x) { return x; } 85 | static inline uint64_t ident64(uint64_t x) { return x; } 86 | 87 | static inline uint32_t swap32(uint32_t x) { 88 | x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); 89 | return (x << 16) | (x >> 16); 90 | } 91 | static inline uint64_t swap64(uint64_t x) { 92 | x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8); 93 | x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16); 94 | return (x << 32) | (x >> 32); 95 | } 96 | 97 | #if defined(__GNUC__) 98 | #define UNUSED __attribute__((unused)) 99 | #else 100 | #define UNUSED 101 | #endif 102 | static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { } 103 | #undef UNUSED 104 | 105 | static inline void mem_inplace_swap32(void *mem, size_t n) { 106 | size_t i; 107 | for (i = 0; i < n; i++) { 108 | ((uint32_t *)mem)[i] = swap32(((const uint32_t *)mem)[i]); 109 | } 110 | } 111 | static inline void mem_inplace_swap64(void *mem, size_t n) { 112 | size_t i; 113 | for (i = 0; i < n; i++) { 114 | ((uint64_t *)mem)[i] = swap64(((const uint64_t *)mem)[i]); 115 | } 116 | } 117 | 118 | static inline void memcpy_ident32(void *dst, const void *src, size_t n) { 119 | memcpy(dst, src, 4 * n); 120 | } 121 | static inline void memcpy_ident64(void *dst, const void *src, size_t n) { 122 | memcpy(dst, src, 8 * n); 123 | } 124 | 125 | static inline void memcpy_swap32(void *dst, const void *src, size_t n) { 126 | size_t i; 127 | for (i = 0; i < n; i++) { 128 | ((uint32_t *)dst)[i] = swap32(((const uint32_t *)src)[i]); 129 | } 130 | } 131 | static inline void memcpy_swap64(void *dst, const void *src, size_t n) { 132 | size_t i; 133 | for (i = 0; i < n; i++) { 134 | ((uint64_t *)dst)[i] = swap64(((const uint64_t *)src)[i]); 135 | } 136 | } 137 | 138 | #define SWAP32LE IDENT32 139 | #define SWAP32BE SWAP32 140 | #define swap32le ident32 141 | #define swap32be swap32 142 | #define mem_inplace_swap32le mem_inplace_ident 143 | #define mem_inplace_swap32be mem_inplace_swap32 144 | #define memcpy_swap32le memcpy_ident32 145 | #define memcpy_swap32be memcpy_swap32 146 | #define SWAP64LE IDENT64 147 | #define SWAP64BE SWAP64 148 | #define swap64le ident64 149 | #define swap64be swap64 150 | #define mem_inplace_swap64le mem_inplace_ident 151 | #define mem_inplace_swap64be mem_inplace_swap64 152 | #define memcpy_swap64le memcpy_ident64 153 | #define memcpy_swap64be memcpy_swap64 -------------------------------------------------------------------------------- /crypto/skein_port.h: -------------------------------------------------------------------------------- 1 | #ifndef _SKEIN_PORT_H_ 2 | #define _SKEIN_PORT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef RETURN_VALUES 9 | # define RETURN_VALUES 10 | # if defined( DLL_EXPORT ) 11 | # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) 12 | # define VOID_RETURN __declspec( dllexport ) void __stdcall 13 | # define INT_RETURN __declspec( dllexport ) int __stdcall 14 | # elif defined( __GNUC__ ) 15 | # define VOID_RETURN __declspec( __dllexport__ ) void 16 | # define INT_RETURN __declspec( __dllexport__ ) int 17 | # else 18 | # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers 19 | # endif 20 | # elif defined( DLL_IMPORT ) 21 | # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) 22 | # define VOID_RETURN __declspec( dllimport ) void __stdcall 23 | # define INT_RETURN __declspec( dllimport ) int __stdcall 24 | # elif defined( __GNUC__ ) 25 | # define VOID_RETURN __declspec( __dllimport__ ) void 26 | # define INT_RETURN __declspec( __dllimport__ ) int 27 | # else 28 | # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers 29 | # endif 30 | # elif defined( __WATCOMC__ ) 31 | # define VOID_RETURN void __cdecl 32 | # define INT_RETURN int __cdecl 33 | # else 34 | # define VOID_RETURN void 35 | # define INT_RETURN int 36 | # endif 37 | #endif 38 | 39 | /* These defines are used to declare buffers in a way that allows 40 | faster operations on longer variables to be used. In all these 41 | defines 'size' must be a power of 2 and >= 8 42 | 43 | dec_unit_type(size,x) declares a variable 'x' of length 44 | 'size' bits 45 | 46 | dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize' 47 | bytes defined as an array of variables 48 | each of 'size' bits (bsize must be a 49 | multiple of size / 8) 50 | 51 | ptr_cast(x,size) casts a pointer to a pointer to a 52 | varaiable of length 'size' bits 53 | */ 54 | 55 | #define ui_type(size) uint##size##_t 56 | #define dec_unit_type(size,x) typedef ui_type(size) x 57 | #define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)] 58 | #define ptr_cast(x,size) ((ui_type(size)*)(x)) 59 | 60 | typedef unsigned int uint_t; /* native unsigned integer */ 61 | typedef uint8_t u08b_t; /* 8-bit unsigned integer */ 62 | typedef uint64_t u64b_t; /* 64-bit unsigned integer */ 63 | 64 | #ifndef RotL_64 65 | #define RotL_64(x,N) (((x) << (N)) | ((x) >> (64-(N)))) 66 | #endif 67 | 68 | /* 69 | * Skein is "natively" little-endian (unlike SHA-xxx), for optimal 70 | * performance on x86 CPUs. The Skein code requires the following 71 | * definitions for dealing with endianness: 72 | * 73 | * SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian 74 | * Skein_Put64_LSB_First 75 | * Skein_Get64_LSB_First 76 | * Skein_Swap64 77 | * 78 | * If SKEIN_NEED_SWAP is defined at compile time, it is used here 79 | * along with the portable versions of Put64/Get64/Swap64, which 80 | * are slow in general. 81 | * 82 | * Otherwise, an "auto-detect" of endianness is attempted below. 83 | * If the default handling doesn't work well, the user may insert 84 | * platform-specific code instead (e.g., for big-endian CPUs). 85 | * 86 | */ 87 | #ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */ 88 | 89 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 90 | 91 | /* special handler for IA64, which may be either endianness (?) */ 92 | /* here we assume little-endian, but this may need to be changed */ 93 | #if defined(__ia64) || defined(__ia64__) || defined(_M_IA64) 94 | # define PLATFORM_MUST_ALIGN (1) 95 | #ifndef PLATFORM_BYTE_ORDER 96 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 97 | #endif 98 | #endif 99 | 100 | #ifndef PLATFORM_MUST_ALIGN 101 | # define PLATFORM_MUST_ALIGN (0) 102 | #endif 103 | 104 | 105 | #if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN 106 | /* here for big-endian CPUs */ 107 | #define SKEIN_NEED_SWAP (1) 108 | #elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN 109 | /* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */ 110 | #define SKEIN_NEED_SWAP (0) 111 | #if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */ 112 | #define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt) 113 | #define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt)) 114 | #endif 115 | #else 116 | #error "Skein needs endianness setting!" 117 | #endif 118 | 119 | #endif /* ifndef SKEIN_NEED_SWAP */ 120 | 121 | /* 122 | ****************************************************************** 123 | * Provide any definitions still needed. 124 | ****************************************************************** 125 | */ 126 | #ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */ 127 | #if SKEIN_NEED_SWAP 128 | #define Skein_Swap64(w64) \ 129 | ( (( ((u64b_t)(w64)) & 0xFF) << 56) | \ 130 | (((((u64b_t)(w64)) >> 8) & 0xFF) << 48) | \ 131 | (((((u64b_t)(w64)) >>16) & 0xFF) << 40) | \ 132 | (((((u64b_t)(w64)) >>24) & 0xFF) << 32) | \ 133 | (((((u64b_t)(w64)) >>32) & 0xFF) << 24) | \ 134 | (((((u64b_t)(w64)) >>40) & 0xFF) << 16) | \ 135 | (((((u64b_t)(w64)) >>48) & 0xFF) << 8) | \ 136 | (((((u64b_t)(w64)) >>56) & 0xFF) ) ) 137 | #else 138 | #define Skein_Swap64(w64) (w64) 139 | #endif 140 | #endif /* ifndef Skein_Swap64 */ 141 | 142 | 143 | #ifndef Skein_Put64_LSB_First 144 | void Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt) 145 | #ifdef SKEIN_PORT_CODE /* instantiate the function code here? */ 146 | { /* this version is fully portable (big-endian or little-endian), but slow */ 147 | size_t n; 148 | 149 | for (n=0;n>3] >> (8*(n&7))); 151 | } 152 | #else 153 | ; /* output only the function prototype */ 154 | #endif 155 | #endif /* ifndef Skein_Put64_LSB_First */ 156 | 157 | 158 | #ifndef Skein_Get64_LSB_First 159 | void Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt) 160 | #ifdef SKEIN_PORT_CODE /* instantiate the function code here? */ 161 | { /* this version is fully portable (big-endian or little-endian), but slow */ 162 | size_t n; 163 | 164 | for (n=0;n<8*wCnt;n+=8) 165 | dst[n/8] = (((u64b_t) src[n ]) ) + 166 | (((u64b_t) src[n+1]) << 8) + 167 | (((u64b_t) src[n+2]) << 16) + 168 | (((u64b_t) src[n+3]) << 24) + 169 | (((u64b_t) src[n+4]) << 32) + 170 | (((u64b_t) src[n+5]) << 40) + 171 | (((u64b_t) src[n+6]) << 48) + 172 | (((u64b_t) src[n+7]) << 56) ; 173 | } 174 | #else 175 | ; /* output only the function prototype */ 176 | #endif 177 | #endif /* ifndef Skein_Get64_LSB_First */ 178 | 179 | #endif /* ifndef _SKEIN_PORT_H_ */ 180 | -------------------------------------------------------------------------------- /donate-level.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Dev donation. 5 | * Percentage of your hashing power that you want to donate to the developer, can be 0.0 if you don't want to do that. 6 | * Example of how it works for the default setting of 1.0: 7 | * You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1.0 minute. 8 | * Switching is instant, and only happens after a successful connection, so you never loose any hashes. 9 | * 10 | * If you plan on changing this setting to 0.0 please consider making a one off donation to my wallet: 11 | * 4581HhZkQHgZrZjKeCfCJxZff9E3xCgHGF25zABZz7oR71TnbbgiS7sK9jveE6Dx6uMs2LwszDuvQJgRZQotdpHt1fTdDhk 12 | * 13 | */ 14 | 15 | constexpr double fDevDonationLevel = 1.0 / 100.0; 16 | -------------------------------------------------------------------------------- /executor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "thdq.hpp" 3 | #include "msgstruct.h" 4 | #include "crypto/cryptonight.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class jpsock; 11 | class minethd; 12 | class telemetry; 13 | 14 | class executor 15 | { 16 | public: 17 | static executor* inst() 18 | { 19 | if (oInst == nullptr) oInst = new executor; 20 | return oInst; 21 | }; 22 | 23 | void ex_start() { my_thd = new std::thread(&executor::ex_main, this); } 24 | void ex_main(); 25 | 26 | void get_http_report(ex_event_name ev_id, std::string& data); 27 | 28 | inline void push_event(ex_event&& ev) { oEventQ.push(std::move(ev)); } 29 | void push_timed_event(ex_event&& ev, size_t sec); 30 | 31 | constexpr static size_t invalid_pool_id = 0; 32 | constexpr static size_t dev_pool_id = 1; 33 | constexpr static size_t usr_pool_id = 2; 34 | 35 | private: 36 | struct timed_event 37 | { 38 | ex_event event; 39 | size_t ticks_left; 40 | 41 | timed_event(ex_event&& ev, size_t ticks) : event(std::move(ev)), ticks_left(ticks) {} 42 | }; 43 | 44 | cryptonight_ctx* cpu_ctx; 45 | 46 | // In miliseconds, has to divide a second (1000ms) into an integer number 47 | constexpr static size_t iTickTime = 500; 48 | 49 | // Dev donation time period in seconds. 100 minutes by default. 50 | // We will divide up this period according to the config setting 51 | constexpr static size_t iDevDonatePeriod = 100 * 60; 52 | 53 | std::list lTimedEvents; 54 | std::mutex timed_event_mutex; 55 | thdq oEventQ; 56 | 57 | telemetry* telem; 58 | std::vector* pvThreads; 59 | std::thread* my_thd; 60 | 61 | size_t current_pool_id; 62 | 63 | jpsock* usr_pool; 64 | jpsock* dev_pool; 65 | 66 | jpsock* pick_pool_by_id(size_t pool_id); 67 | 68 | bool is_dev_time; 69 | 70 | executor(); 71 | static executor* oInst; 72 | 73 | void ex_clock_thd(); 74 | void pool_connect(jpsock* pool); 75 | 76 | void hashrate_report(std::string& out); 77 | void result_report(std::string& out); 78 | void connection_report(std::string& out); 79 | 80 | void http_hashrate_report(std::string& out); 81 | void http_result_report(std::string& out); 82 | void http_connection_report(std::string& out); 83 | 84 | void http_report(ex_event_name ev); 85 | void print_report(ex_event_name ev); 86 | 87 | std::string* pHttpString = nullptr; 88 | std::promise httpReady; 89 | std::mutex httpMutex; 90 | 91 | size_t iReconnectAttempts = 0; 92 | 93 | struct sck_error_log 94 | { 95 | std::chrono::system_clock::time_point time; 96 | std::string msg; 97 | 98 | sck_error_log(std::string&& err) : msg(std::move(err)) 99 | { 100 | time = std::chrono::system_clock::now(); 101 | } 102 | }; 103 | std::vector vSocketLog; 104 | 105 | // Element zero is always the success element. 106 | // Keep in mind that this is a tally and not a log like above 107 | struct result_tally 108 | { 109 | std::chrono::system_clock::time_point time; 110 | std::string msg; 111 | size_t count; 112 | 113 | result_tally() : msg("[OK]"), count(0) 114 | { 115 | time = std::chrono::system_clock::now(); 116 | } 117 | 118 | result_tally(std::string&& err) : msg(std::move(err)), count(1) 119 | { 120 | time = std::chrono::system_clock::now(); 121 | } 122 | 123 | void increment() 124 | { 125 | count++; 126 | time = std::chrono::system_clock::now(); 127 | } 128 | 129 | bool compare(std::string& err) 130 | { 131 | if(msg == err) 132 | { 133 | increment(); 134 | return true; 135 | } 136 | else 137 | return false; 138 | } 139 | }; 140 | std::vector vMineResults; 141 | 142 | //More result statistics 143 | std::array iTopDiff { { } }; //Initialize to zero 144 | 145 | std::chrono::system_clock::time_point tPoolConnTime; 146 | size_t iPoolHashes = 0; 147 | uint64_t iPoolDiff = 0; 148 | 149 | // Set it to 16 bit so that we can just let it grow 150 | // Maximum realistic growth rate - 5MB / month 151 | std::vector iPoolCallTimes; 152 | 153 | //Those stats are reset if we disconnect 154 | inline void reset_stats() 155 | { 156 | iPoolCallTimes.clear(); 157 | tPoolConnTime = std::chrono::system_clock::now(); 158 | iPoolHashes = 0; 159 | iPoolDiff = 0; 160 | } 161 | 162 | double fHighestHps = 0.0; 163 | 164 | void log_socket_error(std::string&& sError); 165 | void log_result_error(std::string&& sError); 166 | void log_result_ok(uint64_t iActualDiff); 167 | 168 | void sched_reconnect(); 169 | 170 | void on_sock_ready(size_t pool_id); 171 | void on_sock_error(size_t pool_id, std::string&& sError); 172 | void on_pool_have_job(size_t pool_id, pool_job& oPoolJob); 173 | void on_miner_result(size_t pool_id, job_result& oResult); 174 | void on_reconnect(size_t pool_id); 175 | void on_switch_pool(size_t pool_id); 176 | 177 | inline size_t sec_to_ticks(size_t sec) { return sec * (1000 / iTickTime); } 178 | }; 179 | 180 | -------------------------------------------------------------------------------- /httpd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program. If not, see . 14 | * 15 | * Additional permission under GNU GPL version 3 section 7 16 | * 17 | * If you modify this Program, or any covered work, by linking or combining 18 | * it with OpenSSL (or a modified version of that library), containing parts 19 | * covered by the terms of OpenSSL License and SSLeay License, the licensors 20 | * of this Program grant you additional permission to convey the resulting work. 21 | * 22 | */ 23 | 24 | #ifndef CONF_NO_HTTPD 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "msgstruct.h" 32 | #include "httpd.h" 33 | #include "console.h" 34 | #include "executor.h" 35 | #include "jconf.h" 36 | 37 | #include "webdesign.h" 38 | 39 | #ifdef _WIN32 40 | #include "libmicrohttpd/microhttpd.h" 41 | #define strcasecmp _stricmp 42 | #else 43 | #include 44 | #endif // _WIN32 45 | 46 | httpd* httpd::oInst = nullptr; 47 | 48 | httpd::httpd() 49 | { 50 | 51 | } 52 | 53 | int httpd::req_handler(void * cls, 54 | MHD_Connection* connection, 55 | const char* url, 56 | const char* method, 57 | const char* version, 58 | const char* upload_data, 59 | size_t* upload_data_size, 60 | void ** ptr) 61 | { 62 | struct MHD_Response * rsp; 63 | 64 | if (strcmp(method, "GET") != 0) 65 | return MHD_NO; 66 | 67 | *ptr = nullptr; 68 | 69 | std::string str; 70 | if(strcasecmp(url, "/style.css") == 0) 71 | { 72 | const char* req_etag = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "If-None-Match"); 73 | 74 | if(req_etag != NULL && strcmp(req_etag, sHtmlCssEtag) == 0) 75 | { //Cache hit 76 | rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); 77 | 78 | int ret = MHD_queue_response(connection, MHD_HTTP_NOT_MODIFIED, rsp); 79 | MHD_destroy_response(rsp); 80 | return ret; 81 | } 82 | 83 | rsp = MHD_create_response_from_buffer(sHtmlCssSize, (void*)sHtmlCssFile, MHD_RESPMEM_PERSISTENT); 84 | MHD_add_response_header(rsp, "ETag", sHtmlCssEtag); 85 | MHD_add_response_header(rsp, "Content-Type", "text/css; charset=utf-8"); 86 | } 87 | else if(strcasecmp(url, "/h") == 0 || strcasecmp(url, "/hashrate") == 0) 88 | { 89 | executor::inst()->get_http_report(EV_HTML_HASHRATE, str); 90 | 91 | rsp = MHD_create_response_from_buffer(str.size(), (void*)str.c_str(), MHD_RESPMEM_MUST_COPY); 92 | MHD_add_response_header(rsp, "Content-Type", "text/html; charset=utf-8"); 93 | } 94 | else if(strcasecmp(url, "/c") == 0 || strcasecmp(url, "/connection") == 0) 95 | { 96 | executor::inst()->get_http_report(EV_HTML_CONNSTAT, str); 97 | 98 | rsp = MHD_create_response_from_buffer(str.size(), (void*)str.c_str(), MHD_RESPMEM_MUST_COPY); 99 | MHD_add_response_header(rsp, "Content-Type", "text/html; charset=utf-8"); 100 | } 101 | else if(strcasecmp(url, "/r") == 0 || strcasecmp(url, "/results") == 0) 102 | { 103 | executor::inst()->get_http_report(EV_HTML_RESULTS, str); 104 | 105 | rsp = MHD_create_response_from_buffer(str.size(), (void*)str.c_str(), MHD_RESPMEM_MUST_COPY); 106 | MHD_add_response_header(rsp, "Content-Type", "text/html; charset=utf-8"); 107 | } 108 | else 109 | { 110 | //Do a 302 redirect to /h 111 | char loc_path[256]; 112 | const char* host_val = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Host"); 113 | 114 | if(host_val != nullptr) 115 | snprintf(loc_path, sizeof(loc_path), "http://%s/h", host_val); 116 | else 117 | snprintf(loc_path, sizeof(loc_path), "/h"); 118 | 119 | rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); 120 | int ret = MHD_queue_response(connection, MHD_HTTP_TEMPORARY_REDIRECT, rsp); 121 | MHD_add_response_header(rsp, "Location", loc_path); 122 | MHD_destroy_response(rsp); 123 | return ret; 124 | } 125 | 126 | int ret = MHD_queue_response(connection, MHD_HTTP_OK, rsp); 127 | MHD_destroy_response(rsp); 128 | return ret; 129 | } 130 | 131 | bool httpd::start_daemon() 132 | { 133 | d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, 134 | jconf::inst()->GetHttpdPort(), NULL, NULL, 135 | &httpd::req_handler, 136 | NULL, MHD_OPTION_END); 137 | 138 | if(d == nullptr) 139 | { 140 | printer::inst()->print_str("HTTP Daemon failed to start."); 141 | return false; 142 | } 143 | 144 | return true; 145 | } 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /httpd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct MHD_Daemon; 4 | struct MHD_Connection; 5 | 6 | class httpd 7 | { 8 | public: 9 | static httpd* inst() 10 | { 11 | if (oInst == nullptr) oInst = new httpd; 12 | return oInst; 13 | }; 14 | 15 | bool start_daemon(); 16 | 17 | private: 18 | httpd(); 19 | static httpd* oInst; 20 | 21 | static int req_handler(void * cls, 22 | MHD_Connection* connection, 23 | const char* url, 24 | const char* method, 25 | const char* version, 26 | const char* upload_data, 27 | size_t* upload_data_size, 28 | void ** ptr); 29 | 30 | MHD_Daemon *d; 31 | }; 32 | -------------------------------------------------------------------------------- /jconf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class jconf 6 | { 7 | public: 8 | static jconf* inst() 9 | { 10 | if (oInst == nullptr) oInst = new jconf; 11 | return oInst; 12 | }; 13 | 14 | bool parse_config(const char* sFilename); 15 | 16 | struct thd_cfg { 17 | uint32_t id; 18 | uint32_t blocks; 19 | uint32_t threads; 20 | uint32_t bfactor; 21 | uint32_t bsleep; 22 | int32_t cpu_aff; 23 | }; 24 | 25 | size_t GetThreadCount(); 26 | bool GetThreadConfig(size_t id, thd_cfg &cfg); 27 | bool NeedsAutoconf(); 28 | 29 | bool GetTlsSetting(); 30 | bool TlsSecureAlgos(); 31 | const char* GetTlsFingerprint(); 32 | 33 | const char* GetPoolAddress(); 34 | const char* GetPoolPwd(); 35 | const char* GetWalletAddress(); 36 | 37 | uint64_t GetVerboseLevel(); 38 | uint64_t GetAutohashTime(); 39 | 40 | const char* GetOutputFile(); 41 | 42 | uint64_t GetCallTimeout(); 43 | uint64_t GetNetRetry(); 44 | uint64_t GetGiveUpLimit(); 45 | 46 | uint16_t GetHttpdPort(); 47 | 48 | bool PreferIpv4(); 49 | 50 | inline bool HaveHardwareAes() { return bHaveAes; } 51 | 52 | private: 53 | jconf(); 54 | static jconf* oInst; 55 | 56 | bool check_cpu_features(); 57 | struct opaque_private; 58 | opaque_private* prv; 59 | 60 | bool bHaveAes; 61 | }; 62 | -------------------------------------------------------------------------------- /jext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using namespace rapidjson; 4 | 5 | /* This macro brings rapidjson more in line with other libs */ 6 | inline const Value* GetObjectMember(const Value& obj, const char* key) 7 | { 8 | Value::ConstMemberIterator itr = obj.FindMember(key); 9 | if (itr != obj.MemberEnd()) 10 | return &itr->value; 11 | else 12 | return nullptr; 13 | } 14 | -------------------------------------------------------------------------------- /jpsock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "msgstruct.h" 9 | 10 | /* Our pool can have two kinds of errors: 11 | - Parsing or connection error 12 | Those are fatal errors (we drop the connection if we encounter them). 13 | After they are constructed from const char* strings from various places. 14 | (can be from read-only mem), we passs them in an exectutor message 15 | once the recv thread expires. 16 | - Call error 17 | This error happens when the "server says no". Usually because the job was 18 | outdated, or we somehow got the hash wrong. It isn't fatal. 19 | We parse it in-situ in the network buffer, after that we copy it to a 20 | std::string. Executor will move the buffer via an r-value ref. 21 | */ 22 | class base_socket; 23 | 24 | class jpsock 25 | { 26 | public: 27 | jpsock(size_t id, bool tls); 28 | ~jpsock(); 29 | 30 | bool connect(const char* sAddr, std::string& sConnectError); 31 | void disconnect(); 32 | 33 | bool cmd_login(const char* sLogin, const char* sPassword); 34 | bool cmd_submit(const char* sJobId, uint32_t iNonce, const uint8_t* bResult); 35 | 36 | static bool hex2bin(const char* in, unsigned int len, unsigned char* out); 37 | static void bin2hex(const unsigned char* in, unsigned int len, char* out); 38 | 39 | inline bool is_running() { return bRunning; } 40 | inline bool is_logged_in() { return bLoggedIn; } 41 | 42 | std::string&& get_call_error(); 43 | bool have_sock_error() { return bHaveSocketError; } 44 | 45 | inline static uint64_t t32_to_t64(uint32_t t) { return 0xFFFFFFFFFFFFFFFFULL / (0xFFFFFFFFULL / ((uint64_t)t)); } 46 | inline static uint64_t t64_to_diff(uint64_t t) { return 0xFFFFFFFFFFFFFFFFULL / t; } 47 | inline static uint64_t diff_to_t64(uint64_t d) { return 0xFFFFFFFFFFFFFFFFULL / d; } 48 | 49 | inline uint64_t get_current_diff() { return iJobDiff; } 50 | 51 | bool get_current_job(pool_job& job); 52 | 53 | size_t pool_id; 54 | 55 | bool set_socket_error(const char* a); 56 | bool set_socket_error(const char* a, const char* b); 57 | bool set_socket_error(const char* a, size_t len); 58 | bool set_socket_error_strerr(const char* a); 59 | bool set_socket_error_strerr(const char* a, int res); 60 | 61 | private: 62 | std::atomic bRunning; 63 | std::atomic bLoggedIn; 64 | 65 | uint8_t* bJsonRecvMem; 66 | uint8_t* bJsonParseMem; 67 | uint8_t* bJsonCallMem; 68 | 69 | static constexpr size_t iJsonMemSize = 4096; 70 | static constexpr size_t iSockBufferSize = 4096; 71 | 72 | struct call_rsp; 73 | struct opaque_private; 74 | struct opq_json_val; 75 | 76 | void jpsock_thread(); 77 | bool jpsock_thd_main(); 78 | bool process_line(char* line, size_t len); 79 | bool process_pool_job(const opq_json_val* params); 80 | bool cmd_ret_wait(const char* sPacket, opq_json_val& poResult); 81 | 82 | char sMinerId[64]; 83 | std::atomic iJobDiff; 84 | 85 | std::string sSocketError; 86 | std::atomic bHaveSocketError; 87 | 88 | std::mutex call_mutex; 89 | std::condition_variable call_cond; 90 | std::thread* oRecvThd; 91 | 92 | std::mutex job_mutex; 93 | pool_job oCurrentJob; 94 | 95 | opaque_private* prv; 96 | base_socket* sck; 97 | }; 98 | 99 | -------------------------------------------------------------------------------- /minethd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program. If not, see . 14 | * 15 | * Additional permission under GNU GPL version 3 section 7 16 | * 17 | * If you modify this Program, or any covered work, by linking or combining 18 | * it with OpenSSL (or a modified version of that library), containing parts 19 | * covered by the terms of OpenSSL License and SSLeay License, the licensors 20 | * of this Program grant you additional permission to convey the resulting work. 21 | * 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "console.h" 29 | 30 | #ifdef _WIN32 31 | #include 32 | 33 | void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) 34 | { 35 | SetThreadAffinityMask(h, 1 << cpu_id); 36 | } 37 | #else 38 | #include 39 | 40 | #if defined(__APPLE__) 41 | #include 42 | #include 43 | #define SYSCTL_CORE_COUNT "machdep.cpu.core_count" 44 | #endif 45 | 46 | void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) 47 | { 48 | #if defined(__APPLE__) 49 | thread_port_t mach_thread; 50 | thread_affinity_policy_data_t policy = { (int)cpu_id }; 51 | mach_thread = pthread_mach_thread_np(h); 52 | thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1); 53 | #else 54 | cpu_set_t mn; 55 | CPU_ZERO(&mn); 56 | CPU_SET(cpu_id, &mn); 57 | pthread_setaffinity_np(h, sizeof(cpu_set_t), &mn); 58 | #endif 59 | } 60 | #endif // _WIN32 61 | 62 | #include "executor.h" 63 | #include "minethd.h" 64 | #include "jconf.h" 65 | #include "crypto/cryptonight.h" 66 | 67 | telemetry::telemetry(size_t iThd) 68 | { 69 | ppHashCounts = new uint64_t*[iThd]; 70 | ppTimestamps = new uint64_t*[iThd]; 71 | iBucketTop = new uint32_t[iThd]; 72 | 73 | for (size_t i = 0; i < iThd; i++) 74 | { 75 | ppHashCounts[i] = new uint64_t[iBucketSize]; 76 | ppTimestamps[i] = new uint64_t[iBucketSize]; 77 | iBucketTop[i] = 0; 78 | memset(ppHashCounts[0], 0, sizeof(uint64_t) * iBucketSize); 79 | memset(ppTimestamps[0], 0, sizeof(uint64_t) * iBucketSize); 80 | } 81 | } 82 | 83 | double telemetry::calc_telemetry_data(size_t iLastMilisec, size_t iThread) 84 | { 85 | using namespace std::chrono; 86 | uint64_t iTimeNow = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); 87 | 88 | uint64_t iEarliestHashCnt = 0; 89 | uint64_t iEarliestStamp = 0; 90 | uint64_t iLastestStamp = 0; 91 | uint64_t iLastestHashCnt = 0; 92 | bool bHaveFullSet = false; 93 | 94 | //Start at 1, buckettop points to next empty 95 | for (size_t i = 1; i < iBucketSize; i++) 96 | { 97 | size_t idx = (iBucketTop[iThread] - i) & iBucketMask; //overflow expected here 98 | 99 | if (ppTimestamps[iThread][idx] == 0) 100 | break; //That means we don't have the data yet 101 | 102 | if (iLastestStamp == 0) 103 | { 104 | iLastestStamp = ppTimestamps[iThread][idx]; 105 | iLastestHashCnt = ppHashCounts[iThread][idx]; 106 | } 107 | 108 | if (iTimeNow - ppTimestamps[iThread][idx] > iLastMilisec) 109 | { 110 | bHaveFullSet = true; 111 | break; //We are out of the requested time period 112 | } 113 | 114 | iEarliestStamp = ppTimestamps[iThread][idx]; 115 | iEarliestHashCnt = ppHashCounts[iThread][idx]; 116 | } 117 | 118 | if (!bHaveFullSet || iEarliestStamp == 0 || iLastestStamp == 0) 119 | return nan(""); 120 | 121 | //Don't think that can happen, but just in case 122 | if (iLastestStamp - iEarliestStamp == 0) 123 | return nan(""); 124 | 125 | double fHashes, fTime; 126 | fHashes = iLastestHashCnt - iEarliestHashCnt; 127 | fTime = iLastestStamp - iEarliestStamp; 128 | fTime /= 1000.0; 129 | 130 | return fHashes / fTime; 131 | } 132 | 133 | void telemetry::push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp) 134 | { 135 | size_t iTop = iBucketTop[iThd]; 136 | ppHashCounts[iThd][iTop] = iHashCount; 137 | ppTimestamps[iThd][iTop] = iTimestamp; 138 | 139 | iBucketTop[iThd] = (iTop + 1) & iBucketMask; 140 | } 141 | 142 | minethd::minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg) 143 | { 144 | oWork = pWork; 145 | bQuit = 0; 146 | iThreadNo = (uint8_t)iNo; 147 | iJobNo = 0; 148 | iHashCount = 0; 149 | iTimestamp = 0; 150 | 151 | ctx.device_id = (int)cfg.id; 152 | ctx.device_blocks = (int)cfg.blocks; 153 | ctx.device_threads = (int)cfg.threads; 154 | ctx.device_bfactor = (int)cfg.bfactor; 155 | ctx.device_bsleep = (int)cfg.bsleep; 156 | 157 | oWorkThd = std::thread(&minethd::work_main, this); 158 | } 159 | 160 | std::atomic minethd::iGlobalJobNo; 161 | std::atomic minethd::iConsumeCnt; //Threads get jobs as they are initialized 162 | minethd::miner_work minethd::oGlobalWork; 163 | uint64_t minethd::iThreadCount = 0; 164 | 165 | bool minethd::self_test() 166 | { 167 | cryptonight_ctx* ctx0; 168 | unsigned char out[32]; 169 | bool bResult; 170 | 171 | ctx0 = new cryptonight_ctx; 172 | if(jconf::inst()->HaveHardwareAes()) 173 | { 174 | cryptonight_hash_ctx("This is a test", 14, out, ctx0); 175 | bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; 176 | } 177 | else 178 | { 179 | cryptonight_hash_ctx_soft("This is a test", 14, out, ctx0); 180 | bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; 181 | } 182 | delete ctx0; 183 | 184 | if(!bResult) 185 | printer::inst()->print_msg(L0, 186 | "Cryptonight hash self-test failed. This might be caused by bad compiler optimizations."); 187 | 188 | return bResult; 189 | } 190 | 191 | std::vector* minethd::thread_starter(miner_work& pWork) 192 | { 193 | iGlobalJobNo = 0; 194 | iConsumeCnt = 0; 195 | std::vector* pvThreads = new std::vector; 196 | 197 | size_t i, n = jconf::inst()->GetThreadCount(); 198 | pvThreads->reserve(n); 199 | 200 | jconf::thd_cfg cfg; 201 | for (i = 0; i < n; i++) 202 | { 203 | jconf::inst()->GetThreadConfig(i, cfg); 204 | 205 | minethd* thd = new minethd(pWork, i, cfg); 206 | 207 | if(cfg.cpu_aff >= 0) 208 | { 209 | #if defined(__APPLE__) 210 | printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); 211 | #endif 212 | thd_setaffinity(thd->oWorkThd.native_handle(), cfg.cpu_aff); 213 | } 214 | 215 | pvThreads->push_back(thd); 216 | 217 | if(cfg.cpu_aff >= 0) 218 | printer::inst()->print_msg(L1, "Starting GPU thread, affinity: %d.", (int)cfg.cpu_aff); 219 | } 220 | 221 | iThreadCount = n; 222 | return pvThreads; 223 | } 224 | 225 | void minethd::switch_work(miner_work& pWork) 226 | { 227 | // iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work 228 | // faster than threads can consume them. This should never happen in real life. 229 | // Pool cant physically send jobs faster than every 250ms or so due to net latency. 230 | 231 | while (iConsumeCnt.load(std::memory_order_seq_cst) < iThreadCount) 232 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 233 | 234 | oGlobalWork = pWork; 235 | iConsumeCnt.store(0, std::memory_order_seq_cst); 236 | iGlobalJobNo++; 237 | } 238 | 239 | void minethd::consume_work() 240 | { 241 | memcpy(&oWork, &oGlobalWork, sizeof(miner_work)); 242 | iJobNo++; 243 | iConsumeCnt++; 244 | } 245 | 246 | void minethd::work_main() 247 | { 248 | uint64_t iCount = 0; 249 | uint32_t iNonce; 250 | 251 | iConsumeCnt++; 252 | 253 | if(cuda_get_deviceinfo(&ctx) != 1 || cryptonight_extra_cpu_init(&ctx) != 1) 254 | { 255 | printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", (int)iThreadNo); 256 | exit(0); 257 | } 258 | 259 | while (bQuit == 0) 260 | { 261 | if (oWork.bStall) 262 | { 263 | /* We are stalled here because the executor didn't find a job for us yet, 264 | either because of network latency, or a socket problem. Since we are 265 | raison d'etre of this software it us sensible to just wait until we have something*/ 266 | 267 | while (iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) 268 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 269 | 270 | consume_work(); 271 | continue; 272 | } 273 | 274 | cryptonight_extra_cpu_set_data(&ctx, oWork.bWorkBlob, oWork.iWorkSize); 275 | iNonce = calc_start_nonce(oWork.iResumeCnt); 276 | 277 | assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); 278 | 279 | while(iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) 280 | { 281 | uint32_t foundNonce[10]; 282 | uint32_t foundCount; 283 | 284 | cryptonight_extra_cpu_prepare(&ctx, iNonce); 285 | cryptonight_core_cpu_hash(&ctx); 286 | cryptonight_extra_cpu_final(&ctx, iNonce, oWork.iTarget, &foundCount, foundNonce); 287 | 288 | for(size_t i = 0; i < foundCount; i++) 289 | { 290 | executor::inst()->push_event(ex_event(job_result(oWork.sJobID, oWork.bWorkBlob, 291 | oWork.iWorkSize, oWork.iTarget, foundNonce[i]), oWork.iPoolId)); 292 | } 293 | 294 | iCount += ctx.device_blocks * ctx.device_threads; 295 | iNonce += ctx.device_blocks * ctx.device_threads; 296 | 297 | using namespace std::chrono; 298 | uint64_t iStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); 299 | iHashCount.store(iCount, std::memory_order_relaxed); 300 | iTimestamp.store(iStamp, std::memory_order_relaxed); 301 | std::this_thread::yield(); 302 | } 303 | 304 | consume_work(); 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /minethd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "nvcc_code/cryptonight.h" 5 | #include "jconf.h" 6 | 7 | class telemetry 8 | { 9 | public: 10 | telemetry(size_t iThd); 11 | void push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp); 12 | double calc_telemetry_data(size_t iLastMilisec, size_t iThread); 13 | 14 | private: 15 | constexpr static size_t iBucketSize = 2 << 11; //Power of 2 to simplify calculations 16 | constexpr static size_t iBucketMask = iBucketSize - 1; 17 | uint32_t* iBucketTop; 18 | uint64_t** ppHashCounts; 19 | uint64_t** ppTimestamps; 20 | }; 21 | 22 | class minethd 23 | { 24 | public: 25 | struct miner_work 26 | { 27 | char sJobID[64]; 28 | uint8_t bWorkBlob[112]; 29 | uint32_t iWorkSize; 30 | uint32_t iResumeCnt; 31 | uint64_t iTarget; 32 | bool bStall; 33 | size_t iPoolId; 34 | 35 | miner_work() : iWorkSize(0), bStall(true), iPoolId(0) { } 36 | 37 | miner_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize, 38 | uint32_t iResumeCnt, uint64_t iTarget, size_t iPoolId) : iWorkSize(iWorkSize), 39 | iResumeCnt(iResumeCnt), iTarget(iTarget), bStall(false), iPoolId(iPoolId) 40 | { 41 | assert(iWorkSize <= sizeof(bWorkBlob)); 42 | memcpy(this->sJobID, sJobID, sizeof(miner_work::sJobID)); 43 | memcpy(this->bWorkBlob, bWork, iWorkSize); 44 | } 45 | 46 | miner_work(miner_work const&) = delete; 47 | 48 | miner_work& operator=(miner_work const& from) 49 | { 50 | assert(this != &from); 51 | 52 | iWorkSize = from.iWorkSize; 53 | iResumeCnt = from.iResumeCnt; 54 | iTarget = from.iTarget; 55 | bStall = from.bStall; 56 | iPoolId = from.iPoolId; 57 | 58 | assert(iWorkSize <= sizeof(bWorkBlob)); 59 | memcpy(sJobID, from.sJobID, sizeof(sJobID)); 60 | memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); 61 | 62 | return *this; 63 | } 64 | 65 | miner_work(miner_work&& from) : iWorkSize(from.iWorkSize), iTarget(from.iTarget), 66 | bStall(from.bStall), iPoolId(from.iPoolId) 67 | { 68 | assert(iWorkSize <= sizeof(bWorkBlob)); 69 | memcpy(sJobID, from.sJobID, sizeof(sJobID)); 70 | memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); 71 | } 72 | 73 | miner_work& operator=(miner_work&& from) 74 | { 75 | assert(this != &from); 76 | 77 | iWorkSize = from.iWorkSize; 78 | iResumeCnt = from.iResumeCnt; 79 | iTarget = from.iTarget; 80 | bStall = from.bStall; 81 | iPoolId = from.iPoolId; 82 | 83 | assert(iWorkSize <= sizeof(bWorkBlob)); 84 | memcpy(sJobID, from.sJobID, sizeof(sJobID)); 85 | memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); 86 | 87 | return *this; 88 | } 89 | }; 90 | 91 | static void switch_work(miner_work& pWork); 92 | static std::vector* thread_starter(miner_work& pWork); 93 | static bool self_test(); 94 | 95 | std::atomic iHashCount; 96 | std::atomic iTimestamp; 97 | 98 | private: 99 | minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg); 100 | 101 | // We use the top 8 bits of the nonce for thread and resume 102 | // This allows us to resume up to 64 threads 4 times before 103 | // we get nonce collisions 104 | // Bottom 24 bits allow for an hour of work at 4000 H/s 105 | inline uint32_t calc_start_nonce(uint32_t resume) 106 | { return (resume * iThreadCount + iThreadNo) << 24; } 107 | 108 | void work_main(); 109 | void consume_work(); 110 | 111 | static std::atomic iGlobalJobNo; 112 | static std::atomic iConsumeCnt; 113 | static uint64_t iThreadCount; 114 | uint64_t iJobNo; 115 | 116 | static miner_work oGlobalWork; 117 | miner_work oWork; 118 | 119 | std::thread oWorkThd; 120 | uint8_t iThreadNo; 121 | 122 | nvid_ctx ctx; 123 | 124 | bool bQuit; 125 | }; 126 | 127 | -------------------------------------------------------------------------------- /msgstruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | // Structures that we use to pass info between threads constructors are here just to make 7 | // the stack allocation take up less space, heap is a shared resouce that needs locks too of course 8 | 9 | struct pool_job 10 | { 11 | char sJobID[64]; 12 | uint8_t bWorkBlob[88]; 13 | uint64_t iTarget; 14 | uint32_t iWorkLen; 15 | uint32_t iResumeCnt; 16 | 17 | pool_job() : iWorkLen(0), iResumeCnt(0) {} 18 | pool_job(const char* sJobID, uint64_t iTarget, const uint8_t* bWorkBlob, uint32_t iWorkLen) : 19 | iTarget(iTarget), iWorkLen(iWorkLen), iResumeCnt(0) 20 | { 21 | assert(iWorkLen <= sizeof(pool_job::bWorkBlob)); 22 | memcpy(this->sJobID, sJobID, sizeof(pool_job::sJobID)); 23 | memcpy(this->bWorkBlob, bWorkBlob, iWorkLen); 24 | } 25 | }; 26 | 27 | struct job_result 28 | { 29 | uint8_t bResult[32]; 30 | char sJobID[64]; 31 | uint64_t iTarget; 32 | uint8_t bWorkBlob[88]; 33 | uint32_t iWorkLen; 34 | uint32_t iNonce; 35 | 36 | job_result() {} 37 | job_result(const char* sJobID, uint8_t* bWorkBlob, uint32_t iWorkLen, uint64_t iTarget, 38 | uint32_t iNonce) : iTarget(iTarget), iWorkLen(iWorkLen), iNonce(iNonce) 39 | { 40 | assert(iWorkLen <= sizeof(job_result::bWorkBlob)); 41 | 42 | memcpy(this->sJobID, sJobID, sizeof(job_result::sJobID)); 43 | memcpy(this->bWorkBlob, bWorkBlob, iWorkLen); 44 | memset(this->bResult, 0, sizeof(job_result::bResult)); 45 | } 46 | }; 47 | 48 | enum ex_event_name { EV_INVALID_VAL, EV_SOCK_READY, EV_SOCK_ERROR, 49 | EV_POOL_HAVE_JOB, EV_MINER_HAVE_RESULT, EV_PERF_TICK, EV_RECONNECT, 50 | EV_SWITCH_POOL, EV_DEV_POOL_EXIT, EV_USR_HASHRATE, EV_USR_RESULTS, EV_USR_CONNSTAT, 51 | EV_HASHRATE_LOOP, EV_HTML_HASHRATE, EV_HTML_RESULTS, EV_HTML_CONNSTAT }; 52 | 53 | /* 54 | This is how I learned to stop worrying and love c++11 =). 55 | Ghosts of endless heap allocations have finally been exorcised. Thanks 56 | to the nifty magic of move semantics, string will only be allocated 57 | once on the heap. Considering that it makes a jorney across stack, 58 | heap alloced queue, to another stack before being finally processed 59 | I think it is kind of nifty, don't you? 60 | Also note that for non-arg events we only copy two qwords 61 | */ 62 | 63 | struct ex_event 64 | { 65 | ex_event_name iName; 66 | size_t iPoolId; 67 | 68 | union 69 | { 70 | pool_job oPoolJob; 71 | job_result oJobResult; 72 | std::string sSocketError; 73 | }; 74 | 75 | ex_event() { iName = EV_INVALID_VAL; iPoolId = 0;} 76 | ex_event(std::string&& err, size_t id) : iName(EV_SOCK_ERROR), iPoolId(id), sSocketError(std::move(err)) { } 77 | ex_event(job_result dat, size_t id) : iName(EV_MINER_HAVE_RESULT), iPoolId(id), oJobResult(dat) {} 78 | ex_event(pool_job dat, size_t id) : iName(EV_POOL_HAVE_JOB), iPoolId(id), oPoolJob(dat) {} 79 | ex_event(ex_event_name ev, size_t id = 0) : iName(ev), iPoolId(id) {} 80 | 81 | // Delete the copy operators to make sure we are moving only what is needed 82 | ex_event(ex_event const&) = delete; 83 | ex_event& operator=(ex_event const&) = delete; 84 | 85 | ex_event(ex_event&& from) 86 | { 87 | iName = from.iName; 88 | iPoolId = from.iPoolId; 89 | 90 | switch(iName) 91 | { 92 | case EV_SOCK_ERROR: 93 | new (&sSocketError) std::string(std::move(from.sSocketError)); 94 | break; 95 | case EV_MINER_HAVE_RESULT: 96 | oJobResult = from.oJobResult; 97 | break; 98 | case EV_POOL_HAVE_JOB: 99 | oPoolJob = from.oPoolJob; 100 | break; 101 | default: 102 | break; 103 | } 104 | } 105 | 106 | ex_event& operator=(ex_event&& from) 107 | { 108 | assert(this != &from); 109 | 110 | if(iName == EV_SOCK_ERROR) 111 | sSocketError.~basic_string(); 112 | 113 | iName = from.iName; 114 | iPoolId = from.iPoolId; 115 | 116 | switch(iName) 117 | { 118 | case EV_SOCK_ERROR: 119 | new (&sSocketError) std::string(); 120 | sSocketError = std::move(from.sSocketError); 121 | break; 122 | case EV_MINER_HAVE_RESULT: 123 | oJobResult = from.oJobResult; 124 | break; 125 | case EV_POOL_HAVE_JOB: 126 | oPoolJob = from.oPoolJob; 127 | break; 128 | default: 129 | break; 130 | } 131 | 132 | return *this; 133 | } 134 | 135 | ~ex_event() 136 | { 137 | if(iName == EV_SOCK_ERROR) 138 | sSocketError.~basic_string(); 139 | } 140 | }; 141 | -------------------------------------------------------------------------------- /nvcc_code/cryptonight.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct { 6 | int device_id; 7 | const char *device_name; 8 | int device_arch[2]; 9 | int device_mpcount; 10 | int device_blocks; 11 | int device_threads; 12 | int device_bfactor; 13 | int device_bsleep; 14 | 15 | uint32_t *d_input; 16 | uint32_t inputlen; 17 | uint32_t *d_result_count; 18 | uint32_t *d_result_nonce; 19 | uint32_t *d_long_state; 20 | uint32_t *d_ctx_state; 21 | uint32_t *d_ctx_a; 22 | uint32_t *d_ctx_b; 23 | uint32_t *d_ctx_key1; 24 | uint32_t *d_ctx_key2; 25 | uint32_t *d_ctx_text; 26 | } nvid_ctx; 27 | 28 | extern "C" { 29 | 30 | /** get device count 31 | * 32 | * @param deviceCount[out] cuda device count 33 | * @return error code: 0 == error is occurred, 1 == no error 34 | */ 35 | int cuda_get_devicecount( int* deviceCount); 36 | int cuda_get_deviceinfo(nvid_ctx *ctx); 37 | int cryptonight_extra_cpu_init(nvid_ctx *ctx); 38 | void cryptonight_extra_cpu_set_data( nvid_ctx* ctx, const void *data, uint32_t len); 39 | void cryptonight_extra_cpu_prepare(nvid_ctx* ctx, uint32_t startNonce); 40 | void cryptonight_core_cpu_hash(nvid_ctx* ctx); 41 | void cryptonight_extra_cpu_final(nvid_ctx* ctx, uint32_t startNonce, uint64_t target, uint32_t* rescount, uint32_t *resnonce); 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /nvcc_code/cuda_blake.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct { 4 | uint32_t h[8], s[4], t[2]; 5 | int buflen, nullt; 6 | uint8_t buf[64]; 7 | } blake_state; 8 | 9 | #define U8TO32(p) \ 10 | (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ 11 | ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) 12 | 13 | #define U32TO8(p, v) \ 14 | (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ 15 | (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); 16 | 17 | #define BLAKE_ROT(x,n) ROTR32(x, n) 18 | #define BLAKE_G(a,b,c,d,e) \ 19 | v[a] += (m[d_blake_sigma[i][e]] ^ d_blake_cst[d_blake_sigma[i][e+1]]) + v[b]; \ 20 | v[d] = BLAKE_ROT(v[d] ^ v[a],16); \ 21 | v[c] += v[d]; \ 22 | v[b] = BLAKE_ROT(v[b] ^ v[c],12); \ 23 | v[a] += (m[d_blake_sigma[i][e+1]] ^ d_blake_cst[d_blake_sigma[i][e]])+v[b]; \ 24 | v[d] = BLAKE_ROT(v[d] ^ v[a], 8); \ 25 | v[c] += v[d]; \ 26 | v[b] = BLAKE_ROT(v[b] ^ v[c], 7); 27 | 28 | __constant__ uint8_t d_blake_sigma[14][16] = 29 | { 30 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 31 | {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, 32 | {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, 33 | {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, 34 | {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, 35 | {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, 36 | {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, 37 | {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, 38 | {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, 39 | {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, 40 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 41 | {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, 42 | {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, 43 | {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8} 44 | }; 45 | __constant__ uint32_t d_blake_cst[16] 46 | = { 47 | 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 48 | 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, 49 | 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 50 | 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917 51 | }; 52 | 53 | __device__ void cn_blake_compress(blake_state * __restrict__ S, const uint8_t * __restrict__ block) 54 | { 55 | uint32_t v[16], m[16], i; 56 | 57 | for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4); 58 | for (i = 0; i < 8; ++i) v[i] = S->h[i]; 59 | v[ 8] = S->s[0] ^ 0x243F6A88; 60 | v[ 9] = S->s[1] ^ 0x85A308D3; 61 | v[10] = S->s[2] ^ 0x13198A2E; 62 | v[11] = S->s[3] ^ 0x03707344; 63 | v[12] = 0xA4093822; 64 | v[13] = 0x299F31D0; 65 | v[14] = 0x082EFA98; 66 | v[15] = 0xEC4E6C89; 67 | 68 | if (S->nullt == 0) 69 | { 70 | v[12] ^= S->t[0]; 71 | v[13] ^= S->t[0]; 72 | v[14] ^= S->t[1]; 73 | v[15] ^= S->t[1]; 74 | } 75 | 76 | for (i = 0; i < 14; ++i) 77 | { 78 | BLAKE_G(0, 4, 8, 12, 0); 79 | BLAKE_G(1, 5, 9, 13, 2); 80 | BLAKE_G(2, 6, 10, 14, 4); 81 | BLAKE_G(3, 7, 11, 15, 6); 82 | BLAKE_G(3, 4, 9, 14, 14); 83 | BLAKE_G(2, 7, 8, 13, 12); 84 | BLAKE_G(0, 5, 10, 15, 8); 85 | BLAKE_G(1, 6, 11, 12, 10); 86 | } 87 | 88 | for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i]; 89 | for (i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4]; 90 | } 91 | 92 | __device__ void cn_blake_update(blake_state * __restrict__ S, const uint8_t * __restrict__ data, uint64_t datalen) 93 | { 94 | int left = S->buflen >> 3; 95 | int fill = 64 - left; 96 | 97 | if (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) 98 | { 99 | memcpy((void *) (S->buf + left), (void *) data, fill); 100 | S->t[0] += 512; 101 | if (S->t[0] == 0) S->t[1]++; 102 | cn_blake_compress(S, S->buf); 103 | data += fill; 104 | datalen -= (fill << 3); 105 | left = 0; 106 | } 107 | 108 | while (datalen >= 512) 109 | { 110 | S->t[0] += 512; 111 | if (S->t[0] == 0) S->t[1]++; 112 | cn_blake_compress(S, data); 113 | data += 64; 114 | datalen -= 512; 115 | } 116 | 117 | if (datalen > 0) 118 | { 119 | memcpy((void *) (S->buf + left), (void *) data, datalen >> 3); 120 | S->buflen = (left << 3) + datalen; 121 | } 122 | else 123 | { 124 | S->buflen = 0; 125 | } 126 | } 127 | 128 | __device__ void cn_blake_final(blake_state * __restrict__ S, uint8_t * __restrict__ digest) 129 | { 130 | const uint8_t padding[] = 131 | { 132 | 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 133 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 134 | }; 135 | 136 | uint8_t pa = 0x81, pb = 0x01; 137 | uint8_t msglen[8]; 138 | uint32_t lo = S->t[0] + S->buflen, hi = S->t[1]; 139 | if (lo < (unsigned) S->buflen) hi++; 140 | U32TO8(msglen + 0, hi); 141 | U32TO8(msglen + 4, lo); 142 | 143 | if (S->buflen == 440) 144 | { 145 | S->t[0] -= 8; 146 | cn_blake_update(S, &pa, 8); 147 | } 148 | else 149 | { 150 | if (S->buflen < 440) 151 | { 152 | if (S->buflen == 0) S->nullt = 1; 153 | S->t[0] -= 440 - S->buflen; 154 | cn_blake_update(S, padding, 440 - S->buflen); 155 | } 156 | else 157 | { 158 | S->t[0] -= 512 - S->buflen; 159 | cn_blake_update(S, padding, 512 - S->buflen); 160 | S->t[0] -= 440; 161 | cn_blake_update(S, padding + 1, 440); 162 | S->nullt = 1; 163 | } 164 | cn_blake_update(S, &pb, 8); 165 | S->t[0] -= 8; 166 | } 167 | S->t[0] -= 64; 168 | cn_blake_update(S, msglen, 64); 169 | 170 | U32TO8(digest + 0, S->h[0]); 171 | U32TO8(digest + 4, S->h[1]); 172 | U32TO8(digest + 8, S->h[2]); 173 | U32TO8(digest + 12, S->h[3]); 174 | U32TO8(digest + 16, S->h[4]); 175 | U32TO8(digest + 20, S->h[5]); 176 | U32TO8(digest + 24, S->h[6]); 177 | U32TO8(digest + 28, S->h[7]); 178 | } 179 | 180 | __device__ void cn_blake(const uint8_t * __restrict__ in, uint64_t inlen, uint8_t * __restrict__ out) 181 | { 182 | blake_state bs; 183 | blake_state *S = (blake_state *)&bs; 184 | 185 | S->h[0] = 0x6A09E667; S->h[1] = 0xBB67AE85; S->h[2] = 0x3C6EF372; 186 | S->h[3] = 0xA54FF53A; S->h[4] = 0x510E527F; S->h[5] = 0x9B05688C; 187 | S->h[6] = 0x1F83D9AB; S->h[7] = 0x5BE0CD19; 188 | S->t[0] = S->t[1] = S->buflen = S->nullt = 0; 189 | S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; 190 | 191 | cn_blake_update(S, (uint8_t *)in, inlen * 8); 192 | cn_blake_final(S, (uint8_t *)out); 193 | } 194 | -------------------------------------------------------------------------------- /nvcc_code/cuda_device.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | static inline void exit_if_cudaerror(int thr_id, const char *file, int line) 7 | { 8 | cudaError_t err = cudaGetLastError(); 9 | if(err != cudaSuccess) 10 | { 11 | printf("\nGPU %d: %s\n%s line %d\n", thr_id, cudaGetErrorString(err), file, line); 12 | exit(1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /nvcc_code/cuda_extra.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __INTELLISENSE__ 4 | #define __CUDA_ARCH__ 520 5 | /* avoid red underlining */ 6 | 7 | struct uint3 8 | { 9 | unsigned int x, y, z; 10 | }; 11 | 12 | struct uint3 threadIdx; 13 | struct uint3 blockIdx; 14 | struct uint3 blockDim; 15 | #define __funnelshift_r(a,b,c) 1 16 | #define __syncthreads() 17 | #define asm(x) 18 | #define __shfl(a,b,c) 1 19 | #endif 20 | 21 | #define MEMORY (1 << 21) // 2 MiB / 2097152 B 22 | #define ITER (1 << 20) // 1048576 23 | #define AES_BLOCK_SIZE 16 24 | #define AES_KEY_SIZE 32 25 | #define INIT_SIZE_BLK 8 26 | #define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE) // 128 B 27 | 28 | #define C32(x) ((uint32_t)(x ## U)) 29 | #define T32(x) ((x) & C32(0xFFFFFFFF)) 30 | 31 | #if __CUDA_ARCH__ >= 350 32 | __forceinline__ __device__ uint64_t cuda_ROTL64(const uint64_t value, const int offset) 33 | { 34 | uint2 result; 35 | if(offset >= 32) 36 | { 37 | asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.x) : "r"(__double2loint(__longlong_as_double(value))), "r"(__double2hiint(__longlong_as_double(value))), "r"(offset)); 38 | asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.y) : "r"(__double2hiint(__longlong_as_double(value))), "r"(__double2loint(__longlong_as_double(value))), "r"(offset)); 39 | } 40 | else 41 | { 42 | asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.x) : "r"(__double2hiint(__longlong_as_double(value))), "r"(__double2loint(__longlong_as_double(value))), "r"(offset)); 43 | asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.y) : "r"(__double2loint(__longlong_as_double(value))), "r"(__double2hiint(__longlong_as_double(value))), "r"(offset)); 44 | } 45 | return __double_as_longlong(__hiloint2double(result.y, result.x)); 46 | } 47 | #define ROTL64(x, n) (cuda_ROTL64(x, n)) 48 | #else 49 | #define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) 50 | #endif 51 | 52 | #if __CUDA_ARCH__ < 350 53 | #define ROTL32(x, n) T32(((x) << (n)) | ((x) >> (32 - (n)))) 54 | #define ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) 55 | #else 56 | #define ROTL32(x, n) __funnelshift_l( (x), (x), (n) ) 57 | #define ROTR32(x, n) __funnelshift_r( (x), (x), (n) ) 58 | #endif 59 | 60 | #define MEMSET8(dst,what,cnt) { \ 61 | int i_memset8; \ 62 | uint64_t *out_memset8 = (uint64_t *)(dst); \ 63 | for( i_memset8 = 0; i_memset8 < cnt; i_memset8++ ) \ 64 | out_memset8[i_memset8] = (what); } 65 | 66 | #define MEMSET4(dst,what,cnt) { \ 67 | int i_memset4; \ 68 | uint32_t *out_memset4 = (uint32_t *)(dst); \ 69 | for( i_memset4 = 0; i_memset4 < cnt; i_memset4++ ) \ 70 | out_memset4[i_memset4] = (what); } 71 | 72 | #define MEMCPY8(dst,src,cnt) { \ 73 | int i_memcpy8; \ 74 | uint64_t *in_memcpy8 = (uint64_t *)(src); \ 75 | uint64_t *out_memcpy8 = (uint64_t *)(dst); \ 76 | for( i_memcpy8 = 0; i_memcpy8 < cnt; i_memcpy8++ ) \ 77 | out_memcpy8[i_memcpy8] = in_memcpy8[i_memcpy8]; } 78 | 79 | #define MEMCPY4(dst,src,cnt) { \ 80 | int i_memcpy4; \ 81 | uint32_t *in_memcpy4 = (uint32_t *)(src); \ 82 | uint32_t *out_memcpy4 = (uint32_t *)(dst); \ 83 | for( i_memcpy4 = 0; i_memcpy4 < cnt; i_memcpy4++ ) \ 84 | out_memcpy4[i_memcpy4] = in_memcpy4[i_memcpy4]; } 85 | 86 | #define XOR_BLOCKS(a,b) { \ 87 | ((uint64_t *)a)[0] ^= ((uint64_t *)b)[0]; \ 88 | ((uint64_t *)a)[1] ^= ((uint64_t *)b)[1]; } 89 | 90 | #define XOR_BLOCKS_DST(x,y,z) { \ 91 | ((uint64_t *)z)[0] = ((uint64_t *)(x))[0] ^ ((uint64_t *)(y))[0]; \ 92 | ((uint64_t *)z)[1] = ((uint64_t *)(x))[1] ^ ((uint64_t *)(y))[1]; } 93 | 94 | #define MUL_SUM_XOR_DST(a,c,dst) { \ 95 | const uint64_t dst0 = ((uint64_t *)dst)[0]; \ 96 | uint64_t hi, lo = cuda_mul128(((uint64_t *)a)[0], dst0, &hi) + ((uint64_t *)c)[1]; \ 97 | hi += ((uint64_t *)c)[0]; \ 98 | ((uint64_t *)c)[0] = dst0 ^ hi; \ 99 | ((uint64_t *)dst)[0] = hi; \ 100 | ((uint64_t *)c)[1] = atomicExch(((unsigned long long int *)dst) + 1, (unsigned long long int)lo) ^ lo; \ 101 | } 102 | 103 | #define E2I(x) ((size_t)(((*((uint64_t*)(x)) >> 4) & 0x1ffff))) 104 | 105 | -------------------------------------------------------------------------------- /rapidjson/error/en.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_EN_H_ 16 | #define RAPIDJSON_ERROR_EN_H_ 17 | 18 | #include "error.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(switch-enum) 23 | RAPIDJSON_DIAG_OFF(covered-switch-default) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Maps error code of parsing into error message. 29 | /*! 30 | \ingroup RAPIDJSON_ERRORS 31 | \param parseErrorCode Error code obtained in parsing. 32 | \return the error message. 33 | \note User can make a copy of this function for localization. 34 | Using switch-case is safer for future modification of error codes. 35 | */ 36 | inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { 37 | switch (parseErrorCode) { 38 | case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); 39 | 40 | case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); 41 | case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); 42 | 43 | case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); 44 | 45 | case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); 46 | case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); 47 | case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); 48 | 49 | case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); 50 | 51 | case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); 52 | case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); 53 | case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); 54 | case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); 55 | case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); 56 | 57 | case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); 58 | case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); 59 | case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); 60 | 61 | case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); 62 | case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); 63 | 64 | default: return RAPIDJSON_ERROR_STRING("Unknown error."); 65 | } 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #ifdef __clang__ 71 | RAPIDJSON_DIAG_POP 72 | #endif 73 | 74 | #endif // RAPIDJSON_ERROR_EN_H_ 75 | -------------------------------------------------------------------------------- /rapidjson/error/error.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_ERROR_H_ 16 | #define RAPIDJSON_ERROR_ERROR_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(padded) 23 | #endif 24 | 25 | /*! \file error.h */ 26 | 27 | /*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ 28 | 29 | /////////////////////////////////////////////////////////////////////////////// 30 | // RAPIDJSON_ERROR_CHARTYPE 31 | 32 | //! Character type of error messages. 33 | /*! \ingroup RAPIDJSON_ERRORS 34 | The default character type is \c char. 35 | On Windows, user can define this macro as \c TCHAR for supporting both 36 | unicode/non-unicode settings. 37 | */ 38 | #ifndef RAPIDJSON_ERROR_CHARTYPE 39 | #define RAPIDJSON_ERROR_CHARTYPE char 40 | #endif 41 | 42 | /////////////////////////////////////////////////////////////////////////////// 43 | // RAPIDJSON_ERROR_STRING 44 | 45 | //! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. 46 | /*! \ingroup RAPIDJSON_ERRORS 47 | By default this conversion macro does nothing. 48 | On Windows, user can define this macro as \c _T(x) for supporting both 49 | unicode/non-unicode settings. 50 | */ 51 | #ifndef RAPIDJSON_ERROR_STRING 52 | #define RAPIDJSON_ERROR_STRING(x) x 53 | #endif 54 | 55 | RAPIDJSON_NAMESPACE_BEGIN 56 | 57 | /////////////////////////////////////////////////////////////////////////////// 58 | // ParseErrorCode 59 | 60 | //! Error code of parsing. 61 | /*! \ingroup RAPIDJSON_ERRORS 62 | \see GenericReader::Parse, GenericReader::GetParseErrorCode 63 | */ 64 | enum ParseErrorCode { 65 | kParseErrorNone = 0, //!< No error. 66 | 67 | kParseErrorDocumentEmpty, //!< The document is empty. 68 | kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. 69 | 70 | kParseErrorValueInvalid, //!< Invalid value. 71 | 72 | kParseErrorObjectMissName, //!< Missing a name for object member. 73 | kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. 74 | kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. 75 | 76 | kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. 77 | 78 | kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. 79 | kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. 80 | kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. 81 | kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. 82 | kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. 83 | 84 | kParseErrorNumberTooBig, //!< Number too big to be stored in double. 85 | kParseErrorNumberMissFraction, //!< Miss fraction part in number. 86 | kParseErrorNumberMissExponent, //!< Miss exponent in number. 87 | 88 | kParseErrorTermination, //!< Parsing was terminated. 89 | kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. 90 | }; 91 | 92 | //! Result of parsing (wraps ParseErrorCode) 93 | /*! 94 | \ingroup RAPIDJSON_ERRORS 95 | \code 96 | Document doc; 97 | ParseResult ok = doc.Parse("[42]"); 98 | if (!ok) { 99 | fprintf(stderr, "JSON parse error: %s (%u)", 100 | GetParseError_En(ok.Code()), ok.Offset()); 101 | exit(EXIT_FAILURE); 102 | } 103 | \endcode 104 | \see GenericReader::Parse, GenericDocument::Parse 105 | */ 106 | struct ParseResult { 107 | public: 108 | //! Default constructor, no error. 109 | ParseResult() : code_(kParseErrorNone), offset_(0) {} 110 | //! Constructor to set an error. 111 | ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} 112 | 113 | //! Get the error code. 114 | ParseErrorCode Code() const { return code_; } 115 | //! Get the error offset, if \ref IsError(), 0 otherwise. 116 | size_t Offset() const { return offset_; } 117 | 118 | //! Conversion to \c bool, returns \c true, iff !\ref IsError(). 119 | operator bool() const { return !IsError(); } 120 | //! Whether the result is an error. 121 | bool IsError() const { return code_ != kParseErrorNone; } 122 | 123 | bool operator==(const ParseResult& that) const { return code_ == that.code_; } 124 | bool operator==(ParseErrorCode code) const { return code_ == code; } 125 | friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } 126 | 127 | //! Reset error code. 128 | void Clear() { Set(kParseErrorNone); } 129 | //! Update error code and offset. 130 | void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } 131 | 132 | private: 133 | ParseErrorCode code_; 134 | size_t offset_; 135 | }; 136 | 137 | //! Function pointer type of GetParseError(). 138 | /*! \ingroup RAPIDJSON_ERRORS 139 | 140 | This is the prototype for \c GetParseError_X(), where \c X is a locale. 141 | User can dynamically change locale in runtime, e.g.: 142 | \code 143 | GetParseErrorFunc GetParseError = GetParseError_En; // or whatever 144 | const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); 145 | \endcode 146 | */ 147 | typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #ifdef __clang__ 152 | RAPIDJSON_DIAG_POP 153 | #endif 154 | 155 | #endif // RAPIDJSON_ERROR_ERROR_H_ 156 | -------------------------------------------------------------------------------- /rapidjson/filereadstream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 16 | #define RAPIDJSON_FILEREADSTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | RAPIDJSON_DIAG_OFF(unreachable-code) 25 | RAPIDJSON_DIAG_OFF(missing-noreturn) 26 | #endif 27 | 28 | RAPIDJSON_NAMESPACE_BEGIN 29 | 30 | //! File byte stream for input using fread(). 31 | /*! 32 | \note implements Stream concept 33 | */ 34 | class FileReadStream { 35 | public: 36 | typedef char Ch; //!< Character type (byte). 37 | 38 | //! Constructor. 39 | /*! 40 | \param fp File pointer opened for read. 41 | \param buffer user-supplied buffer. 42 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 43 | */ 44 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 45 | RAPIDJSON_ASSERT(fp_ != 0); 46 | RAPIDJSON_ASSERT(bufferSize >= 4); 47 | Read(); 48 | } 49 | 50 | Ch Peek() const { return *current_; } 51 | Ch Take() { Ch c = *current_; Read(); return c; } 52 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); } 53 | 54 | // Not implemented 55 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 56 | void Flush() { RAPIDJSON_ASSERT(false); } 57 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 58 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 59 | 60 | // For encoding detection only. 61 | const Ch* Peek4() const { 62 | return (current_ + 4 <= bufferLast_) ? current_ : 0; 63 | } 64 | 65 | private: 66 | void Read() { 67 | if (current_ < bufferLast_) 68 | ++current_; 69 | else if (!eof_) { 70 | count_ += readCount_; 71 | readCount_ = fread(buffer_, 1, bufferSize_, fp_); 72 | bufferLast_ = buffer_ + readCount_ - 1; 73 | current_ = buffer_; 74 | 75 | if (readCount_ < bufferSize_) { 76 | buffer_[readCount_] = '\0'; 77 | ++bufferLast_; 78 | eof_ = true; 79 | } 80 | } 81 | } 82 | 83 | std::FILE* fp_; 84 | Ch *buffer_; 85 | size_t bufferSize_; 86 | Ch *bufferLast_; 87 | Ch *current_; 88 | size_t readCount_; 89 | size_t count_; //!< Number of characters read 90 | bool eof_; 91 | }; 92 | 93 | RAPIDJSON_NAMESPACE_END 94 | 95 | #ifdef __clang__ 96 | RAPIDJSON_DIAG_POP 97 | #endif 98 | 99 | #endif // RAPIDJSON_FILESTREAM_H_ 100 | -------------------------------------------------------------------------------- /rapidjson/filewritestream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 16 | #define RAPIDJSON_FILEWRITESTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(unreachable-code) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of C file stream for input using fread(). 29 | /*! 30 | \note implements Stream concept 31 | */ 32 | class FileWriteStream { 33 | public: 34 | typedef char Ch; //!< Character type. Only support char. 35 | 36 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 37 | RAPIDJSON_ASSERT(fp_ != 0); 38 | } 39 | 40 | void Put(char c) { 41 | if (current_ >= bufferEnd_) 42 | Flush(); 43 | 44 | *current_++ = c; 45 | } 46 | 47 | void PutN(char c, size_t n) { 48 | size_t avail = static_cast(bufferEnd_ - current_); 49 | while (n > avail) { 50 | std::memset(current_, c, avail); 51 | current_ += avail; 52 | Flush(); 53 | n -= avail; 54 | avail = static_cast(bufferEnd_ - current_); 55 | } 56 | 57 | if (n > 0) { 58 | std::memset(current_, c, n); 59 | current_ += n; 60 | } 61 | } 62 | 63 | void Flush() { 64 | if (current_ != buffer_) { 65 | size_t result = fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); 66 | if (result < static_cast(current_ - buffer_)) { 67 | // failure deliberately ignored at this time 68 | // added to avoid warn_unused_result build errors 69 | } 70 | current_ = buffer_; 71 | } 72 | } 73 | 74 | // Not implemented 75 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 76 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 77 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 78 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 79 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 80 | 81 | private: 82 | // Prohibit copy constructor & assignment operator. 83 | FileWriteStream(const FileWriteStream&); 84 | FileWriteStream& operator=(const FileWriteStream&); 85 | 86 | std::FILE* fp_; 87 | char *buffer_; 88 | char *bufferEnd_; 89 | char *current_; 90 | }; 91 | 92 | //! Implement specialized version of PutN() with memset() for better performance. 93 | template<> 94 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 95 | stream.PutN(c, n); 96 | } 97 | 98 | RAPIDJSON_NAMESPACE_END 99 | 100 | #ifdef __clang__ 101 | RAPIDJSON_DIAG_POP 102 | #endif 103 | 104 | #endif // RAPIDJSON_FILESTREAM_H_ 105 | -------------------------------------------------------------------------------- /rapidjson/fwd.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FWD_H_ 16 | #define RAPIDJSON_FWD_H_ 17 | 18 | #include "rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | 22 | // encodings.h 23 | 24 | template struct UTF8; 25 | template struct UTF16; 26 | template struct UTF16BE; 27 | template struct UTF16LE; 28 | template struct UTF32; 29 | template struct UTF32BE; 30 | template struct UTF32LE; 31 | template struct ASCII; 32 | template struct AutoUTF; 33 | 34 | template 35 | struct Transcoder; 36 | 37 | // allocators.h 38 | 39 | class CrtAllocator; 40 | 41 | template 42 | class MemoryPoolAllocator; 43 | 44 | // stream.h 45 | 46 | template 47 | struct GenericStringStream; 48 | 49 | typedef GenericStringStream > StringStream; 50 | 51 | template 52 | struct GenericInsituStringStream; 53 | 54 | typedef GenericInsituStringStream > InsituStringStream; 55 | 56 | // stringbuffer.h 57 | 58 | template 59 | class GenericStringBuffer; 60 | 61 | typedef GenericStringBuffer, CrtAllocator> StringBuffer; 62 | 63 | // filereadstream.h 64 | 65 | class FileReadStream; 66 | 67 | // filewritestream.h 68 | 69 | class FileWriteStream; 70 | 71 | // memorybuffer.h 72 | 73 | template 74 | struct GenericMemoryBuffer; 75 | 76 | typedef GenericMemoryBuffer MemoryBuffer; 77 | 78 | // memorystream.h 79 | 80 | struct MemoryStream; 81 | 82 | // reader.h 83 | 84 | template 85 | struct BaseReaderHandler; 86 | 87 | template 88 | class GenericReader; 89 | 90 | typedef GenericReader, UTF8, CrtAllocator> Reader; 91 | 92 | // writer.h 93 | 94 | template 95 | class Writer; 96 | 97 | // prettywriter.h 98 | 99 | template 100 | class PrettyWriter; 101 | 102 | // document.h 103 | 104 | template 105 | struct GenericMember; 106 | 107 | template 108 | class GenericMemberIterator; 109 | 110 | template 111 | struct GenericStringRef; 112 | 113 | template 114 | class GenericValue; 115 | 116 | typedef GenericValue, MemoryPoolAllocator > Value; 117 | 118 | template 119 | class GenericDocument; 120 | 121 | typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; 122 | 123 | // pointer.h 124 | 125 | template 126 | class GenericPointer; 127 | 128 | typedef GenericPointer Pointer; 129 | 130 | // schema.h 131 | 132 | template 133 | class IGenericRemoteSchemaDocumentProvider; 134 | 135 | template 136 | class GenericSchemaDocument; 137 | 138 | typedef GenericSchemaDocument SchemaDocument; 139 | typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; 140 | 141 | template < 142 | typename SchemaDocumentType, 143 | typename OutputHandler, 144 | typename StateAllocator> 145 | class GenericSchemaValidator; 146 | 147 | typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #endif // RAPIDJSON_RAPIDJSONFWD_H_ 152 | -------------------------------------------------------------------------------- /rapidjson/internal/dtoa.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | // This is a C++ header-only implementation of Grisu2 algorithm from the publication: 16 | // Loitsch, Florian. "Printing floating-point numbers quickly and accurately with 17 | // integers." ACM Sigplan Notices 45.6 (2010): 233-243. 18 | 19 | #ifndef RAPIDJSON_DTOA_ 20 | #define RAPIDJSON_DTOA_ 21 | 22 | #include "itoa.h" // GetDigitsLut() 23 | #include "diyfp.h" 24 | #include "ieee754.h" 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | namespace internal { 28 | 29 | #ifdef __GNUC__ 30 | RAPIDJSON_DIAG_PUSH 31 | RAPIDJSON_DIAG_OFF(effc++) 32 | RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 33 | #endif 34 | 35 | inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { 36 | while (rest < wp_w && delta - rest >= ten_kappa && 37 | (rest + ten_kappa < wp_w || /// closer 38 | wp_w - rest > rest + ten_kappa - wp_w)) { 39 | buffer[len - 1]--; 40 | rest += ten_kappa; 41 | } 42 | } 43 | 44 | inline unsigned CountDecimalDigit32(uint32_t n) { 45 | // Simple pure C++ implementation was faster than __builtin_clz version in this situation. 46 | if (n < 10) return 1; 47 | if (n < 100) return 2; 48 | if (n < 1000) return 3; 49 | if (n < 10000) return 4; 50 | if (n < 100000) return 5; 51 | if (n < 1000000) return 6; 52 | if (n < 10000000) return 7; 53 | if (n < 100000000) return 8; 54 | // Will not reach 10 digits in DigitGen() 55 | //if (n < 1000000000) return 9; 56 | //return 10; 57 | return 9; 58 | } 59 | 60 | inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { 61 | static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; 62 | const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); 63 | const DiyFp wp_w = Mp - W; 64 | uint32_t p1 = static_cast(Mp.f >> -one.e); 65 | uint64_t p2 = Mp.f & (one.f - 1); 66 | unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9] 67 | *len = 0; 68 | 69 | while (kappa > 0) { 70 | uint32_t d = 0; 71 | switch (kappa) { 72 | case 9: d = p1 / 100000000; p1 %= 100000000; break; 73 | case 8: d = p1 / 10000000; p1 %= 10000000; break; 74 | case 7: d = p1 / 1000000; p1 %= 1000000; break; 75 | case 6: d = p1 / 100000; p1 %= 100000; break; 76 | case 5: d = p1 / 10000; p1 %= 10000; break; 77 | case 4: d = p1 / 1000; p1 %= 1000; break; 78 | case 3: d = p1 / 100; p1 %= 100; break; 79 | case 2: d = p1 / 10; p1 %= 10; break; 80 | case 1: d = p1; p1 = 0; break; 81 | default:; 82 | } 83 | if (d || *len) 84 | buffer[(*len)++] = static_cast('0' + static_cast(d)); 85 | kappa--; 86 | uint64_t tmp = (static_cast(p1) << -one.e) + p2; 87 | if (tmp <= delta) { 88 | *K += kappa; 89 | GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); 90 | return; 91 | } 92 | } 93 | 94 | // kappa = 0 95 | for (;;) { 96 | p2 *= 10; 97 | delta *= 10; 98 | char d = static_cast(p2 >> -one.e); 99 | if (d || *len) 100 | buffer[(*len)++] = static_cast('0' + d); 101 | p2 &= one.f - 1; 102 | kappa--; 103 | if (p2 < delta) { 104 | *K += kappa; 105 | int index = -static_cast(kappa); 106 | GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast(kappa)] : 0)); 107 | return; 108 | } 109 | } 110 | } 111 | 112 | inline void Grisu2(double value, char* buffer, int* length, int* K) { 113 | const DiyFp v(value); 114 | DiyFp w_m, w_p; 115 | v.NormalizedBoundaries(&w_m, &w_p); 116 | 117 | const DiyFp c_mk = GetCachedPower(w_p.e, K); 118 | const DiyFp W = v.Normalize() * c_mk; 119 | DiyFp Wp = w_p * c_mk; 120 | DiyFp Wm = w_m * c_mk; 121 | Wm.f++; 122 | Wp.f--; 123 | DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); 124 | } 125 | 126 | inline char* WriteExponent(int K, char* buffer) { 127 | if (K < 0) { 128 | *buffer++ = '-'; 129 | K = -K; 130 | } 131 | 132 | if (K >= 100) { 133 | *buffer++ = static_cast('0' + static_cast(K / 100)); 134 | K %= 100; 135 | const char* d = GetDigitsLut() + K * 2; 136 | *buffer++ = d[0]; 137 | *buffer++ = d[1]; 138 | } 139 | else if (K >= 10) { 140 | const char* d = GetDigitsLut() + K * 2; 141 | *buffer++ = d[0]; 142 | *buffer++ = d[1]; 143 | } 144 | else 145 | *buffer++ = static_cast('0' + static_cast(K)); 146 | 147 | return buffer; 148 | } 149 | 150 | inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { 151 | const int kk = length + k; // 10^(kk-1) <= v < 10^kk 152 | 153 | if (0 <= k && kk <= 21) { 154 | // 1234e7 -> 12340000000 155 | for (int i = length; i < kk; i++) 156 | buffer[i] = '0'; 157 | buffer[kk] = '.'; 158 | buffer[kk + 1] = '0'; 159 | return &buffer[kk + 2]; 160 | } 161 | else if (0 < kk && kk <= 21) { 162 | // 1234e-2 -> 12.34 163 | std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); 164 | buffer[kk] = '.'; 165 | if (0 > k + maxDecimalPlaces) { 166 | // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 167 | // Remove extra trailing zeros (at least one) after truncation. 168 | for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) 169 | if (buffer[i] != '0') 170 | return &buffer[i + 1]; 171 | return &buffer[kk + 2]; // Reserve one zero 172 | } 173 | else 174 | return &buffer[length + 1]; 175 | } 176 | else if (-6 < kk && kk <= 0) { 177 | // 1234e-6 -> 0.001234 178 | const int offset = 2 - kk; 179 | std::memmove(&buffer[offset], &buffer[0], static_cast(length)); 180 | buffer[0] = '0'; 181 | buffer[1] = '.'; 182 | for (int i = 2; i < offset; i++) 183 | buffer[i] = '0'; 184 | if (length - kk > maxDecimalPlaces) { 185 | // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 186 | // Remove extra trailing zeros (at least one) after truncation. 187 | for (int i = maxDecimalPlaces + 1; i > 2; i--) 188 | if (buffer[i] != '0') 189 | return &buffer[i + 1]; 190 | return &buffer[3]; // Reserve one zero 191 | } 192 | else 193 | return &buffer[length + offset]; 194 | } 195 | else if (kk < -maxDecimalPlaces) { 196 | // Truncate to zero 197 | buffer[0] = '0'; 198 | buffer[1] = '.'; 199 | buffer[2] = '0'; 200 | return &buffer[3]; 201 | } 202 | else if (length == 1) { 203 | // 1e30 204 | buffer[1] = 'e'; 205 | return WriteExponent(kk - 1, &buffer[2]); 206 | } 207 | else { 208 | // 1234e30 -> 1.234e33 209 | std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); 210 | buffer[1] = '.'; 211 | buffer[length + 1] = 'e'; 212 | return WriteExponent(kk - 1, &buffer[0 + length + 2]); 213 | } 214 | } 215 | 216 | inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { 217 | RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); 218 | Double d(value); 219 | if (d.IsZero()) { 220 | if (d.Sign()) 221 | *buffer++ = '-'; // -0.0, Issue #289 222 | buffer[0] = '0'; 223 | buffer[1] = '.'; 224 | buffer[2] = '0'; 225 | return &buffer[3]; 226 | } 227 | else { 228 | if (value < 0) { 229 | *buffer++ = '-'; 230 | value = -value; 231 | } 232 | int length, K; 233 | Grisu2(value, buffer, &length, &K); 234 | return Prettify(buffer, length, K, maxDecimalPlaces); 235 | } 236 | } 237 | 238 | #ifdef __GNUC__ 239 | RAPIDJSON_DIAG_POP 240 | #endif 241 | 242 | } // namespace internal 243 | RAPIDJSON_NAMESPACE_END 244 | 245 | #endif // RAPIDJSON_DTOA_ 246 | -------------------------------------------------------------------------------- /rapidjson/internal/ieee754.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_IEEE754_ 16 | #define RAPIDJSON_IEEE754_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | class Double { 24 | public: 25 | Double() {} 26 | Double(double d) : d_(d) {} 27 | Double(uint64_t u) : u_(u) {} 28 | 29 | double Value() const { return d_; } 30 | uint64_t Uint64Value() const { return u_; } 31 | 32 | double NextPositiveDouble() const { 33 | RAPIDJSON_ASSERT(!Sign()); 34 | return Double(u_ + 1).Value(); 35 | } 36 | 37 | bool Sign() const { return (u_ & kSignMask) != 0; } 38 | uint64_t Significand() const { return u_ & kSignificandMask; } 39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } 40 | 41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } 42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } 43 | bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } 44 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } 45 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } 46 | 47 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } 48 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } 49 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } 50 | 51 | static unsigned EffectiveSignificandSize(int order) { 52 | if (order >= -1021) 53 | return 53; 54 | else if (order <= -1074) 55 | return 0; 56 | else 57 | return static_cast(order) + 1074; 58 | } 59 | 60 | private: 61 | static const int kSignificandSize = 52; 62 | static const int kExponentBias = 0x3FF; 63 | static const int kDenormalExponent = 1 - kExponentBias; 64 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); 65 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); 66 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); 67 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); 68 | 69 | union { 70 | double d_; 71 | uint64_t u_; 72 | }; 73 | }; 74 | 75 | } // namespace internal 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_IEEE754_ 79 | -------------------------------------------------------------------------------- /rapidjson/internal/meta.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_META_H_ 16 | #define RAPIDJSON_INTERNAL_META_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #ifdef __GNUC__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | #if defined(_MSC_VER) 25 | RAPIDJSON_DIAG_PUSH 26 | RAPIDJSON_DIAG_OFF(6334) 27 | #endif 28 | 29 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS 30 | #include 31 | #endif 32 | 33 | //@cond RAPIDJSON_INTERNAL 34 | RAPIDJSON_NAMESPACE_BEGIN 35 | namespace internal { 36 | 37 | // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching 38 | template struct Void { typedef void Type; }; 39 | 40 | /////////////////////////////////////////////////////////////////////////////// 41 | // BoolType, TrueType, FalseType 42 | // 43 | template struct BoolType { 44 | static const bool Value = Cond; 45 | typedef BoolType Type; 46 | }; 47 | typedef BoolType TrueType; 48 | typedef BoolType FalseType; 49 | 50 | 51 | /////////////////////////////////////////////////////////////////////////////// 52 | // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr 53 | // 54 | 55 | template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; 56 | template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; 57 | template struct SelectIfCond : SelectIfImpl::template Apply {}; 58 | template struct SelectIf : SelectIfCond {}; 59 | 60 | template struct AndExprCond : FalseType {}; 61 | template <> struct AndExprCond : TrueType {}; 62 | template struct OrExprCond : TrueType {}; 63 | template <> struct OrExprCond : FalseType {}; 64 | 65 | template struct BoolExpr : SelectIf::Type {}; 66 | template struct NotExpr : SelectIf::Type {}; 67 | template struct AndExpr : AndExprCond::Type {}; 68 | template struct OrExpr : OrExprCond::Type {}; 69 | 70 | 71 | /////////////////////////////////////////////////////////////////////////////// 72 | // AddConst, MaybeAddConst, RemoveConst 73 | template struct AddConst { typedef const T Type; }; 74 | template struct MaybeAddConst : SelectIfCond {}; 75 | template struct RemoveConst { typedef T Type; }; 76 | template struct RemoveConst { typedef T Type; }; 77 | 78 | 79 | /////////////////////////////////////////////////////////////////////////////// 80 | // IsSame, IsConst, IsMoreConst, IsPointer 81 | // 82 | template struct IsSame : FalseType {}; 83 | template struct IsSame : TrueType {}; 84 | 85 | template struct IsConst : FalseType {}; 86 | template struct IsConst : TrueType {}; 87 | 88 | template 89 | struct IsMoreConst 90 | : AndExpr::Type, typename RemoveConst::Type>, 91 | BoolType::Value >= IsConst::Value> >::Type {}; 92 | 93 | template struct IsPointer : FalseType {}; 94 | template struct IsPointer : TrueType {}; 95 | 96 | /////////////////////////////////////////////////////////////////////////////// 97 | // IsBaseOf 98 | // 99 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS 100 | 101 | template struct IsBaseOf 102 | : BoolType< ::std::is_base_of::value> {}; 103 | 104 | #else // simplified version adopted from Boost 105 | 106 | template struct IsBaseOfImpl { 107 | RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); 108 | RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); 109 | 110 | typedef char (&Yes)[1]; 111 | typedef char (&No) [2]; 112 | 113 | template 114 | static Yes Check(const D*, T); 115 | static No Check(const B*, int); 116 | 117 | struct Host { 118 | operator const B*() const; 119 | operator const D*(); 120 | }; 121 | 122 | enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; 123 | }; 124 | 125 | template struct IsBaseOf 126 | : OrExpr, BoolExpr > >::Type {}; 127 | 128 | #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS 129 | 130 | 131 | ////////////////////////////////////////////////////////////////////////// 132 | // EnableIf / DisableIf 133 | // 134 | template struct EnableIfCond { typedef T Type; }; 135 | template struct EnableIfCond { /* empty */ }; 136 | 137 | template struct DisableIfCond { typedef T Type; }; 138 | template struct DisableIfCond { /* empty */ }; 139 | 140 | template 141 | struct EnableIf : EnableIfCond {}; 142 | 143 | template 144 | struct DisableIf : DisableIfCond {}; 145 | 146 | // SFINAE helpers 147 | struct SfinaeTag {}; 148 | template struct RemoveSfinaeTag; 149 | template struct RemoveSfinaeTag { typedef T Type; }; 150 | 151 | #define RAPIDJSON_REMOVEFPTR_(type) \ 152 | typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ 153 | < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type 154 | 155 | #define RAPIDJSON_ENABLEIF(cond) \ 156 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ 157 | ::Type * = NULL 158 | 159 | #define RAPIDJSON_DISABLEIF(cond) \ 160 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ 161 | ::Type * = NULL 162 | 163 | #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ 164 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ 165 | ::Type 167 | 168 | #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ 169 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ 170 | ::Type 172 | 173 | } // namespace internal 174 | RAPIDJSON_NAMESPACE_END 175 | //@endcond 176 | 177 | #if defined(__GNUC__) || defined(_MSC_VER) 178 | RAPIDJSON_DIAG_POP 179 | #endif 180 | 181 | #endif // RAPIDJSON_INTERNAL_META_H_ 182 | -------------------------------------------------------------------------------- /rapidjson/internal/pow10.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_POW10_ 16 | #define RAPIDJSON_POW10_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Computes integer powers of 10 in double (10.0^n). 24 | /*! This function uses lookup table for fast and accurate results. 25 | \param n non-negative exponent. Must <= 308. 26 | \return 10.0^n 27 | */ 28 | inline double Pow10(int n) { 29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes 30 | 1e+0, 31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 47 | }; 48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308); 49 | return e[n]; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_POW10_ 56 | -------------------------------------------------------------------------------- /rapidjson/internal/stack.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STACK_H_ 16 | #define RAPIDJSON_INTERNAL_STACK_H_ 17 | 18 | #include "../allocators.h" 19 | #include "swap.h" 20 | 21 | #if defined(__clang__) 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(c++98-compat) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | namespace internal { 28 | 29 | /////////////////////////////////////////////////////////////////////////////// 30 | // Stack 31 | 32 | //! A type-unsafe stack for storing different types of data. 33 | /*! \tparam Allocator Allocator for allocating stack memory. 34 | */ 35 | template 36 | class Stack { 37 | public: 38 | // Optimization note: Do not allocate memory for stack_ in constructor. 39 | // Do it lazily when first Push() -> Expand() -> Resize(). 40 | Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { 41 | } 42 | 43 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 44 | Stack(Stack&& rhs) 45 | : allocator_(rhs.allocator_), 46 | ownAllocator_(rhs.ownAllocator_), 47 | stack_(rhs.stack_), 48 | stackTop_(rhs.stackTop_), 49 | stackEnd_(rhs.stackEnd_), 50 | initialCapacity_(rhs.initialCapacity_) 51 | { 52 | rhs.allocator_ = 0; 53 | rhs.ownAllocator_ = 0; 54 | rhs.stack_ = 0; 55 | rhs.stackTop_ = 0; 56 | rhs.stackEnd_ = 0; 57 | rhs.initialCapacity_ = 0; 58 | } 59 | #endif 60 | 61 | ~Stack() { 62 | Destroy(); 63 | } 64 | 65 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 66 | Stack& operator=(Stack&& rhs) { 67 | if (&rhs != this) 68 | { 69 | Destroy(); 70 | 71 | allocator_ = rhs.allocator_; 72 | ownAllocator_ = rhs.ownAllocator_; 73 | stack_ = rhs.stack_; 74 | stackTop_ = rhs.stackTop_; 75 | stackEnd_ = rhs.stackEnd_; 76 | initialCapacity_ = rhs.initialCapacity_; 77 | 78 | rhs.allocator_ = 0; 79 | rhs.ownAllocator_ = 0; 80 | rhs.stack_ = 0; 81 | rhs.stackTop_ = 0; 82 | rhs.stackEnd_ = 0; 83 | rhs.initialCapacity_ = 0; 84 | } 85 | return *this; 86 | } 87 | #endif 88 | 89 | void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { 90 | internal::Swap(allocator_, rhs.allocator_); 91 | internal::Swap(ownAllocator_, rhs.ownAllocator_); 92 | internal::Swap(stack_, rhs.stack_); 93 | internal::Swap(stackTop_, rhs.stackTop_); 94 | internal::Swap(stackEnd_, rhs.stackEnd_); 95 | internal::Swap(initialCapacity_, rhs.initialCapacity_); 96 | } 97 | 98 | void Clear() { stackTop_ = stack_; } 99 | 100 | void ShrinkToFit() { 101 | if (Empty()) { 102 | // If the stack is empty, completely deallocate the memory. 103 | Allocator::Free(stack_); 104 | stack_ = 0; 105 | stackTop_ = 0; 106 | stackEnd_ = 0; 107 | } 108 | else 109 | Resize(GetSize()); 110 | } 111 | 112 | // Optimization note: try to minimize the size of this function for force inline. 113 | // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. 114 | template 115 | RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { 116 | // Expand the stack if needed 117 | if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_)) 118 | Expand(count); 119 | } 120 | 121 | template 122 | RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { 123 | Reserve(count); 124 | return PushUnsafe(count); 125 | } 126 | 127 | template 128 | RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { 129 | RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_); 130 | T* ret = reinterpret_cast(stackTop_); 131 | stackTop_ += sizeof(T) * count; 132 | return ret; 133 | } 134 | 135 | template 136 | T* Pop(size_t count) { 137 | RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); 138 | stackTop_ -= count * sizeof(T); 139 | return reinterpret_cast(stackTop_); 140 | } 141 | 142 | template 143 | T* Top() { 144 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); 145 | return reinterpret_cast(stackTop_ - sizeof(T)); 146 | } 147 | 148 | template 149 | const T* Top() const { 150 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); 151 | return reinterpret_cast(stackTop_ - sizeof(T)); 152 | } 153 | 154 | template 155 | T* End() { return reinterpret_cast(stackTop_); } 156 | 157 | template 158 | const T* End() const { return reinterpret_cast(stackTop_); } 159 | 160 | template 161 | T* Bottom() { return reinterpret_cast(stack_); } 162 | 163 | template 164 | const T* Bottom() const { return reinterpret_cast(stack_); } 165 | 166 | bool HasAllocator() const { 167 | return allocator_ != 0; 168 | } 169 | 170 | Allocator& GetAllocator() { 171 | RAPIDJSON_ASSERT(allocator_); 172 | return *allocator_; 173 | } 174 | 175 | bool Empty() const { return stackTop_ == stack_; } 176 | size_t GetSize() const { return static_cast(stackTop_ - stack_); } 177 | size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } 178 | 179 | private: 180 | template 181 | void Expand(size_t count) { 182 | // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. 183 | size_t newCapacity; 184 | if (stack_ == 0) { 185 | if (!allocator_) 186 | ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); 187 | newCapacity = initialCapacity_; 188 | } else { 189 | newCapacity = GetCapacity(); 190 | newCapacity += (newCapacity + 1) / 2; 191 | } 192 | size_t newSize = GetSize() + sizeof(T) * count; 193 | if (newCapacity < newSize) 194 | newCapacity = newSize; 195 | 196 | Resize(newCapacity); 197 | } 198 | 199 | void Resize(size_t newCapacity) { 200 | const size_t size = GetSize(); // Backup the current size 201 | stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); 202 | stackTop_ = stack_ + size; 203 | stackEnd_ = stack_ + newCapacity; 204 | } 205 | 206 | void Destroy() { 207 | Allocator::Free(stack_); 208 | RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack 209 | } 210 | 211 | // Prohibit copy constructor & assignment operator. 212 | Stack(const Stack&); 213 | Stack& operator=(const Stack&); 214 | 215 | Allocator* allocator_; 216 | Allocator* ownAllocator_; 217 | char *stack_; 218 | char *stackTop_; 219 | char *stackEnd_; 220 | size_t initialCapacity_; 221 | }; 222 | 223 | } // namespace internal 224 | RAPIDJSON_NAMESPACE_END 225 | 226 | #if defined(__clang__) 227 | RAPIDJSON_DIAG_POP 228 | #endif 229 | 230 | #endif // RAPIDJSON_STACK_H_ 231 | -------------------------------------------------------------------------------- /rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "../stream.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Custom strlen() which works on different character types. 24 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 25 | \param s Null-terminated input string. 26 | \return Number of characters in the string. 27 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 28 | */ 29 | template 30 | inline SizeType StrLen(const Ch* s) { 31 | RAPIDJSON_ASSERT(s != 0); 32 | const Ch* p = s; 33 | while (*p) ++p; 34 | return SizeType(p - s); 35 | } 36 | 37 | //! Returns number of code points in a encoded string. 38 | template 39 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 40 | RAPIDJSON_ASSERT(s != 0); 41 | RAPIDJSON_ASSERT(outCount != 0); 42 | GenericStringStream is(s); 43 | const typename Encoding::Ch* end = s + length; 44 | SizeType count = 0; 45 | while (is.src_ < end) { 46 | unsigned codepoint; 47 | if (!Encoding::Decode(is, &codepoint)) 48 | return false; 49 | count++; 50 | } 51 | *outCount = count; 52 | return true; 53 | } 54 | 55 | } // namespace internal 56 | RAPIDJSON_NAMESPACE_END 57 | 58 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 59 | -------------------------------------------------------------------------------- /rapidjson/internal/strtod.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_STRTOD_ 16 | #define RAPIDJSON_STRTOD_ 17 | 18 | #include "ieee754.h" 19 | #include "biginteger.h" 20 | #include "diyfp.h" 21 | #include "pow10.h" 22 | 23 | RAPIDJSON_NAMESPACE_BEGIN 24 | namespace internal { 25 | 26 | inline double FastPath(double significand, int exp) { 27 | if (exp < -308) 28 | return 0.0; 29 | else if (exp >= 0) 30 | return significand * internal::Pow10(exp); 31 | else 32 | return significand / internal::Pow10(-exp); 33 | } 34 | 35 | inline double StrtodNormalPrecision(double d, int p) { 36 | if (p < -308) { 37 | // Prevent expSum < -308, making Pow10(p) = 0 38 | d = FastPath(d, -308); 39 | d = FastPath(d, p + 308); 40 | } 41 | else 42 | d = FastPath(d, p); 43 | return d; 44 | } 45 | 46 | template 47 | inline T Min3(T a, T b, T c) { 48 | T m = a; 49 | if (m > b) m = b; 50 | if (m > c) m = c; 51 | return m; 52 | } 53 | 54 | inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { 55 | const Double db(b); 56 | const uint64_t bInt = db.IntegerSignificand(); 57 | const int bExp = db.IntegerExponent(); 58 | const int hExp = bExp - 1; 59 | 60 | int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; 61 | 62 | // Adjust for decimal exponent 63 | if (dExp >= 0) { 64 | dS_Exp2 += dExp; 65 | dS_Exp5 += dExp; 66 | } 67 | else { 68 | bS_Exp2 -= dExp; 69 | bS_Exp5 -= dExp; 70 | hS_Exp2 -= dExp; 71 | hS_Exp5 -= dExp; 72 | } 73 | 74 | // Adjust for binary exponent 75 | if (bExp >= 0) 76 | bS_Exp2 += bExp; 77 | else { 78 | dS_Exp2 -= bExp; 79 | hS_Exp2 -= bExp; 80 | } 81 | 82 | // Adjust for half ulp exponent 83 | if (hExp >= 0) 84 | hS_Exp2 += hExp; 85 | else { 86 | dS_Exp2 -= hExp; 87 | bS_Exp2 -= hExp; 88 | } 89 | 90 | // Remove common power of two factor from all three scaled values 91 | int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); 92 | dS_Exp2 -= common_Exp2; 93 | bS_Exp2 -= common_Exp2; 94 | hS_Exp2 -= common_Exp2; 95 | 96 | BigInteger dS = d; 97 | dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); 98 | 99 | BigInteger bS(bInt); 100 | bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); 101 | 102 | BigInteger hS(1); 103 | hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); 104 | 105 | BigInteger delta(0); 106 | dS.Difference(bS, &delta); 107 | 108 | return delta.Compare(hS); 109 | } 110 | 111 | inline bool StrtodFast(double d, int p, double* result) { 112 | // Use fast path for string-to-double conversion if possible 113 | // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ 114 | if (p > 22 && p < 22 + 16) { 115 | // Fast Path Cases In Disguise 116 | d *= internal::Pow10(p - 22); 117 | p = 22; 118 | } 119 | 120 | if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 121 | *result = FastPath(d, p); 122 | return true; 123 | } 124 | else 125 | return false; 126 | } 127 | 128 | // Compute an approximation and see if it is within 1/2 ULP 129 | inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { 130 | uint64_t significand = 0; 131 | size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 132 | for (; i < length; i++) { 133 | if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || 134 | (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) 135 | break; 136 | significand = significand * 10u + static_cast(decimals[i] - '0'); 137 | } 138 | 139 | if (i < length && decimals[i] >= '5') // Rounding 140 | significand++; 141 | 142 | size_t remaining = length - i; 143 | const unsigned kUlpShift = 3; 144 | const unsigned kUlp = 1 << kUlpShift; 145 | int64_t error = (remaining == 0) ? 0 : kUlp / 2; 146 | 147 | DiyFp v(significand, 0); 148 | v = v.Normalize(); 149 | error <<= -v.e; 150 | 151 | const int dExp = static_cast(decimalPosition) - static_cast(i) + exp; 152 | 153 | int actualExp; 154 | DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); 155 | if (actualExp != dExp) { 156 | static const DiyFp kPow10[] = { 157 | DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 158 | DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 159 | DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 160 | DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 161 | DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 162 | DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 163 | DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 164 | }; 165 | int adjustment = dExp - actualExp - 1; 166 | RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); 167 | v = v * kPow10[adjustment]; 168 | if (length + static_cast(adjustment)> 19u) // has more digits than decimal digits in 64-bit 169 | error += kUlp / 2; 170 | } 171 | 172 | v = v * cachedPower; 173 | 174 | error += kUlp + (error == 0 ? 0 : 1); 175 | 176 | const int oldExp = v.e; 177 | v = v.Normalize(); 178 | error <<= oldExp - v.e; 179 | 180 | const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); 181 | unsigned precisionSize = 64 - effectiveSignificandSize; 182 | if (precisionSize + kUlpShift >= 64) { 183 | unsigned scaleExp = (precisionSize + kUlpShift) - 63; 184 | v.f >>= scaleExp; 185 | v.e += scaleExp; 186 | error = (error >> scaleExp) + 1 + static_cast(kUlp); 187 | precisionSize -= scaleExp; 188 | } 189 | 190 | DiyFp rounded(v.f >> precisionSize, v.e + static_cast(precisionSize)); 191 | const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; 192 | const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; 193 | if (precisionBits >= halfWay + static_cast(error)) { 194 | rounded.f++; 195 | if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) 196 | rounded.f >>= 1; 197 | rounded.e++; 198 | } 199 | } 200 | 201 | *result = rounded.ToDouble(); 202 | 203 | return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); 204 | } 205 | 206 | inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { 207 | const BigInteger dInt(decimals, length); 208 | const int dExp = static_cast(decimalPosition) - static_cast(length) + exp; 209 | Double a(approx); 210 | int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); 211 | if (cmp < 0) 212 | return a.Value(); // within half ULP 213 | else if (cmp == 0) { 214 | // Round towards even 215 | if (a.Significand() & 1) 216 | return a.NextPositiveDouble(); 217 | else 218 | return a.Value(); 219 | } 220 | else // adjustment 221 | return a.NextPositiveDouble(); 222 | } 223 | 224 | inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { 225 | RAPIDJSON_ASSERT(d >= 0.0); 226 | RAPIDJSON_ASSERT(length >= 1); 227 | 228 | double result; 229 | if (StrtodFast(d, p, &result)) 230 | return result; 231 | 232 | // Trim leading zeros 233 | while (*decimals == '0' && length > 1) { 234 | length--; 235 | decimals++; 236 | decimalPosition--; 237 | } 238 | 239 | // Trim trailing zeros 240 | while (decimals[length - 1] == '0' && length > 1) { 241 | length--; 242 | decimalPosition--; 243 | exp++; 244 | } 245 | 246 | // Trim right-most digits 247 | const int kMaxDecimalDigit = 780; 248 | if (static_cast(length) > kMaxDecimalDigit) { 249 | int delta = (static_cast(length) - kMaxDecimalDigit); 250 | exp += delta; 251 | decimalPosition -= static_cast(delta); 252 | length = kMaxDecimalDigit; 253 | } 254 | 255 | // If too small, underflow to zero 256 | if (int(length) + exp < -324) 257 | return 0.0; 258 | 259 | if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) 260 | return result; 261 | 262 | // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison 263 | return StrtodBigInteger(result, decimals, length, decimalPosition, exp); 264 | } 265 | 266 | } // namespace internal 267 | RAPIDJSON_NAMESPACE_END 268 | 269 | #endif // RAPIDJSON_STRTOD_ 270 | -------------------------------------------------------------------------------- /rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /rapidjson/istreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ISTREAMWRAPPER_H_ 16 | #define RAPIDJSON_ISTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | #ifdef _MSC_VER 27 | RAPIDJSON_DIAG_PUSH 28 | RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | //! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. 34 | /*! 35 | The classes can be wrapped including but not limited to: 36 | 37 | - \c std::istringstream 38 | - \c std::stringstream 39 | - \c std::wistringstream 40 | - \c std::wstringstream 41 | - \c std::ifstream 42 | - \c std::fstream 43 | - \c std::wifstream 44 | - \c std::wfstream 45 | 46 | \tparam StreamType Class derived from \c std::basic_istream. 47 | */ 48 | 49 | template 50 | class BasicIStreamWrapper { 51 | public: 52 | typedef typename StreamType::char_type Ch; 53 | BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} 54 | 55 | Ch Peek() const { 56 | typename StreamType::int_type c = stream_.peek(); 57 | return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : '\0'; 58 | } 59 | 60 | Ch Take() { 61 | typename StreamType::int_type c = stream_.get(); 62 | if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { 63 | count_++; 64 | return static_cast(c); 65 | } 66 | else 67 | return '\0'; 68 | } 69 | 70 | // tellg() may return -1 when failed. So we count by ourself. 71 | size_t Tell() const { return count_; } 72 | 73 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 74 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 75 | void Flush() { RAPIDJSON_ASSERT(false); } 76 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 77 | 78 | // For encoding detection only. 79 | const Ch* Peek4() const { 80 | RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. 81 | int i; 82 | bool hasError = false; 83 | for (i = 0; i < 4; ++i) { 84 | typename StreamType::int_type c = stream_.get(); 85 | if (c == StreamType::traits_type::eof()) { 86 | hasError = true; 87 | stream_.clear(); 88 | break; 89 | } 90 | peekBuffer_[i] = static_cast(c); 91 | } 92 | for (--i; i >= 0; --i) 93 | stream_.putback(peekBuffer_[i]); 94 | return !hasError ? peekBuffer_ : 0; 95 | } 96 | 97 | private: 98 | BasicIStreamWrapper(const BasicIStreamWrapper&); 99 | BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); 100 | 101 | StreamType& stream_; 102 | size_t count_; //!< Number of characters read. Note: 103 | mutable Ch peekBuffer_[4]; 104 | }; 105 | 106 | typedef BasicIStreamWrapper IStreamWrapper; 107 | typedef BasicIStreamWrapper WIStreamWrapper; 108 | 109 | #if defined(__clang__) || defined(_MSC_VER) 110 | RAPIDJSON_DIAG_POP 111 | #endif 112 | 113 | RAPIDJSON_NAMESPACE_END 114 | 115 | #endif // RAPIDJSON_ISTREAMWRAPPER_H_ 116 | -------------------------------------------------------------------------------- /rapidjson/memorybuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_ 16 | #define RAPIDJSON_MEMORYBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | 23 | //! Represents an in-memory output byte stream. 24 | /*! 25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. 26 | 27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. 28 | 29 | Differences between MemoryBuffer and StringBuffer: 30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. 31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. 32 | 33 | \tparam Allocator type for allocating memory buffer. 34 | \note implements Stream concept 35 | */ 36 | template 37 | struct GenericMemoryBuffer { 38 | typedef char Ch; // byte 39 | 40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 41 | 42 | void Put(Ch c) { *stack_.template Push() = c; } 43 | void Flush() {} 44 | 45 | void Clear() { stack_.Clear(); } 46 | void ShrinkToFit() { stack_.ShrinkToFit(); } 47 | Ch* Push(size_t count) { return stack_.template Push(count); } 48 | void Pop(size_t count) { stack_.template Pop(count); } 49 | 50 | const Ch* GetBuffer() const { 51 | return stack_.template Bottom(); 52 | } 53 | 54 | size_t GetSize() const { return stack_.GetSize(); } 55 | 56 | static const size_t kDefaultCapacity = 256; 57 | mutable internal::Stack stack_; 58 | }; 59 | 60 | typedef GenericMemoryBuffer<> MemoryBuffer; 61 | 62 | //! Implement specialized version of PutN() with memset() for better performance. 63 | template<> 64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { 65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 71 | -------------------------------------------------------------------------------- /rapidjson/memorystream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_ 16 | #define RAPIDJSON_MEMORYSTREAM_H_ 17 | 18 | #include "stream.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(unreachable-code) 23 | RAPIDJSON_DIAG_OFF(missing-noreturn) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Represents an in-memory input byte stream. 29 | /*! 30 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. 31 | 32 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. 33 | 34 | Differences between MemoryStream and StringStream: 35 | 1. StringStream has encoding but MemoryStream is a byte stream. 36 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. 37 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). 38 | \note implements Stream concept 39 | */ 40 | struct MemoryStream { 41 | typedef char Ch; // byte 42 | 43 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} 44 | 45 | Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } 46 | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } 47 | size_t Tell() const { return static_cast(src_ - begin_); } 48 | 49 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 50 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 51 | void Flush() { RAPIDJSON_ASSERT(false); } 52 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 53 | 54 | // For encoding detection only. 55 | const Ch* Peek4() const { 56 | return Tell() + 4 <= size_ ? src_ : 0; 57 | } 58 | 59 | const Ch* src_; //!< Current read position. 60 | const Ch* begin_; //!< Original head of the string. 61 | const Ch* end_; //!< End of stream. 62 | size_t size_; //!< Size of the stream. 63 | }; 64 | 65 | RAPIDJSON_NAMESPACE_END 66 | 67 | #ifdef __clang__ 68 | RAPIDJSON_DIAG_POP 69 | #endif 70 | 71 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 72 | -------------------------------------------------------------------------------- /rapidjson/msinttypes/inttypes.h: -------------------------------------------------------------------------------- 1 | // ISO C9x compliant inttypes.h for Microsoft Visual Studio 2 | // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 3 | // 4 | // Copyright (c) 2006-2013 Alexander Chemeris 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | // 9 | // 1. Redistributions of source code must retain the above copyright notice, 10 | // this list of conditions and the following disclaimer. 11 | // 12 | // 2. Redistributions in binary form must reproduce the above copyright 13 | // notice, this list of conditions and the following disclaimer in the 14 | // documentation and/or other materials provided with the distribution. 15 | // 16 | // 3. Neither the name of the product nor the names of its contributors may 17 | // be used to endorse or promote products derived from this software 18 | // without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 23 | // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 | // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | // 31 | /////////////////////////////////////////////////////////////////////////////// 32 | 33 | // The above software in this distribution may have been modified by 34 | // THL A29 Limited ("Tencent Modifications"). 35 | // All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. 36 | 37 | #ifndef _MSC_VER // [ 38 | #error "Use this header only with Microsoft Visual C++ compilers!" 39 | #endif // _MSC_VER ] 40 | 41 | #ifndef _MSC_INTTYPES_H_ // [ 42 | #define _MSC_INTTYPES_H_ 43 | 44 | #if _MSC_VER > 1000 45 | #pragma once 46 | #endif 47 | 48 | #include "stdint.h" 49 | 50 | // miloyip: VC supports inttypes.h since VC2013 51 | #if _MSC_VER >= 1800 52 | #include 53 | #else 54 | 55 | // 7.8 Format conversion of integer types 56 | 57 | typedef struct { 58 | intmax_t quot; 59 | intmax_t rem; 60 | } imaxdiv_t; 61 | 62 | // 7.8.1 Macros for format specifiers 63 | 64 | #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 65 | 66 | // The fprintf macros for signed integers are: 67 | #define PRId8 "d" 68 | #define PRIi8 "i" 69 | #define PRIdLEAST8 "d" 70 | #define PRIiLEAST8 "i" 71 | #define PRIdFAST8 "d" 72 | #define PRIiFAST8 "i" 73 | 74 | #define PRId16 "hd" 75 | #define PRIi16 "hi" 76 | #define PRIdLEAST16 "hd" 77 | #define PRIiLEAST16 "hi" 78 | #define PRIdFAST16 "hd" 79 | #define PRIiFAST16 "hi" 80 | 81 | #define PRId32 "I32d" 82 | #define PRIi32 "I32i" 83 | #define PRIdLEAST32 "I32d" 84 | #define PRIiLEAST32 "I32i" 85 | #define PRIdFAST32 "I32d" 86 | #define PRIiFAST32 "I32i" 87 | 88 | #define PRId64 "I64d" 89 | #define PRIi64 "I64i" 90 | #define PRIdLEAST64 "I64d" 91 | #define PRIiLEAST64 "I64i" 92 | #define PRIdFAST64 "I64d" 93 | #define PRIiFAST64 "I64i" 94 | 95 | #define PRIdMAX "I64d" 96 | #define PRIiMAX "I64i" 97 | 98 | #define PRIdPTR "Id" 99 | #define PRIiPTR "Ii" 100 | 101 | // The fprintf macros for unsigned integers are: 102 | #define PRIo8 "o" 103 | #define PRIu8 "u" 104 | #define PRIx8 "x" 105 | #define PRIX8 "X" 106 | #define PRIoLEAST8 "o" 107 | #define PRIuLEAST8 "u" 108 | #define PRIxLEAST8 "x" 109 | #define PRIXLEAST8 "X" 110 | #define PRIoFAST8 "o" 111 | #define PRIuFAST8 "u" 112 | #define PRIxFAST8 "x" 113 | #define PRIXFAST8 "X" 114 | 115 | #define PRIo16 "ho" 116 | #define PRIu16 "hu" 117 | #define PRIx16 "hx" 118 | #define PRIX16 "hX" 119 | #define PRIoLEAST16 "ho" 120 | #define PRIuLEAST16 "hu" 121 | #define PRIxLEAST16 "hx" 122 | #define PRIXLEAST16 "hX" 123 | #define PRIoFAST16 "ho" 124 | #define PRIuFAST16 "hu" 125 | #define PRIxFAST16 "hx" 126 | #define PRIXFAST16 "hX" 127 | 128 | #define PRIo32 "I32o" 129 | #define PRIu32 "I32u" 130 | #define PRIx32 "I32x" 131 | #define PRIX32 "I32X" 132 | #define PRIoLEAST32 "I32o" 133 | #define PRIuLEAST32 "I32u" 134 | #define PRIxLEAST32 "I32x" 135 | #define PRIXLEAST32 "I32X" 136 | #define PRIoFAST32 "I32o" 137 | #define PRIuFAST32 "I32u" 138 | #define PRIxFAST32 "I32x" 139 | #define PRIXFAST32 "I32X" 140 | 141 | #define PRIo64 "I64o" 142 | #define PRIu64 "I64u" 143 | #define PRIx64 "I64x" 144 | #define PRIX64 "I64X" 145 | #define PRIoLEAST64 "I64o" 146 | #define PRIuLEAST64 "I64u" 147 | #define PRIxLEAST64 "I64x" 148 | #define PRIXLEAST64 "I64X" 149 | #define PRIoFAST64 "I64o" 150 | #define PRIuFAST64 "I64u" 151 | #define PRIxFAST64 "I64x" 152 | #define PRIXFAST64 "I64X" 153 | 154 | #define PRIoMAX "I64o" 155 | #define PRIuMAX "I64u" 156 | #define PRIxMAX "I64x" 157 | #define PRIXMAX "I64X" 158 | 159 | #define PRIoPTR "Io" 160 | #define PRIuPTR "Iu" 161 | #define PRIxPTR "Ix" 162 | #define PRIXPTR "IX" 163 | 164 | // The fscanf macros for signed integers are: 165 | #define SCNd8 "d" 166 | #define SCNi8 "i" 167 | #define SCNdLEAST8 "d" 168 | #define SCNiLEAST8 "i" 169 | #define SCNdFAST8 "d" 170 | #define SCNiFAST8 "i" 171 | 172 | #define SCNd16 "hd" 173 | #define SCNi16 "hi" 174 | #define SCNdLEAST16 "hd" 175 | #define SCNiLEAST16 "hi" 176 | #define SCNdFAST16 "hd" 177 | #define SCNiFAST16 "hi" 178 | 179 | #define SCNd32 "ld" 180 | #define SCNi32 "li" 181 | #define SCNdLEAST32 "ld" 182 | #define SCNiLEAST32 "li" 183 | #define SCNdFAST32 "ld" 184 | #define SCNiFAST32 "li" 185 | 186 | #define SCNd64 "I64d" 187 | #define SCNi64 "I64i" 188 | #define SCNdLEAST64 "I64d" 189 | #define SCNiLEAST64 "I64i" 190 | #define SCNdFAST64 "I64d" 191 | #define SCNiFAST64 "I64i" 192 | 193 | #define SCNdMAX "I64d" 194 | #define SCNiMAX "I64i" 195 | 196 | #ifdef _WIN64 // [ 197 | # define SCNdPTR "I64d" 198 | # define SCNiPTR "I64i" 199 | #else // _WIN64 ][ 200 | # define SCNdPTR "ld" 201 | # define SCNiPTR "li" 202 | #endif // _WIN64 ] 203 | 204 | // The fscanf macros for unsigned integers are: 205 | #define SCNo8 "o" 206 | #define SCNu8 "u" 207 | #define SCNx8 "x" 208 | #define SCNX8 "X" 209 | #define SCNoLEAST8 "o" 210 | #define SCNuLEAST8 "u" 211 | #define SCNxLEAST8 "x" 212 | #define SCNXLEAST8 "X" 213 | #define SCNoFAST8 "o" 214 | #define SCNuFAST8 "u" 215 | #define SCNxFAST8 "x" 216 | #define SCNXFAST8 "X" 217 | 218 | #define SCNo16 "ho" 219 | #define SCNu16 "hu" 220 | #define SCNx16 "hx" 221 | #define SCNX16 "hX" 222 | #define SCNoLEAST16 "ho" 223 | #define SCNuLEAST16 "hu" 224 | #define SCNxLEAST16 "hx" 225 | #define SCNXLEAST16 "hX" 226 | #define SCNoFAST16 "ho" 227 | #define SCNuFAST16 "hu" 228 | #define SCNxFAST16 "hx" 229 | #define SCNXFAST16 "hX" 230 | 231 | #define SCNo32 "lo" 232 | #define SCNu32 "lu" 233 | #define SCNx32 "lx" 234 | #define SCNX32 "lX" 235 | #define SCNoLEAST32 "lo" 236 | #define SCNuLEAST32 "lu" 237 | #define SCNxLEAST32 "lx" 238 | #define SCNXLEAST32 "lX" 239 | #define SCNoFAST32 "lo" 240 | #define SCNuFAST32 "lu" 241 | #define SCNxFAST32 "lx" 242 | #define SCNXFAST32 "lX" 243 | 244 | #define SCNo64 "I64o" 245 | #define SCNu64 "I64u" 246 | #define SCNx64 "I64x" 247 | #define SCNX64 "I64X" 248 | #define SCNoLEAST64 "I64o" 249 | #define SCNuLEAST64 "I64u" 250 | #define SCNxLEAST64 "I64x" 251 | #define SCNXLEAST64 "I64X" 252 | #define SCNoFAST64 "I64o" 253 | #define SCNuFAST64 "I64u" 254 | #define SCNxFAST64 "I64x" 255 | #define SCNXFAST64 "I64X" 256 | 257 | #define SCNoMAX "I64o" 258 | #define SCNuMAX "I64u" 259 | #define SCNxMAX "I64x" 260 | #define SCNXMAX "I64X" 261 | 262 | #ifdef _WIN64 // [ 263 | # define SCNoPTR "I64o" 264 | # define SCNuPTR "I64u" 265 | # define SCNxPTR "I64x" 266 | # define SCNXPTR "I64X" 267 | #else // _WIN64 ][ 268 | # define SCNoPTR "lo" 269 | # define SCNuPTR "lu" 270 | # define SCNxPTR "lx" 271 | # define SCNXPTR "lX" 272 | #endif // _WIN64 ] 273 | 274 | #endif // __STDC_FORMAT_MACROS ] 275 | 276 | // 7.8.2 Functions for greatest-width integer types 277 | 278 | // 7.8.2.1 The imaxabs function 279 | #define imaxabs _abs64 280 | 281 | // 7.8.2.2 The imaxdiv function 282 | 283 | // This is modified version of div() function from Microsoft's div.c found 284 | // in %MSVC.NET%\crt\src\div.c 285 | #ifdef STATIC_IMAXDIV // [ 286 | static 287 | #else // STATIC_IMAXDIV ][ 288 | _inline 289 | #endif // STATIC_IMAXDIV ] 290 | imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) 291 | { 292 | imaxdiv_t result; 293 | 294 | result.quot = numer / denom; 295 | result.rem = numer % denom; 296 | 297 | if (numer < 0 && result.rem > 0) { 298 | // did division wrong; must fix up 299 | ++result.quot; 300 | result.rem -= denom; 301 | } 302 | 303 | return result; 304 | } 305 | 306 | // 7.8.2.3 The strtoimax and strtoumax functions 307 | #define strtoimax _strtoi64 308 | #define strtoumax _strtoui64 309 | 310 | // 7.8.2.4 The wcstoimax and wcstoumax functions 311 | #define wcstoimax _wcstoi64 312 | #define wcstoumax _wcstoui64 313 | 314 | #endif // _MSC_VER >= 1800 315 | 316 | #endif // _MSC_INTTYPES_H_ ] 317 | -------------------------------------------------------------------------------- /rapidjson/ostreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_OSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_OSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. 29 | /*! 30 | The classes can be wrapped including but not limited to: 31 | 32 | - \c std::ostringstream 33 | - \c std::stringstream 34 | - \c std::wpstringstream 35 | - \c std::wstringstream 36 | - \c std::ifstream 37 | - \c std::fstream 38 | - \c std::wofstream 39 | - \c std::wfstream 40 | 41 | \tparam StreamType Class derived from \c std::basic_ostream. 42 | */ 43 | 44 | template 45 | class BasicOStreamWrapper { 46 | public: 47 | typedef typename StreamType::char_type Ch; 48 | BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} 49 | 50 | void Put(Ch c) { 51 | stream_.put(c); 52 | } 53 | 54 | void Flush() { 55 | stream_.flush(); 56 | } 57 | 58 | // Not implemented 59 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 60 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 61 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 62 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 63 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 64 | 65 | private: 66 | BasicOStreamWrapper(const BasicOStreamWrapper&); 67 | BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); 68 | 69 | StreamType& stream_; 70 | }; 71 | 72 | typedef BasicOStreamWrapper OStreamWrapper; 73 | typedef BasicOStreamWrapper WOStreamWrapper; 74 | 75 | #ifdef __clang__ 76 | RAPIDJSON_DIAG_POP 77 | #endif 78 | 79 | RAPIDJSON_NAMESPACE_END 80 | 81 | #endif // RAPIDJSON_OSTREAMWRAPPER_H_ 82 | -------------------------------------------------------------------------------- /rapidjson/stream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #include "rapidjson.h" 16 | 17 | #ifndef RAPIDJSON_STREAM_H_ 18 | #define RAPIDJSON_STREAM_H_ 19 | 20 | #include "encodings.h" 21 | 22 | RAPIDJSON_NAMESPACE_BEGIN 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | // Stream 26 | 27 | /*! \class rapidjson::Stream 28 | \brief Concept for reading and writing characters. 29 | 30 | For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). 31 | 32 | For write-only stream, only need to implement Put() and Flush(). 33 | 34 | \code 35 | concept Stream { 36 | typename Ch; //!< Character type of the stream. 37 | 38 | //! Read the current character from stream without moving the read cursor. 39 | Ch Peek() const; 40 | 41 | //! Read the current character from stream and moving the read cursor to next character. 42 | Ch Take(); 43 | 44 | //! Get the current read cursor. 45 | //! \return Number of characters read from start. 46 | size_t Tell(); 47 | 48 | //! Begin writing operation at the current read pointer. 49 | //! \return The begin writer pointer. 50 | Ch* PutBegin(); 51 | 52 | //! Write a character. 53 | void Put(Ch c); 54 | 55 | //! Flush the buffer. 56 | void Flush(); 57 | 58 | //! End the writing operation. 59 | //! \param begin The begin write pointer returned by PutBegin(). 60 | //! \return Number of characters written. 61 | size_t PutEnd(Ch* begin); 62 | } 63 | \endcode 64 | */ 65 | 66 | //! Provides additional information for stream. 67 | /*! 68 | By using traits pattern, this type provides a default configuration for stream. 69 | For custom stream, this type can be specialized for other configuration. 70 | See TEST(Reader, CustomStringStream) in readertest.cpp for example. 71 | */ 72 | template 73 | struct StreamTraits { 74 | //! Whether to make local copy of stream for optimization during parsing. 75 | /*! 76 | By default, for safety, streams do not use local copy optimization. 77 | Stream that can be copied fast should specialize this, like StreamTraits. 78 | */ 79 | enum { copyOptimization = 0 }; 80 | }; 81 | 82 | //! Reserve n characters for writing to a stream. 83 | template 84 | inline void PutReserve(Stream& stream, size_t count) { 85 | (void)stream; 86 | (void)count; 87 | } 88 | 89 | //! Write character to a stream, presuming buffer is reserved. 90 | template 91 | inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { 92 | stream.Put(c); 93 | } 94 | 95 | //! Put N copies of a character to a stream. 96 | template 97 | inline void PutN(Stream& stream, Ch c, size_t n) { 98 | PutReserve(stream, n); 99 | for (size_t i = 0; i < n; i++) 100 | PutUnsafe(stream, c); 101 | } 102 | 103 | /////////////////////////////////////////////////////////////////////////////// 104 | // StringStream 105 | 106 | //! Read-only string stream. 107 | /*! \note implements Stream concept 108 | */ 109 | template 110 | struct GenericStringStream { 111 | typedef typename Encoding::Ch Ch; 112 | 113 | GenericStringStream(const Ch *src) : src_(src), head_(src) {} 114 | 115 | Ch Peek() const { return *src_; } 116 | Ch Take() { return *src_++; } 117 | size_t Tell() const { return static_cast(src_ - head_); } 118 | 119 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 120 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 121 | void Flush() { RAPIDJSON_ASSERT(false); } 122 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 123 | 124 | const Ch* src_; //!< Current read position. 125 | const Ch* head_; //!< Original head of the string. 126 | }; 127 | 128 | template 129 | struct StreamTraits > { 130 | enum { copyOptimization = 1 }; 131 | }; 132 | 133 | //! String stream with UTF8 encoding. 134 | typedef GenericStringStream > StringStream; 135 | 136 | /////////////////////////////////////////////////////////////////////////////// 137 | // InsituStringStream 138 | 139 | //! A read-write string stream. 140 | /*! This string stream is particularly designed for in-situ parsing. 141 | \note implements Stream concept 142 | */ 143 | template 144 | struct GenericInsituStringStream { 145 | typedef typename Encoding::Ch Ch; 146 | 147 | GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} 148 | 149 | // Read 150 | Ch Peek() { return *src_; } 151 | Ch Take() { return *src_++; } 152 | size_t Tell() { return static_cast(src_ - head_); } 153 | 154 | // Write 155 | void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } 156 | 157 | Ch* PutBegin() { return dst_ = src_; } 158 | size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } 159 | void Flush() {} 160 | 161 | Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } 162 | void Pop(size_t count) { dst_ -= count; } 163 | 164 | Ch* src_; 165 | Ch* dst_; 166 | Ch* head_; 167 | }; 168 | 169 | template 170 | struct StreamTraits > { 171 | enum { copyOptimization = 1 }; 172 | }; 173 | 174 | //! Insitu string stream with UTF8 encoding. 175 | typedef GenericInsituStringStream > InsituStringStream; 176 | 177 | RAPIDJSON_NAMESPACE_END 178 | 179 | #endif // RAPIDJSON_STREAM_H_ 180 | -------------------------------------------------------------------------------- /rapidjson/stringbuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 16 | #define RAPIDJSON_STRINGBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 22 | #include // std::move 23 | #endif 24 | 25 | #include "internal/stack.h" 26 | 27 | #if defined(__clang__) 28 | RAPIDJSON_DIAG_PUSH 29 | RAPIDJSON_DIAG_OFF(c++98-compat) 30 | #endif 31 | 32 | RAPIDJSON_NAMESPACE_BEGIN 33 | 34 | //! Represents an in-memory output stream. 35 | /*! 36 | \tparam Encoding Encoding of the stream. 37 | \tparam Allocator type for allocating memory buffer. 38 | \note implements Stream concept 39 | */ 40 | template 41 | class GenericStringBuffer { 42 | public: 43 | typedef typename Encoding::Ch Ch; 44 | 45 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 46 | 47 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 48 | GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} 49 | GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { 50 | if (&rhs != this) 51 | stack_ = std::move(rhs.stack_); 52 | return *this; 53 | } 54 | #endif 55 | 56 | void Put(Ch c) { *stack_.template Push() = c; } 57 | void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } 58 | void Flush() {} 59 | 60 | void Clear() { stack_.Clear(); } 61 | void ShrinkToFit() { 62 | // Push and pop a null terminator. This is safe. 63 | *stack_.template Push() = '\0'; 64 | stack_.ShrinkToFit(); 65 | stack_.template Pop(1); 66 | } 67 | 68 | void Reserve(size_t count) { stack_.template Reserve(count); } 69 | Ch* Push(size_t count) { return stack_.template Push(count); } 70 | Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } 71 | void Pop(size_t count) { stack_.template Pop(count); } 72 | 73 | const Ch* GetString() const { 74 | // Push and pop a null terminator. This is safe. 75 | *stack_.template Push() = '\0'; 76 | stack_.template Pop(1); 77 | 78 | return stack_.template Bottom(); 79 | } 80 | 81 | //! Get the size of string in bytes in the string buffer. 82 | size_t GetSize() const { return stack_.GetSize(); } 83 | 84 | //! Get the length of string in Ch in the string buffer. 85 | size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } 86 | 87 | static const size_t kDefaultCapacity = 256; 88 | mutable internal::Stack stack_; 89 | 90 | private: 91 | // Prohibit copy constructor & assignment operator. 92 | GenericStringBuffer(const GenericStringBuffer&); 93 | GenericStringBuffer& operator=(const GenericStringBuffer&); 94 | }; 95 | 96 | //! String buffer with UTF8 encoding 97 | typedef GenericStringBuffer > StringBuffer; 98 | 99 | template 100 | inline void PutReserve(GenericStringBuffer& stream, size_t count) { 101 | stream.Reserve(count); 102 | } 103 | 104 | template 105 | inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { 106 | stream.PutUnsafe(c); 107 | } 108 | 109 | //! Implement specialized version of PutN() with memset() for better performance. 110 | template<> 111 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 112 | std::memset(stream.stack_.Push(n), c, n * sizeof(c)); 113 | } 114 | 115 | RAPIDJSON_NAMESPACE_END 116 | 117 | #if defined(__clang__) 118 | RAPIDJSON_DIAG_POP 119 | #endif 120 | 121 | #endif // RAPIDJSON_STRINGBUFFER_H_ 122 | -------------------------------------------------------------------------------- /socket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program. If not, see . 14 | * 15 | * Additional permission under GNU GPL version 3 section 7 16 | * 17 | * If you modify this Program, or any covered work, by linking or combining 18 | * it with OpenSSL (or a modified version of that library), containing parts 19 | * covered by the terms of OpenSSL License and SSLeay License, the licensors 20 | * of this Program grant you additional permission to convey the resulting work. 21 | * 22 | */ 23 | 24 | #include "socket.h" 25 | #include "jpsock.h" 26 | #include "jconf.h" 27 | #include "console.h" 28 | #include "executor.h" 29 | 30 | #ifndef CONF_NO_TLS 31 | #include 32 | #include 33 | #include 34 | 35 | #ifndef OPENSSL_THREADS 36 | #error OpenSSL was compiled without thread support 37 | #endif 38 | #endif 39 | 40 | plain_socket::plain_socket(jpsock* err_callback) : pCallback(err_callback) 41 | { 42 | hSocket = INVALID_SOCKET; 43 | pSockAddr = nullptr; 44 | } 45 | 46 | bool plain_socket::set_hostname(const char* sAddr) 47 | { 48 | char sAddrMb[256]; 49 | char *sTmp, *sPort; 50 | 51 | size_t ln = strlen(sAddr); 52 | if (ln >= sizeof(sAddrMb)) 53 | return pCallback->set_socket_error("CONNECT error: Pool address overflow."); 54 | 55 | memcpy(sAddrMb, sAddr, ln); 56 | sAddrMb[ln] = '\0'; 57 | 58 | if ((sTmp = strstr(sAddrMb, "//")) != nullptr) 59 | memmove(sAddrMb, sTmp, strlen(sTmp) + 1); 60 | 61 | if ((sPort = strchr(sAddrMb, ':')) == nullptr) 62 | return pCallback->set_socket_error("CONNECT error: Pool port number not specified, please use format :."); 63 | 64 | sPort[0] = '\0'; 65 | sPort++; 66 | 67 | addrinfo hints = { 0 }; 68 | hints.ai_family = AF_UNSPEC; 69 | hints.ai_socktype = SOCK_STREAM; 70 | hints.ai_protocol = IPPROTO_TCP; 71 | 72 | pAddrRoot = nullptr; 73 | int err; 74 | if ((err = getaddrinfo(sAddrMb, sPort, &hints, &pAddrRoot)) != 0) 75 | return pCallback->set_socket_error_strerr("CONNECT error: GetAddrInfo: ", err); 76 | 77 | addrinfo *ptr = pAddrRoot; 78 | addrinfo *ipv4 = nullptr, *ipv6 = nullptr; 79 | 80 | while (ptr != nullptr) 81 | { 82 | if (ptr->ai_family == AF_INET) 83 | ipv4 = ptr; 84 | if (ptr->ai_family == AF_INET6) 85 | ipv6 = ptr; 86 | ptr = ptr->ai_next; 87 | } 88 | 89 | if (ipv4 == nullptr && ipv6 == nullptr) 90 | { 91 | freeaddrinfo(pAddrRoot); 92 | pAddrRoot = nullptr; 93 | return pCallback->set_socket_error("CONNECT error: I found some DNS records but no IPv4 or IPv6 addresses."); 94 | } 95 | else if (ipv4 != nullptr && ipv6 == nullptr) 96 | pSockAddr = ipv4; 97 | else if (ipv4 == nullptr && ipv6 != nullptr) 98 | pSockAddr = ipv6; 99 | else if (ipv4 != nullptr && ipv6 != nullptr) 100 | { 101 | if(jconf::inst()->PreferIpv4()) 102 | pSockAddr = ipv4; 103 | else 104 | pSockAddr = ipv6; 105 | } 106 | 107 | hSocket = socket(pSockAddr->ai_family, pSockAddr->ai_socktype, pSockAddr->ai_protocol); 108 | 109 | if (hSocket == INVALID_SOCKET) 110 | { 111 | freeaddrinfo(pAddrRoot); 112 | pAddrRoot = nullptr; 113 | return pCallback->set_socket_error_strerr("CONNECT error: Socket creation failed "); 114 | } 115 | 116 | return true; 117 | } 118 | 119 | bool plain_socket::connect() 120 | { 121 | int ret = ::connect(hSocket, pSockAddr->ai_addr, (int)pSockAddr->ai_addrlen); 122 | 123 | freeaddrinfo(pAddrRoot); 124 | pAddrRoot = nullptr; 125 | 126 | if (ret != 0) 127 | return pCallback->set_socket_error_strerr("CONNECT error: "); 128 | else 129 | return true; 130 | } 131 | 132 | int plain_socket::recv(char* buf, unsigned int len) 133 | { 134 | int ret = ::recv(hSocket, buf, len, 0); 135 | 136 | if(ret == 0) 137 | pCallback->set_socket_error("RECEIVE error: socket closed"); 138 | if(ret == SOCKET_ERROR || ret < 0) 139 | pCallback->set_socket_error_strerr("RECEIVE error: "); 140 | 141 | return ret; 142 | } 143 | 144 | bool plain_socket::send(const char* buf) 145 | { 146 | int pos = 0, slen = strlen(buf); 147 | while (pos != slen) 148 | { 149 | int ret = ::send(hSocket, buf + pos, slen - pos, 0); 150 | if (ret == SOCKET_ERROR) 151 | { 152 | pCallback->set_socket_error_strerr("SEND error: "); 153 | return false; 154 | } 155 | else 156 | pos += ret; 157 | } 158 | 159 | return true; 160 | } 161 | 162 | void plain_socket::close(bool free) 163 | { 164 | if(hSocket != INVALID_SOCKET) 165 | { 166 | sock_close(hSocket); 167 | hSocket = INVALID_SOCKET; 168 | } 169 | } 170 | 171 | #ifndef CONF_NO_TLS 172 | tls_socket::tls_socket(jpsock* err_callback) : pCallback(err_callback) 173 | { 174 | } 175 | 176 | void tls_socket::print_error() 177 | { 178 | BIO* err_bio = BIO_new(BIO_s_mem()); 179 | ERR_print_errors(err_bio); 180 | 181 | char *buf = nullptr; 182 | size_t len = BIO_get_mem_data(err_bio, &buf); 183 | 184 | pCallback->set_socket_error(buf, len); 185 | 186 | BIO_free(err_bio); 187 | } 188 | 189 | void tls_socket::init_ctx() 190 | { 191 | const SSL_METHOD* method = SSLv23_method(); 192 | 193 | if(method == nullptr) 194 | return; 195 | 196 | ctx = SSL_CTX_new(method); 197 | if(ctx == nullptr) 198 | return; 199 | 200 | if(jconf::inst()->TlsSecureAlgos()) 201 | { 202 | SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_COMPRESSION); 203 | } 204 | } 205 | 206 | bool tls_socket::set_hostname(const char* sAddr) 207 | { 208 | if(ctx == nullptr) 209 | { 210 | init_ctx(); 211 | if(ctx == nullptr) 212 | { 213 | print_error(); 214 | return false; 215 | } 216 | } 217 | 218 | if((bio = BIO_new_ssl_connect(ctx)) == nullptr) 219 | { 220 | print_error(); 221 | return false; 222 | } 223 | 224 | if(BIO_set_conn_hostname(bio, sAddr) != 1) 225 | { 226 | print_error(); 227 | return false; 228 | } 229 | 230 | BIO_get_ssl(bio, &ssl); 231 | if(ssl == nullptr) 232 | { 233 | print_error(); 234 | return false; 235 | } 236 | 237 | if(jconf::inst()->TlsSecureAlgos()) 238 | { 239 | if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1) 240 | { 241 | print_error(); 242 | return false; 243 | } 244 | } 245 | 246 | return true; 247 | } 248 | 249 | bool tls_socket::connect() 250 | { 251 | if(BIO_do_connect(bio) != 1) 252 | { 253 | print_error(); 254 | return false; 255 | } 256 | 257 | if(BIO_do_handshake(bio) != 1) 258 | { 259 | print_error(); 260 | return false; 261 | } 262 | 263 | /* Step 1: verify a server certificate was presented during the negotiation */ 264 | X509* cert = SSL_get_peer_certificate(ssl); 265 | if(cert == nullptr) 266 | { 267 | print_error(); 268 | return false; 269 | } 270 | 271 | const EVP_MD* digest; 272 | unsigned char md[EVP_MAX_MD_SIZE]; 273 | unsigned int dlen; 274 | 275 | digest = EVP_get_digestbyname("sha256"); 276 | if(digest == nullptr) 277 | { 278 | print_error(); 279 | return false; 280 | } 281 | 282 | if(X509_digest(cert, digest, md, &dlen) != 1) 283 | { 284 | X509_free(cert); 285 | print_error(); 286 | return false; 287 | } 288 | 289 | if(pCallback->pool_id != executor::dev_pool_id) 290 | { 291 | //Base64 encode digest 292 | BIO *bmem, *b64; 293 | b64 = BIO_new(BIO_f_base64()); 294 | bmem = BIO_new(BIO_s_mem()); 295 | 296 | BIO_puts(bmem, "SHA256:"); 297 | b64 = BIO_push(b64, bmem); 298 | BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 299 | BIO_write(b64, md, dlen); 300 | BIO_flush(b64); 301 | 302 | const char* conf_md = jconf::inst()->GetTlsFingerprint(); 303 | char *b64_md = nullptr; 304 | size_t b64_len = BIO_get_mem_data(bmem, &b64_md); 305 | 306 | if(strlen(conf_md) == 0) 307 | { 308 | printer::inst()->print_msg(L1, "Server fingerprint: %.*s", (int)b64_len, b64_md); 309 | } 310 | else if(strncmp(b64_md, conf_md, b64_len) != 0) 311 | { 312 | printer::inst()->print_msg(L0, "FINGERPRINT FAILED CHECK: %.*s was given, %s was configured", 313 | (int)b64_len, b64_md, conf_md); 314 | 315 | pCallback->set_socket_error("FINGERPRINT FAILED CHECK"); 316 | BIO_free_all(b64); 317 | X509_free(cert); 318 | return false; 319 | } 320 | 321 | BIO_free_all(b64); 322 | } 323 | 324 | X509_free(cert); 325 | return true; 326 | } 327 | 328 | int tls_socket::recv(char* buf, unsigned int len) 329 | { 330 | int ret = BIO_read(bio, buf, len); 331 | 332 | if(ret == 0) 333 | pCallback->set_socket_error("RECEIVE error: socket closed"); 334 | if(ret < 0) 335 | print_error(); 336 | 337 | return ret; 338 | } 339 | 340 | bool tls_socket::send(const char* buf) 341 | { 342 | return BIO_puts(bio, buf) > 0; 343 | } 344 | 345 | void tls_socket::close(bool free) 346 | { 347 | if(bio == nullptr || ssl == nullptr) 348 | return; 349 | 350 | if(!free) 351 | { 352 | sock_close(BIO_get_fd(bio, nullptr)); 353 | } 354 | else 355 | { 356 | BIO_free_all(bio); 357 | ssl = nullptr; 358 | bio = nullptr; 359 | } 360 | } 361 | #endif 362 | 363 | -------------------------------------------------------------------------------- /socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "socks.h" 3 | class jpsock; 4 | 5 | class base_socket 6 | { 7 | public: 8 | virtual bool set_hostname(const char* sAddr) = 0; 9 | virtual bool connect() = 0; 10 | virtual int recv(char* buf, unsigned int len) = 0; 11 | virtual bool send(const char* buf) = 0; 12 | virtual void close(bool free) = 0; 13 | }; 14 | 15 | class plain_socket : public base_socket 16 | { 17 | public: 18 | plain_socket(jpsock* err_callback); 19 | 20 | bool set_hostname(const char* sAddr); 21 | bool connect(); 22 | int recv(char* buf, unsigned int len); 23 | bool send(const char* buf); 24 | void close(bool free); 25 | 26 | private: 27 | jpsock* pCallback; 28 | addrinfo *pSockAddr; 29 | addrinfo *pAddrRoot; 30 | SOCKET hSocket; 31 | }; 32 | 33 | typedef struct ssl_ctx_st SSL_CTX; 34 | typedef struct bio_st BIO; 35 | typedef struct ssl_st SSL; 36 | 37 | class tls_socket : public base_socket 38 | { 39 | public: 40 | tls_socket(jpsock* err_callback); 41 | 42 | bool set_hostname(const char* sAddr); 43 | bool connect(); 44 | int recv(char* buf, unsigned int len); 45 | bool send(const char* buf); 46 | void close(bool free); 47 | 48 | private: 49 | void init_ctx(); 50 | void print_error(); 51 | 52 | jpsock* pCallback; 53 | 54 | SSL_CTX* ctx = nullptr; 55 | BIO* bio = nullptr; 56 | SSL* ssl = nullptr; 57 | }; 58 | -------------------------------------------------------------------------------- /socks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef _WIN32 3 | #ifndef _WIN32_WINNT 4 | #define _WIN32_WINNT 0x0601 /* Windows 7 */ 5 | #endif 6 | #include 7 | #include 8 | #include 9 | 10 | inline void sock_init() 11 | { 12 | static bool bWSAInit = false; 13 | 14 | if (!bWSAInit) 15 | { 16 | WSADATA wsaData; 17 | WSAStartup(MAKEWORD(2, 2), &wsaData); 18 | bWSAInit = true; 19 | } 20 | } 21 | 22 | inline void sock_close(SOCKET s) 23 | { 24 | shutdown(s, SD_BOTH); 25 | closesocket(s); 26 | } 27 | 28 | inline const char* sock_strerror(char* buf, size_t len) 29 | { 30 | buf[0] = '\0'; 31 | 32 | FormatMessageA( 33 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, 34 | NULL, WSAGetLastError(), 35 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 36 | (LPSTR)buf, len, NULL); 37 | 38 | return buf; 39 | } 40 | 41 | inline const char* sock_gai_strerror(int err, char* buf, size_t len) 42 | { 43 | buf[0] = '\0'; 44 | 45 | FormatMessageA( 46 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, 47 | NULL, (DWORD)err, 48 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 49 | (LPSTR)buf, len, NULL); 50 | 51 | return buf; 52 | } 53 | 54 | #else 55 | 56 | /* Assume that any non-Windows platform uses POSIX-style sockets instead. */ 57 | #include 58 | #include 59 | #include /* Needed for getaddrinfo() and freeaddrinfo() */ 60 | #include /* Needed for close() */ 61 | #include 62 | #include 63 | 64 | inline void sock_init() {} 65 | typedef int SOCKET; 66 | 67 | #define INVALID_SOCKET (-1) 68 | #define SOCKET_ERROR (-1) 69 | 70 | inline void sock_close(SOCKET s) 71 | { 72 | shutdown(s, SHUT_RDWR); 73 | close(s); 74 | } 75 | 76 | inline const char* sock_strerror(char* buf, size_t len) 77 | { 78 | buf[0] = '\0'; 79 | #if defined(__APPLE__) 80 | strerror_r(errno, buf, len); 81 | return buf; 82 | #else 83 | return strerror_r(errno, buf, len); 84 | #endif 85 | } 86 | 87 | inline const char* sock_gai_strerror(int err, char* buf, size_t len) 88 | { 89 | buf[0] = '\0'; 90 | return gai_strerror(err); 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /thdq.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | class thdq 10 | { 11 | public: 12 | T pop() 13 | { 14 | std::unique_lock mlock(mutex_); 15 | while (queue_.empty()) { cond_.wait(mlock); } 16 | auto item = std::move(queue_.front()); 17 | queue_.pop(); 18 | return item; 19 | } 20 | 21 | void pop(T& item) 22 | { 23 | std::unique_lock mlock(mutex_); 24 | while (queue_.empty()) { cond_.wait(mlock); } 25 | item = queue_.front(); 26 | queue_.pop(); 27 | } 28 | 29 | void push(const T& item) 30 | { 31 | std::unique_lock mlock(mutex_); 32 | queue_.push(item); 33 | mlock.unlock(); 34 | cond_.notify_one(); 35 | } 36 | 37 | void push(T&& item) 38 | { 39 | std::unique_lock mlock(mutex_); 40 | queue_.push(std::move(item)); 41 | mlock.unlock(); 42 | cond_.notify_one(); 43 | } 44 | 45 | private: 46 | std::queue queue_; 47 | std::mutex mutex_; 48 | std::condition_variable cond_; 49 | }; 50 | -------------------------------------------------------------------------------- /webdesign.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern const char sHtmlCssEtag [] = "00000006"; 4 | extern const char sHtmlCssFile [] = 5 | "body {" 6 | "font-family: Tahoma, Arial, sans-serif;" 7 | "font-size: 80%;" 8 | "background-color: rgb(240, 240, 240);" 9 | "}" 10 | 11 | "a {" 12 | "color: rgb(44, 55, 66);" 13 | "}" 14 | 15 | "a:link {" 16 | "text-decoration: none;" 17 | "}" 18 | 19 | "a:visited {" 20 | "color: rgb(44, 55, 66);" 21 | "}" 22 | 23 | "a:hover {" 24 | "color: rgb(255, 153, 0);" 25 | "}" 26 | 27 | "a:active {" 28 | "color: rgb(204, 122, 0);" 29 | "}" 30 | 31 | ".all {" 32 | "max-width:600px;" 33 | "margin: auto;" 34 | "}" 35 | 36 | ".header {" 37 | "background-color: rgb(30, 30, 30);" 38 | "color: white;" 39 | "padding: 10px;" 40 | "font-weight: bold;" 41 | "margin: 10px 0px;" 42 | "}" 43 | 44 | ".links {" 45 | "padding: 7px;" 46 | "text-align: center;" 47 | "background-color: rgb(215, 215, 215);" 48 | "box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12);" 49 | "}" 50 | 51 | ".data th, td {" 52 | "padding: 5px 12px;" 53 | "text-align: right;" 54 | "border-bottom: 1px solid #ccc;" 55 | "}" 56 | 57 | ".data tr:nth-child(even) {" 58 | "background-color: #ddd;" 59 | "}" 60 | 61 | ".data th {" 62 | "background-color: #ccc;" 63 | "}" 64 | 65 | ".data table {" 66 | "width: 100%;" 67 | "max-width: 600px;" 68 | "}" 69 | 70 | ".letter {" 71 | "font-weight: bold;" 72 | "}" 73 | 74 | "h4 {" 75 | "background-color: rgb(0, 130, 130);" 76 | "color: white;" 77 | "padding: 10px;" 78 | "margin: 10px 0px;" 79 | "}" 80 | 81 | ".flex-container {" 82 | "display: -webkit-flex;" 83 | "display: flex;" 84 | "}" 85 | 86 | ".flex-item {" 87 | "width: 33%;" 88 | "margin: 3px;" 89 | "}"; 90 | 91 | size_t sHtmlCssSize = sizeof(sHtmlCssFile) - 1; 92 | 93 | extern const char sHtmlCommonHeader [] = 94 | "" 95 | "" 96 | "" 97 | "%s" 98 | "" 99 | "
" 100 | "
XMR-Stak-NVIDIA
" 101 | 102 | "
" 103 | "" 106 | "" 109 | "" 112 | "
" 113 | "

%s

"; 114 | 115 | extern const char sHtmlHashrateBodyHigh [] = 116 | "
" 117 | "" 118 | ""; 119 | 120 | extern const char sHtmlHashrateTableRow [] = 121 | ""; 122 | 123 | extern const char sHtmlHashrateBodyLow [] = 124 | "" 125 | "" 126 | "
Thread ID10s60s15mH/s
%u%s%s%s
Totals:%s%s%s
Highest:%s
" 127 | "
"; 128 | 129 | extern const char sHtmlConnectionBodyHigh [] = 130 | "
" 131 | "" 132 | "" 133 | "" 134 | "" 135 | "
Pool address%s
Connected since%s
Pool ping time%u ms
" 136 | "

Network error log

" 137 | "" 138 | ""; 139 | 140 | extern const char sHtmlConnectionTableRow [] = 141 | ""; 142 | 143 | extern const char sHtmlConnectionBodyLow [] = 144 | "
DateError
%s%s
"; 145 | 146 | extern const char sHtmlResultBodyHigh [] = 147 | "
" 148 | "" 149 | "" 150 | "" 151 | "" 152 | "" 153 | "
Difficulty%u
Good results%u / %u (%.1f %%)
Avg result time%.1f sec
Pool-side hashes%u
" 154 | "

Top 10 best results found

" 155 | "" 156 | "" 157 | "" 158 | "" 159 | "" 160 | "" 161 | "
1%llu2%llu
3%llu4%llu
5%llu6%llu
7%llu8%llu
9%llu10%llu
" 162 | "

Error details

" 163 | "" 164 | "" 165 | ""; 166 | 167 | extern const char sHtmlResultTableRow [] = 168 | ""; 169 | 170 | extern const char sHtmlResultBodyLow [] = 171 | "
Error text
CountLast seen
%s
%llu%s
"; 172 | 173 | -------------------------------------------------------------------------------- /webdesign.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern const char sHtmlCssEtag[]; 4 | extern const char sHtmlCssFile[]; 5 | extern size_t sHtmlCssSize; 6 | 7 | extern const char sHtmlCommonHeader[]; 8 | 9 | extern const char sHtmlHashrateBodyHigh[]; 10 | extern const char sHtmlHashrateTableRow[]; 11 | extern const char sHtmlHashrateBodyLow[]; 12 | 13 | extern const char sHtmlConnectionBodyHigh[]; 14 | extern const char sHtmlConnectionTableRow[]; 15 | extern const char sHtmlConnectionBodyLow[]; 16 | 17 | extern const char sHtmlResultBodyHigh[]; 18 | extern const char sHtmlResultTableRow[]; 19 | extern const char sHtmlResultBodyLow[]; 20 | --------------------------------------------------------------------------------