bool OTAgreement::SetAgreement(const long & lTransactionNum, const OTString & strConsideration, const time_t & VALID_FROM/*=0*/, const time_t & VALID_TO/*=0*/) { // Set the Transaction Number... SetTransactionNum(lTransactionNum); // Set the Consideration memo... m_strConsideration.Set(strConsideration); // ------------------------------------------- time_t CURRENT_TIME = time(NULL); // Set the Creation Date. SetCreationDate(CURRENT_TIME); // ------------------------------------------- // The default "valid from" time is NOW. if (0 >= VALID_FROM) // if it's 0 or less, set to current time. SetValidFrom(CURRENT_TIME); else // Otherwise use whatever was passed in. SetValidFrom(VALID_FROM); // ------------------------------------------- // The default "valid to" time is 0 (which means no expiration date / cancel anytime.) if (0 == VALID_TO) // VALID_TO is 0 { SetValidTo(VALID_TO); // Keep it at zero then, so it won't expire. } else if (0 < VALID_TO) // VALID_TO is ABOVE zero... { if (VALID_TO < VALID_FROM) // If Valid-To date is EARLIER than Valid-From date... { long lValidTo = VALID_TO, lValidFrom = VALID_FROM; OTLog::vError("VALID_TO is earlier than VALID_FROM in SetAgreement: %ld, %ld\n", lValidTo, lValidFrom); return false; } SetValidTo(VALID_TO); // Set it to whatever it is, since it is now validated as higher than Valid-From. } else // VALID_TO is a NEGATIVE number... Error. { long lValidTo = VALID_TO; OTLog::vError("Negative value for valid_to in SetAgreement: %ld\n", lValidTo); return false; } // ------------------------------------------- OTLog::Output(4, "Successfully performed SetAgreement()\n"); return true; }
bool OTOffer::MakeOffer( bool bBuyingOrSelling, // True == SELLING, False == BUYING const int64_t& lPriceLimit, // Per Minimum Increment... (Zero price means // it's a market order.) const int64_t& lTotalAssetsOffer, // Total assets available for sale or // purchase. const int64_t& lMinimumIncrement, // The minimum increment that must be // bought or sold for each transaction const int64_t& lTransactionNum, // The transaction number authorizing this // trade. const time64_t& VALID_FROM, // defaults to RIGHT NOW const time64_t& VALID_TO) // defaults to 24 hours (a "Day Order") { m_bSelling = bBuyingOrSelling; // Bid or Ask? SetTransactionNum(lTransactionNum); SetTotalAssetsOnOffer(lTotalAssetsOffer); // 500 bushels for sale. m_strContractType.Set((m_bSelling ? "ASK" : "BID")); // Make sure minimum increment isn't bigger than total Assets. // (If you pass them into this function as the same value, it's functionally // a "FILL OR KILL" order.) int64_t lRealMinInc = lMinimumIncrement; if (lMinimumIncrement > lTotalAssetsOffer) // Once the total, minus finish // so far, is smaller than the // minimum increment, lRealMinInc = lTotalAssetsOffer; // then the OTTrade object I am linked // to will expire and remove me from // the market. // OR it could set the minimum increment to the remainder. But then need to // calc price. SetMinimumIncrement(lRealMinInc); // Must sell in 50 bushel increments. // (Perhaps on the 10-bushel market it // will sell in 5 increments of 10.) SetPriceLimit(lPriceLimit); // Won't sell for any less than $10 per // increment. (Always get best market price.) SetFinishedSoFar(0); // So far have already sold 350 bushels. Actual amount // available is (total - finished). time64_t REAL_VALID_FROM = VALID_FROM; time64_t REAL_VALID_TO = VALID_TO; if (OT_TIME_ZERO >= VALID_FROM) { REAL_VALID_FROM = OTTimeGetCurrentTime(); // This time is set to TODAY NOW } if (OT_TIME_ZERO >= VALID_TO) { // (All offers default to a "DAY ORDER" if valid dates not specified.) REAL_VALID_TO = OTTimeAddTimeInterval( REAL_VALID_FROM, OTTimeGetSecondsFromTime(OT_TIME_DAY_IN_SECONDS)); // 1 day. } SetValidFrom(REAL_VALID_FROM); SetValidTo(REAL_VALID_TO); return true; }
// This is called by the client side. First you call MakeOffer() to set up the // Offer, // then you call IssueTrade() and pass the Offer into it here. bool OTTrade::IssueTrade(OTOffer& offer, char stopSign, int64_t stopPrice) { // Make sure the Stop Sign is within parameters (0, '<', or '>') if ((stopSign == 0) || (stopSign == '<') || (stopSign == '>')) stopSign_ = stopSign; else { otErr << "Bad data in Stop Sign while issuing trade: " << stopSign << "\n"; return false; } // Make sure, if this IS a Stop order, that the price is within parameters // and set. if ((stopSign_ == '<') || (stopSign_ == '>')) { if (0 >= stopPrice) { otErr << "Expected Stop Price for trade.\n"; return false; } stopPrice_ = stopPrice; } tradesAlreadyDone_ = 0; SetCreationDate( OTTimeGetCurrentTime()); // This time is set to TODAY NOW (OTCronItem) // Validate the Notary ID, Instrument Definition ID, Currency Type ID, and // Date Range. if ((GetNotaryID() != offer.GetNotaryID()) || (GetCurrencyID() != offer.GetCurrencyID()) || (GetInstrumentDefinitionID() != offer.GetInstrumentDefinitionID()) || (offer.GetValidFrom() < OT_TIME_ZERO) || (offer.GetValidTo() < offer.GetValidFrom())) { return false; } // currencyTypeID_ // This is already set in the constructors of this // and the offer. (And compared.) // currencyAcctID_ // This is already set in the constructor of this. // Set the (now validated) date range as per the Offer. SetValidFrom(offer.GetValidFrom()); SetValidTo(offer.GetValidTo()); // Get the transaction number from the Offer. SetTransactionNum(offer.GetTransactionNum()); // Save a copy of the offer, in XML form, here on this Trade. String strOffer(offer); marketOffer_.Set(strOffer); return true; }
// Imagine that you are actually writing a cheque. // That's basically what this function does. // Make sure to sign it afterwards. bool Cheque::IssueCheque( const int64_t& lAmount, const int64_t& lTransactionNum, const time64_t& VALID_FROM, const time64_t& VALID_TO, // The expiration date (valid from/to dates) of // the cheque const Identifier& SENDER_ACCT_ID, // The asset account the cheque is drawn // on. const Identifier& SENDER_NYM_ID, // This ID must match the user ID on the // asset account, // AND must verify the cheque signature with that user's key. const String& strMemo, // Optional memo field. const Identifier* pRECIPIENT_NYM_ID) // Recipient optional. // (Might be a blank // cheque.) { m_lAmount = lAmount; m_strMemo = strMemo; SetValidFrom(VALID_FROM); SetValidTo(VALID_TO); SetTransactionNum(lTransactionNum); SetSenderAcctID(SENDER_ACCT_ID); SetSenderNymID(SENDER_NYM_ID); if (nullptr == pRECIPIENT_NYM_ID) { m_bHasRecipient = false; m_RECIPIENT_NYM_ID.Release(); } else { m_bHasRecipient = true; m_RECIPIENT_NYM_ID = *pRECIPIENT_NYM_ID; } m_bHasRemitter = false; // OTCheque::SetAsVoucher() will set this to true. if (m_lAmount < 0) m_strContractType.Set("INVOICE"); return true; }
// return -1 if error, 0 if nothing, and 1 if the node was processed. int32_t OTTrade::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { int32_t returnVal = 0; // Here we call the parent class first. // If the node is found there, or there is some error, // then we just return either way. But if it comes back // as '0', then nothing happened, and we'll continue executing. // // -- Note you can choose not to call the parent if // you don't want to use any of those xml tags. // As I do below, in the case of OTAccount. // if (0 != (returnVal = ot_super::ProcessXMLNode(xml))) return returnVal; if (!strcmp("trade", xml->getNodeName())) { m_strVersion = xml->getAttributeValue("version"); tradesAlreadyDone_ = atoi(xml->getAttributeValue("completedNoTrades")); SetTransactionNum( String::StringToLong(xml->getAttributeValue("transactionNum"))); const std::string creationStr = xml->getAttributeValue("creationDate"); const std::string validFromStr = xml->getAttributeValue("validFrom"); const std::string validToStr = xml->getAttributeValue("validTo"); int64_t creation = parseTimestamp(creationStr); int64_t validFrom = parseTimestamp(validFromStr); int64_t validTo = parseTimestamp(validToStr); SetCreationDate(OTTimeGetTimeFromSeconds(creation)); SetValidFrom(OTTimeGetTimeFromSeconds(validFrom)); SetValidTo(OTTimeGetTimeFromSeconds(validTo)); String activated(xml->getAttributeValue("hasActivated")); if (activated.Compare("true")) hasTradeActivated_ = true; else hasTradeActivated_ = false; const String notaryID(xml->getAttributeValue("notaryID")), nymID(xml->getAttributeValue("nymID")), instrumentDefinitionID( xml->getAttributeValue("instrumentDefinitionID")), assetAcctID(xml->getAttributeValue("assetAcctID")), currencyTypeID(xml->getAttributeValue("currencyTypeID")), currencyAcctID(xml->getAttributeValue("currencyAcctID")); const Identifier NOTARY_ID(notaryID), NYM_ID(nymID), INSTRUMENT_DEFINITION_ID(instrumentDefinitionID), ASSET_ACCT_ID(assetAcctID), CURRENCY_TYPE_ID(currencyTypeID), CURRENCY_ACCT_ID(currencyAcctID); SetNotaryID(NOTARY_ID); SetSenderNymID(NYM_ID); SetInstrumentDefinitionID(INSTRUMENT_DEFINITION_ID); SetSenderAcctID(ASSET_ACCT_ID); SetCurrencyID(CURRENCY_TYPE_ID); SetCurrencyAcctID(CURRENCY_ACCT_ID); otLog3 << "\n\nTrade. Transaction Number: " << m_lTransactionNum << " Completed # of Trades: " << tradesAlreadyDone_ << "\n"; otWarn << " Creation Date: " << creation << " Valid From: " << validFrom << "\n Valid To: " << validTo << "\n" " instrumentDefinitionID: " << instrumentDefinitionID << "\n assetAcctID: " << assetAcctID << "\n" " NotaryID: " << notaryID << "\n NymID: " << nymID << "\n " " currencyTypeID: " << currencyTypeID << "\n currencyAcctID: " << currencyAcctID << "\n "; returnVal = 1; } if (!strcmp("stopOrder", xml->getNodeName())) { String sign(xml->getAttributeValue("sign")); if (sign.Compare("0")) { stopSign_ = 0; // Zero means it isn't a stop order. So why is the // tag in the file? otErr << "Strange: Stop order tag found in trade, but sign " "character set to 0.\n" "(Zero means: NOT a stop order.)\n"; return (-1); } else if (sign.Compare("<")) stopSign_ = '<'; else if (sign.Compare(">")) stopSign_ = '>'; else { stopSign_ = 0; otErr << "Unexpected or nonexistent value in stop order sign: " << sign << "\n"; return (-1); } // Now we know the sign is properly formed, let's grab the price value. stopPrice_ = String::StringToLong(xml->getAttributeValue("price")); String activated(xml->getAttributeValue("hasActivated")); if (activated.Compare("true")) stopActivated_ = true; else stopActivated_ = false; otLog3 << "\n\nStop order -- " << (stopActivated_ ? "Already activated" : "Will activate") << " when price " << (stopActivated_ ? "was" : "reaches") << " " << (('<' == stopSign_) ? "LESS THAN" : "GREATER THAN") << ": " << stopPrice_ << ".\n"; returnVal = 1; } else if (!strcmp("offer", xml->getNodeName())) { if (!Contract::LoadEncodedTextField(xml, marketOffer_)) { otErr << "Error in OTTrade::ProcessXMLNode: offer field without " "value.\n"; return (-1); // error condition } returnVal = 1; } return returnVal; }
// THIS FUNCTION IS CALLED BY THE MERCHANT // // (lMerchantTransactionNumber, lMerchantClosingNumber are set internally in this call, from MERCHANT_NYM.) bool OTAgreement::SetProposal(OTPseudonym & MERCHANT_NYM, const OTString & strConsideration, const time_t VALID_FROM/*=0*/, const time_t VALID_TO/*=0*/) { // ---------------------------------------------------------------------------- OTIdentifier id_MERCHANT_NYM; MERCHANT_NYM.GetIdentifier(id_MERCHANT_NYM); if (GetRecipientUserID() != id_MERCHANT_NYM) { OTLog::Output(0, "OTAgreement::SetProposal: Merchant has wrong NymID (should be same as RecipientUserID.)\n"); return false; } else if (GetRecipientUserID() == GetSenderUserID()) { OTLog::Output(0, "OTAgreement::SetProposal: Error: Sender and recipient have the same Nym ID (not allowed.)\n"); return false; } else if (MERCHANT_NYM.GetTransactionNumCount(GetServerID()) < 2) // Need opening and closing numbers (that's 2)... { OTLog::Output(0, "OTAgreement::SetProposal: Failure. You need at least 2 transaction numbers available to do this.\n"); return false; } // ------------------------------------------- // Set the CREATION DATE // const time_t CURRENT_TIME = time(NULL); // Set the Creation Date. SetCreationDate(CURRENT_TIME); // ----------------------------------------- // Putting this above here so I don't have to put the transaction numbers back if this fails: // ------------------------------------------- // VALID_FROM // // The default "valid from" time is NOW. if (0 >= VALID_FROM) // if it's 0 or less, set to current time. SetValidFrom(CURRENT_TIME); else // Otherwise use whatever was passed in. SetValidFrom(VALID_FROM); // ------------------------------------------- // VALID_TO // // The default "valid to" time is 0 (which means no expiration date / cancel anytime.) if (0 == VALID_TO) // VALID_TO is 0 { SetValidTo(VALID_TO); // Keep it at zero then, so it won't expire. } else if (0 < VALID_TO) // VALID_TO is ABOVE zero... { if (VALID_TO < VALID_FROM) // If Valid-To date is EARLIER than Valid-From date... { long lValidTo = VALID_TO, lValidFrom = VALID_FROM; OTLog::vError("OTAgreement::SetProposal: VALID_TO (%ld) is earlier than VALID_FROM (%ld)\n", lValidTo, lValidFrom); return false; } SetValidTo(VALID_TO); // Set it to whatever it is, since it is now validated as higher than Valid-From. } else // VALID_TO is a NEGATIVE number... Error. { long lValidTo = VALID_TO; OTLog::vError("Negative value for valid_to in SetAgreement: %ld\n", lValidTo); return false; } // ---------------------------------------------------------------------------- // Since we'll be needing 2 transaction numbers to do this, let's grab 'em... // OTString strServerID(GetServerID()); long lTransactionNumber=0, lClosingTransactionNo=0; if (MERCHANT_NYM.GetTransactionNumCount(GetServerID()) < 2) // Need opening and closing numbers (that's 2)... { OTLog::Output(0, "OTAgreement::SetProposal: Failure. You need at least 2 transaction numbers available to do this.\n"); return false; } else if (false == MERCHANT_NYM.GetNextTransactionNum(MERCHANT_NYM, strServerID, lTransactionNumber)) { OTLog::Error("OTAgreement::SetProposal: Error: Strangely unable to get a transaction number.\n"); return false; } else if (false == MERCHANT_NYM.GetNextTransactionNum(MERCHANT_NYM, strServerID, lClosingTransactionNo)) { OTLog::Error("OTAgreement::SetProposal: Error: Strangely unable to get a closing transaction number.\n"); MERCHANT_NYM.AddTransactionNum(MERCHANT_NYM, strServerID, lTransactionNumber, true); // bSave=true // (Since the first one was successful, we just put it back before returning.) return false; } // At this point we now have 2 transaction numbers... // We can't return without either USING THEM, or PUTTING THEM BACK. // // --------------------------------------------------------- // Set the Transaction Number and the Closing transaction number... (for merchant / recipient.) // this->AddRecipientClosingTransactionNo(lTransactionNumber); this->AddRecipientClosingTransactionNo(lClosingTransactionNo); // (They just both go onto this same list.) // ------------------------------------------- // Set the Consideration memo... m_strConsideration.Set(strConsideration); // ------------------------------------------- OTLog::Output(4, "Successfully performed OTPaymentPlan::SetProposal()\n"); return true; }
// return -1 if error, 0 if nothing, and 1 if the node was processed. int OTAgreement::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { int nReturnVal = 0; // Here we call the parent class first. // If the node is found there, or there is some error, // then we just return either way. But if it comes back // as '0', then nothing happened, and we'll continue executing. // // -- Note you can choose not to call the parent if // you don't want to use any of those xml tags. // As I do below, in the case of OTAccount. if (0 != (nReturnVal = OTCronItem::ProcessXMLNode(xml))) return nReturnVal; // ------------------------------------------------- if (!strcmp("agreement", xml->getNodeName())) { m_strVersion = xml->getAttributeValue("version"); SetTransactionNum( atol(xml->getAttributeValue("transactionNum")) ); SetCreationDate( atoi(xml->getAttributeValue("creationDate"))); SetValidFrom( atoi(xml->getAttributeValue("validFrom"))); SetValidTo( atoi(xml->getAttributeValue("validTo"))); // --------------------- const OTString strServerID(xml->getAttributeValue("serverID")), strAssetTypeID(xml->getAttributeValue("assetTypeID")), strSenderAcctID(xml->getAttributeValue("senderAcctID")), strSenderUserID(xml->getAttributeValue("senderUserID")), strRecipientAcctID(xml->getAttributeValue("recipientAcctID")), strRecipientUserID(xml->getAttributeValue("recipientUserID")); const OTIdentifier SERVER_ID(strServerID), ASSET_ID(strAssetTypeID), SENDER_ACCT_ID(strSenderAcctID), SENDER_USER_ID(strSenderUserID), RECIPIENT_ACCT_ID(strRecipientAcctID), RECIPIENT_USER_ID(strRecipientUserID); SetServerID(SERVER_ID); SetAssetID(ASSET_ID); SetSenderAcctID(SENDER_ACCT_ID); SetSenderUserID(SENDER_USER_ID); SetRecipientAcctID(RECIPIENT_ACCT_ID); SetRecipientUserID(RECIPIENT_USER_ID); // --------------------- OTLog::vOutput(0, "\n\nAgreement. Transaction Number: %ld\n", m_lTransactionNum); OTLog::vOutput(1, " Creation Date: %d Valid From: %d\n Valid To: %d\n" " AssetTypeID: %s\n ServerID: %s\n" " senderAcctID: %s\n senderUserID: %s\n " " recipientAcctID: %s\n recipientUserID: %s\n ", GetCreationDate(), GetValidFrom(), GetValidTo(), strAssetTypeID.Get(), strServerID.Get(), strSenderAcctID.Get(), strSenderUserID.Get(), strRecipientAcctID.Get(), strRecipientUserID.Get()); nReturnVal = 1; } else if (!strcmp("consideration", xml->getNodeName())) { if (false == LoadEncodedTextField(xml, m_strConsideration)) { OTLog::Error("Error in OTPaymentPlan::ProcessXMLNode: consideration field without value.\n"); return (-1); // error condition } nReturnVal = 1; } else if (!strcmp("merchantSignedCopy", xml->getNodeName())) { if (false == LoadEncodedTextField(xml, m_strMerchantSignedCopy)) { OTLog::Error("Error in OTPaymentPlan::ProcessXMLNode: merchant_signed_copy field without value.\n"); return (-1); // error condition } nReturnVal = 1; } // ------------------------------------------- // std::deque<long> m_dequeRecipientClosingNumbers; // Numbers used for CLOSING a transaction. (finalReceipt.) else if (!strcmp("closingRecipientNumber", xml->getNodeName())) { OTString strClosingNumber = xml->getAttributeValue("value"); if (strClosingNumber.Exists()) { const long lClosingNumber = atol(strClosingNumber.Get()); this->AddRecipientClosingTransactionNo(lClosingNumber); } else { OTLog::Error("Error in OTAgreement::ProcessXMLNode: closingRecipientNumber field without value.\n"); return (-1); // error condition } nReturnVal = 1; } return nReturnVal; }
// return -1 if error, 0 if nothing, and 1 if the node was processed. int32_t OTOffer::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { int32_t nReturnVal = 0; // Here we call the parent class first. // If the node is found there, or there is some error, // then we just return either way. But if it comes back // as '0', then nothing happened, and we'll continue executing. // // -- Note you can choose not to call the parent if // you don't want to use any of those xml tags. // As I do below, in the case of OTAccount. //if (nReturnVal = OTContract::ProcessXMLNode(xml)) // return nReturnVal; if (!strcmp("marketOffer", xml->getNodeName())) { m_strVersion = xml->getAttributeValue("version"); OTString strIsSelling; strIsSelling = xml->getAttributeValue("isSelling"); if (strIsSelling.Compare("true")) m_bSelling = true; else m_bSelling = false; m_strContractType.Set((m_bSelling ? "ASK" : "BID")); const OTString strServerID(xml->getAttributeValue("serverID")), strAssetTypeID(xml->getAttributeValue("assetTypeID")), strCurrencyTypeID(xml->getAttributeValue("currencyTypeID")); const OTIdentifier SERVER_ID(strServerID), ASSET_ID(strAssetTypeID), CURRENCY_TYPE_ID(strCurrencyTypeID); SetServerID(SERVER_ID); SetAssetID(ASSET_ID); SetCurrencyID(CURRENCY_TYPE_ID); // ------------------------------------ const OTString strScale = xml->getAttributeValue("marketScale"); const int64_t lScale = strScale.Exists() ? atol(strScale.Get()) : 0; // if it doesn't exist, the 0 here causes the below error to fire. if (false == isPowerOfTen( lScale )) { OTLog::vOutput(0, "OTOffer::ProcessXMLNode: Failure: marketScale *must* be 1, or a power of 10. Instead I got: %lld.\n", lScale); return (-1); } else SetScale(lScale); // ------------------------------------ const OTString strPriceLimit = xml->getAttributeValue("priceLimit"); const int64_t lPriceLimit = strPriceLimit.Exists() ? atol(strPriceLimit.Get()) : 0; // if it doesn't exist, the 0 here causes the below error to fire. // NOTE: Market Orders (new) have a 0 price, so this error condition was changed. if (!strPriceLimit.Exists()) // if (lPriceLimit < 1) { OTLog::vOutput(0, "OTOffer::ProcessXMLNode: Failure: priceLimit *must* be provided.\n", lPriceLimit); return (-1); } else SetPriceLimit(lPriceLimit); // ------------------------------------ const OTString strTotal = xml->getAttributeValue("totalAssetsOnOffer"); const int64_t lTotal = strTotal.Exists() ? atol(strTotal.Get()) : 0; // if it doesn't exist, the 0 here causes the below error to fire. if (lTotal < 1) { OTLog::vOutput(0, "OTOffer::ProcessXMLNode: Failure: totalAssetsOnOffer *must* be larger than 0. Instead I got: %lld.\n", lTotal); return (-1); } else SetTotalAssetsOnOffer(lTotal); // ------------------------------------ const OTString strFinished = xml->getAttributeValue("finishedSoFar"); const int64_t lFinished = strFinished.Exists() ? atol(strFinished.Get()) : 0; // if it doesn't exist, the 0 here causes the below error to fire. if (lFinished < 0) { OTLog::vOutput(0, "OTOffer::ProcessXMLNode: Failure: finishedSoFar *must* be 0 or larger. Instead I got: %lld.\n", lFinished); return (-1); } else SetFinishedSoFar(lFinished); // ------------------------------------ const OTString strMinInc = xml->getAttributeValue("minimumIncrement"); const int64_t lMinInc = strMinInc.Exists() ? atol(strMinInc.Get()) : 0; // if it doesn't exist, the 0 here causes the below error to fire. if ((lMinInc < 1) || (lMinInc > lTotal)) // Minimum increment cannot logically be higher than the total assets on offer... { OTLog::vOutput(0, "OTOffer::ProcessXMLNode: Failure: minimumIncrement *must* be 1 or larger, \n" "and must also be less than the total assets on offer. Instead I got: %lld.\n", lMinInc); return (-1); } else SetMinimumIncrement(lMinInc); // ----------------------------------- const OTString strTransNum = xml->getAttributeValue("transactionNum"); const int64_t lTransNum = strTransNum.Exists() ? atol(strTransNum.Get()) : 0; SetTransactionNum(lTransNum); // ---------------------------------------------------------------- const OTString str_valid_from = xml->getAttributeValue("validFrom"); const OTString str_valid_to = xml->getAttributeValue("validTo"); int64_t tValidFrom = str_valid_from.Exists() ? str_valid_from.ToLong() : 0; int64_t tValidTo = str_valid_to.Exists () ? str_valid_to.ToLong() : 0; if ((tValidTo < tValidFrom) && (tValidTo != 0)) { OTLog::vOutput(0, "OTOffer::%s: Failure: validTo date (%" PRId64") cannot be earlier than " "validFrom date (%" PRId64").\n", __FUNCTION__, tValidFrom, tValidTo); return (-1); } // ---------------------------------------------------------------- SetValidFrom(OTTimeGetTimeFromSeconds(tValidFrom)); SetValidTo(OTTimeGetTimeFromSeconds(tValidTo)); // ---------------------------------------------------------------- OTLog::vOutput(4, "\n\nOffer. Transaction Number: %lld\n Valid From: %" PRId64"\n Valid To: %" PRId64"\n" " AssetTypeID: %s\n CurrencyTypeID: %s\n ServerID: %s\n" " Price Limit: %lld, Total Assets on Offer: %lld, %s so far: %lld\n " " Scale: %lld. Minimum Increment: %lld. This offer is a%s.\n", m_lTransactionNum, tValidFrom, tValidTo, strAssetTypeID.Get(), strCurrencyTypeID.Get(), strServerID.Get(), GetPriceLimit(), GetTotalAssetsOnOffer(), (m_bSelling ? "sold" : "bought"), GetFinishedSoFar(), GetScale(), GetMinimumIncrement(), (m_bSelling ? "n ASK" : " BID")); // ---------------------------------------------------------------- nReturnVal = 1; } // ---------------- return nReturnVal; }
// return -1 if error, 0 if nothing, and 1 if the node was processed. int32_t OTOffer::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { int32_t nReturnVal = 0; // Here we call the parent class first. // If the node is found there, or there is some error, // then we just return either way. But if it comes back // as '0', then nothing happened, and we'll continue executing. // // -- Note you can choose not to call the parent if // you don't want to use any of those xml tags. // As I do below, in the case of OTAccount. // if (nReturnVal = Contract::ProcessXMLNode(xml)) // return nReturnVal; if (!strcmp("marketOffer", xml->getNodeName())) { m_strVersion = xml->getAttributeValue("version"); String strIsSelling; strIsSelling = xml->getAttributeValue("isSelling"); if (strIsSelling.Compare("true")) m_bSelling = true; else m_bSelling = false; m_strContractType.Set((m_bSelling ? "ASK" : "BID")); const String strNotaryID(xml->getAttributeValue("notaryID")), strInstrumentDefinitionID( xml->getAttributeValue("instrumentDefinitionID")), strCurrencyTypeID(xml->getAttributeValue("currencyTypeID")); const Identifier NOTARY_ID(strNotaryID), INSTRUMENT_DEFINITION_ID(strInstrumentDefinitionID), CURRENCY_TYPE_ID(strCurrencyTypeID); SetNotaryID(NOTARY_ID); SetInstrumentDefinitionID(INSTRUMENT_DEFINITION_ID); SetCurrencyID(CURRENCY_TYPE_ID); const String strScale = xml->getAttributeValue("marketScale"); const int64_t lScale = strScale.Exists() ? strScale.ToLong() : 0; // if it doesn't exist, // the 0 here causes the // below error to fire. if (!isPowerOfTen(lScale)) { otOut << "OTOffer::ProcessXMLNode: Failure: marketScale *must* be " "1, or a power of 10. Instead I got: " << lScale << ".\n"; return (-1); } else SetScale(lScale); const String strPriceLimit = xml->getAttributeValue("priceLimit"); const int64_t lPriceLimit = strPriceLimit.Exists() ? strPriceLimit.ToLong() : 0; // if it doesn't exist, the 0 here // causes the below error to fire. // NOTE: Market Orders (new) have a 0 price, so this error condition was // changed. if (!strPriceLimit.Exists()) // if (lPriceLimit < 1) { otOut << "OTOffer::ProcessXMLNode: Failure: priceLimit *must* be " "provided(" << lPriceLimit << ").\n"; return (-1); } else SetPriceLimit(lPriceLimit); const String strTotal = xml->getAttributeValue("totalAssetsOnOffer"); const int64_t lTotal = strTotal.Exists() ? strTotal.ToLong() : 0; // if it doesn't exist, // the 0 here causes the // below error to fire. if (lTotal < 1) { otOut << "OTOffer::ProcessXMLNode: Failure: totalAssetsOnOffer " "*must* be larger than 0. Instead I got: " << lTotal << ".\n"; return (-1); } else SetTotalAssetsOnOffer(lTotal); const String strFinished = xml->getAttributeValue("finishedSoFar"); const int64_t lFinished = strFinished.Exists() ? strFinished.ToLong() : 0; // if it doesn't exist, the 0 here // causes the below error to fire. if (lFinished < 0) { otOut << "OTOffer::ProcessXMLNode: Failure: finishedSoFar *must* " "be 0 or larger. Instead I got: " << lFinished << ".\n"; return (-1); } else SetFinishedSoFar(lFinished); const String strMinInc = xml->getAttributeValue("minimumIncrement"); // if it doesn't exist, the 0 here causes the below error to fire. const int64_t lMinInc = strMinInc.Exists() ? strMinInc.ToLong() : 0; if ((lMinInc < 1) || (lMinInc > lTotal)) // Minimum increment cannot // logically be higher than the // total assets on offer... { otOut << "OTOffer::ProcessXMLNode: Failure: minimumIncrement " "*must* be 1 or larger, \n" "and must also be less than the total assets on offer. " "Instead I got: " << lMinInc << ".\n"; return (-1); } else SetMinimumIncrement(lMinInc); const String strTransNum = xml->getAttributeValue("transactionNum"); const int64_t lTransNum = strTransNum.Exists() ? strTransNum.ToLong() : 0; SetTransactionNum(lTransNum); const String str_valid_from = xml->getAttributeValue("validFrom"); const String str_valid_to = xml->getAttributeValue("validTo"); int64_t tValidFrom = str_valid_from.Exists() ? parseTimestamp(str_valid_from.Get()) : 0; int64_t tValidTo = str_valid_to.Exists() ? parseTimestamp(str_valid_to.Get()) : 0; if ((tValidTo < tValidFrom) && (tValidTo != 0)) { otOut << "OTOffer::" << __FUNCTION__ << ": Failure: validTo date (" << tValidFrom << ") cannot be earlier than " "validFrom date (" << tValidTo << ").\n"; return (-1); } SetValidFrom(OTTimeGetTimeFromSeconds(tValidFrom)); SetValidTo(OTTimeGetTimeFromSeconds(tValidTo)); otLog4 << "\n\nOffer. Transaction Number: " << m_lTransactionNum << "\n Valid From: " << tValidFrom << "\n Valid To: " << tValidTo << "\n" " InstrumentDefinitionID: " << strInstrumentDefinitionID << "\n CurrencyTypeID: " << strCurrencyTypeID << "\n NotaryID: " << strNotaryID << "\n" " Price Limit: " << GetPriceLimit() << ", Total Assets on Offer: " << GetTotalAssetsOnOffer() << ", " << (m_bSelling ? "sold" : "bought") << " so far: " << GetFinishedSoFar() << "\n " " Scale: " << GetScale() << ". Minimum Increment: " << GetMinimumIncrement() << ". This offer is a" << (m_bSelling ? "n ASK" : " BID") << ".\n"; nReturnVal = 1; } return nReturnVal; }
// return -1 if error, 0 if nothing, and 1 if the node was processed. int32_t Cheque::ProcessXMLNode(IrrXMLReader*& xml) { int32_t nReturnVal = 0; // Here we call the parent class first. // If the node is found there, or there is some error, // then we just return either way. But if it comes back // as '0', then nothing happened, and we'll continue executing. // // -- Note you can choose not to call the parent if // you don't want to use any of those xml tags. // As I do below, in the case of OTAccount. // if (nReturnVal = Contract::ProcessXMLNode(xml)) // return nReturnVal; if (!strcmp("cheque", xml->getNodeName())) { String strHasRecipient = xml->getAttributeValue("hasRecipient"); m_bHasRecipient = strHasRecipient.Compare("true"); String strHasRemitter = xml->getAttributeValue("hasRemitter"); m_bHasRemitter = strHasRemitter.Compare("true"); m_strVersion = xml->getAttributeValue("version"); m_lAmount = String::StringToLong(xml->getAttributeValue("amount")); SetTransactionNum( String::StringToLong(xml->getAttributeValue("transactionNum"))); const std::string str_valid_from = xml->getAttributeValue("validFrom"); const std::string str_valid_to = xml->getAttributeValue("validTo"); SetValidFrom(parseTimestamp(str_valid_from)); SetValidTo(parseTimestamp(str_valid_to)); String strInstrumentDefinitionID( xml->getAttributeValue("instrumentDefinitionID")), strNotaryID(xml->getAttributeValue("notaryID")), strSenderAcctID(xml->getAttributeValue("senderAcctID")), strSenderNymID(xml->getAttributeValue("senderNymID")), strRecipientNymID(xml->getAttributeValue("recipientNymID")), strRemitterNymID(xml->getAttributeValue("remitterNymID")), strRemitterAcctID(xml->getAttributeValue("remitterAcctID")); Identifier INSTRUMENT_DEFINITION_ID(strInstrumentDefinitionID), NOTARY_ID(strNotaryID), SENDER_ACCT_ID(strSenderAcctID), SENDER_NYM_ID(strSenderNymID); SetInstrumentDefinitionID(INSTRUMENT_DEFINITION_ID); SetNotaryID(NOTARY_ID); SetSenderAcctID(SENDER_ACCT_ID); SetSenderNymID(SENDER_NYM_ID); // Recipient ID if (m_bHasRecipient) m_RECIPIENT_NYM_ID.SetString(strRecipientNymID); else m_RECIPIENT_NYM_ID.Release(); // Remitter ID (for vouchers) if (m_bHasRemitter) { m_REMITTER_NYM_ID.SetString(strRemitterNymID); m_REMITTER_ACCT_ID.SetString(strRemitterAcctID); } else { m_REMITTER_NYM_ID.Release(); m_REMITTER_ACCT_ID.Release(); } otInfo << "\n\nCheque Amount: " << m_lAmount << ". Transaction Number: " << m_lTransactionNum << "\n Valid From: " << str_valid_from << "\n Valid To: " << str_valid_to << "\n InstrumentDefinitionID: " << strInstrumentDefinitionID << "\n NotaryID: " << strNotaryID << "\n" " senderAcctID: " << strSenderAcctID << "\n senderNymID: " << strSenderNymID << "\n " " Has Recipient? " << (m_bHasRecipient ? "Yes" : "No") << ". If yes, NymID of Recipient: " << strRecipientNymID << "\n" " Has Remitter? " << (m_bHasRemitter ? "Yes" : "No") << ". If yes, NymID/Acct of Remitter: " << strRemitterNymID << " / " << strRemitterAcctID << "\n"; nReturnVal = 1; } else if (!strcmp("memo", xml->getNodeName())) { if (!Contract::LoadEncodedTextField(xml, m_strMemo)) { otErr << "Error in OTCheque::ProcessXMLNode: memo field without " "value.\n"; return (-1); // error condition } return 1; } return nReturnVal; }