fc::vector<header> parse_urlencoded_params( const fc::string& f ) { int num_args = 0; for( size_t i = 0; i < f.size(); ++i ) { if( f[i] == '=' ) ++num_args; } fc::vector<header> h(num_args); int arg = 0; for( size_t i = 0; i < f.size(); ++i ) { while( f[i] != '=' && i < f.size() ) { if( f[i] == '%' ) { h[arg].key += char((fc::from_hex(f[i+1]) << 4) | fc::from_hex(f[i+2])); i += 3; } else { h[arg].key += f[i]; ++i; } } ++i; while( i < f.size() && f[i] != '&' ) { if( f[i] == '%' ) { h[arg].val += char((fc::from_hex(f[i+1]) << 4) | fc::from_hex(f[i+2])); i += 3; } else { h[arg].val += f[i] == '+' ? ' ' : f[i]; ++i; } } ++arg; } return h; }
size_t from_hex( const fc::string& hex_str, char* out_data, size_t out_data_len ) { fc::string::const_iterator i = hex_str.begin(); uint8_t* out_pos = (uint8_t*)out_data; uint8_t* out_end = out_pos + out_data_len; while( i != hex_str.end() && out_end != out_pos ) { *out_pos = from_hex( *i ) << 4; ++i; if( i != hex_str.end() ) { *out_pos |= from_hex( *i ); ++i; } ++out_pos; } return out_pos - (uint8_t*)out_data; }
void node::start_service( uint16_t cn, const fc::string& name, const node::new_channel_handler& cb ) { if( !my->_thread.is_current() ) { my->_thread.async( [&,this](){ return start_service( cn, name, cb ); } ).wait(); return; } if( !my->_services.insert( service( cn, name, cb ) ).second ) FC_THROW_MSG( "Unable to start service '%s' on channel '%s' because channel '%s' is in use.", name.c_str(), cn, cn ); slog( "Starting service '%s' on channel %d", name.c_str(), cn ); }
// windows command-line escaping rules are a disaster, partly because how the command-line is // parsed depends on what program you're running. In windows, the command line is passed in // as a single string, and the process is left to interpret it as it sees fit. The standard // C runtime uses one set of rules, the function CommandLineToArgvW usually used by // GUI-mode programs uses a different set. // Here we try to find a common denominator that works well for simple cases // it's only minimally tested right now due to time constraints. fc::string detail::process_impl::windows_shell_escape(const fc::string& str) { if (str.find_first_of(" \"") == fc::string::npos) return str; fc::string escaped_quotes(str); for (size_t start = escaped_quotes.find("\""); start != fc::string::npos; start = escaped_quotes.find("\"", start + 2)) escaped_quotes.replace(start, 1, "\\\""); fc::string escaped_str("\""); escaped_str += escaped_quotes; escaped_str += "\""; return escaped_str; }
// these rules work pretty well for a standard bash shell on unix fc::string detail::process_impl::unix_shell_escape(const fc::string& str) { if (str.find_first_of(" ;&|><*?`$(){}[]!#'\"") == fc::string::npos) return str; fc::string escaped_quotes(str); for (size_t start = escaped_quotes.find("'"); start != fc::string::npos; start = escaped_quotes.find("'", start + 5)) escaped_quotes.replace(start, 1, "'\"'\"'"); fc::string escaped_str("\'"); escaped_str += escaped_quotes; escaped_str += "\'"; return escaped_str; }
/*** * @brief Read input from the user * @param prompt the prompt to display * @param line what the user typed */ void cli::getline( const fc::string& prompt, fc::string& line) { // getting file descriptor for C++ streams is near impossible // so we just assume it's the same as the C stream... #ifdef HAVE_EDITLINE #ifndef WIN32 if( isatty( fileno( stdin ) ) ) #else // it's implied by // https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx // that this is the proper way to do this on Windows, but I have // no access to a Windows compiler and thus, // no idea if this actually works if( _isatty( _fileno( stdin ) ) ) #endif { rl_set_complete_func(my_rl_complete); rl_set_list_possib_func(cli_completion); rl_set_check_secret_func(cli_check_secret); static fc::thread getline_thread("getline"); getline_thread.async( [&](){ char* line_read = nullptr; std::cout.flush(); //readline doesn't use cin, so we must manually flush _out line_read = readline(prompt.c_str()); if( line_read == nullptr ) FC_THROW_EXCEPTION( fc::eof_exception, "" ); line = line_read; // we don't need here to add line in editline's history, cause it will be doubled free(line_read); }).wait(); } else #endif { std::cout << prompt; // sync_call( cin_thread, [&](){ std::getline( *input_stream, line ); }, "getline"); fc::getline( fc::cin, line ); return; } }
fc::string pretty_print( const fc::string& v, uint8_t indent ) { int level = 0; fc::stringstream ss; bool first = false; bool quote = false; bool escape = false; for( uint32_t i = 0; i < v.size(); ++i ) { switch( v[i] ) { case '\\': if( !escape ) { if( quote ) escape = true; } else { escape = false; } ss<<v[i]; break; case ':': if( !quote ) { ss<<": "; } else { ss<<':'; } break; case '"': if( first ) { ss<<'\n'; for( int i = 0; i < level*indent; ++i ) ss<<' '; first = false; } if( !escape ) { quote = !quote; } escape = false; ss<<'"'; break; case '{': case '[': ss<<v[i]; if( !quote ) { ++level; first = true; }else { escape = false; } break; case '}': case ']': if( !quote ) { if( v[i-1] != '[' && v[i-1] != '{' ) { ss<<'\n'; } --level; if( !first ) { for( int i = 0; i < level*indent; ++i ) ss<<' '; } first = false; ss<<v[i]; break; } else { escape = false; ss<<v[i]; } break; case ',': if( !quote ) { ss<<','; first = true; } else { escape = false; ss<<','; } break; case 'n': //If we're in quotes and see a \n, just print it literally but unset the escape flag. if( quote && escape ) escape = false; //No break; fall through to default case default: if( first ) { ss<<'\n'; for( int i = 0; i < level*indent; ++i ) ss<<' '; first = false; } ss << v[i]; } } return ss.str(); }
address::address( const fc::string& s ) { _ip = boost::asio::ip::address_v4::from_string(s.c_str()).to_ulong(); }