void attempt ( bool sell, std::string name, Quality taker_quality, cross_attempt_offer const offer, std::string const funds, Quality cross_quality, cross_attempt_offer const cross, std::string const cross_funds, cross_attempt_offer const flow, Issue const& issue_in, Issue const& issue_out, Rate rate_in = parityRate, Rate rate_out = parityRate) { Amounts taker_offer (parse_amounts ( offer.in, issue_in, offer.out, issue_out)); Amounts cross_offer (parse_amounts ( cross.in, issue_in, cross.out, issue_out)); CrossType cross_type; if (isXRP (issue_out)) cross_type = CrossType::IouToXrp; else if (isXRP (issue_in)) cross_type = CrossType::XrpToIou; else cross_type = CrossType::IouToIou; // FIXME: We are always invoking the IOU-to-IOU taker. We should select // the correct type dynamically. TestTaker taker (cross_type, taker_offer, taker_quality, parse_amount (funds, issue_in), sell ? tfSell : 0, rate_in, rate_out); taker.set_funds (parse_amount (cross_funds, issue_out)); auto result = taker.cross (cross_offer, cross_quality); Amounts const expected (parse_amounts ( flow.in, issue_in, flow.out, issue_out)); BEAST_EXPECT(expected == result); if (expected != result) { log << "Expected: " << format_amount (expected.in) << " : " << format_amount (expected.out) << '\n' << " Actual: " << format_amount (result.in) << " : " << format_amount (result.out) << std::endl; } }
bool uri_decode(const std::string& uri, uri_decode_result& result) { uri_parse_result raw_result; if (!uri_parse(uri, raw_result)) return false; if (raw_result.address) result.address.reset(raw_result.address.get()); for (const parameter_pair& pair: raw_result.parameters) { if (pair.key == "amount") { uint64_t amount = parse_amount(pair.value); if (amount == std::numeric_limits<uint64_t>::max()) return false; result.amount.reset(amount); } else if (pair.key == "label") result.label.reset(pair.value); else if (pair.key == "message") result.message.reset(pair.value); else if (pair.key == "r") result.r.reset(pair.value); else if (!pair.key.compare(0, 4, "req-")) return false; } return true; }
void GncPreSplit::set (GncTransPropType prop_type, const std::string& value) { try { // Drop any existing error for the prop_type we're about to set m_errors.erase(prop_type); Account *acct = nullptr; switch (prop_type) { case GncTransPropType::ACTION: m_action = boost::none; if (!value.empty()) m_action = value; break; case GncTransPropType::TACTION: m_taction = boost::none; if (!value.empty()) m_taction = value; break; case GncTransPropType::ACCOUNT: m_account = boost::none; if (value.empty()) throw std::invalid_argument (_("Account value can't be empty.")); acct = gnc_csv_account_map_search (value.c_str()); if (acct) m_account = acct; else throw std::invalid_argument (_(bad_acct)); break; case GncTransPropType::TACCOUNT: m_taccount = boost::none; if (value.empty()) throw std::invalid_argument (_("Transfer account value can't be empty.")); acct = gnc_csv_account_map_search (value.c_str()); if (acct) m_taccount = acct; else throw std::invalid_argument (_(bad_tacct)); break; case GncTransPropType::MEMO: m_memo = boost::none; if (!value.empty()) m_memo = value; break; case GncTransPropType::TMEMO: m_tmemo = boost::none; if (!value.empty()) m_tmemo = value; break; case GncTransPropType::DEPOSIT: m_deposit = boost::none; m_deposit = parse_amount (value, m_currency_format); // Will throw if parsing fails break; case GncTransPropType::WITHDRAWAL: m_withdrawal = boost::none; m_withdrawal = parse_amount (value, m_currency_format); // Will throw if parsing fails break; case GncTransPropType::PRICE: m_price = boost::none; m_price = parse_amount (value, m_currency_format); // Will throw if parsing fails break; case GncTransPropType::REC_STATE: m_rec_state = boost::none; m_rec_state = parse_reconciled (value); // Throws if parsing fails break; case GncTransPropType::TREC_STATE: m_trec_state = boost::none; m_trec_state = parse_reconciled (value); // Throws if parsing fails break; case GncTransPropType::REC_DATE: m_rec_date = boost::none; if (!value.empty()) m_rec_date = GncDate (value, GncDate::c_formats[m_date_format].m_fmt); // Throws if parsing fails break; case GncTransPropType::TREC_DATE: m_trec_date = boost::none; if (!value.empty()) m_trec_date = GncDate (value, GncDate::c_formats[m_date_format].m_fmt); // Throws if parsing fails break; default: /* Issue a warning for all other prop_types. */ PWARN ("%d is an invalid property for a split", static_cast<int>(prop_type)); break; } } catch (const std::invalid_argument& e) { auto err_str = std::string(_(gnc_csv_col_type_strs[prop_type])) + std::string(_(" could not be understood.\n")) + e.what(); m_errors.emplace(prop_type, err_str); throw std::invalid_argument (err_str); } catch (const std::out_of_range& e) { auto err_str = std::string(_(gnc_csv_col_type_strs[prop_type])) + std::string(_(" could not be understood.\n")) + e.what(); m_errors.emplace(prop_type, err_str); throw std::invalid_argument (err_str); } }