// Use a local variable for theToken, do NOT allocate it on the heap // unless you are going to delete it yourself. // Repeat: OTPurse is NOT responsible to delete it. We create our OWN internal // variable here, new that, and add it to the stack. We do not add the one passed in. bool OTPurse::Push(const OTPseudonym & theOwner, const OTToken & theToken) { if (theToken.GetAssetID() == m_AssetID) { OTString strToken(theToken); // OTLog::vError("$$$$$$$$$$$$$$$ PUSHING token to Purse:\n---------->%s<-------------\n", strToken.Get()); OTEnvelope theEnvelope; theEnvelope.Seal(theOwner, strToken); OTASCIIArmor * pArmor = new OTASCIIArmor(theEnvelope); // OTLog::vError("$$$$$$$$$$$$$$$ PUSHING token to Purse in armored form:\n---------->%s<-------------\n", // pArmor->Get()); m_dequeTokens.push_front(pArmor); // We keep track of the purse's total value. m_lTotalValue += theToken.GetDenomination(); return true; } else { OTString strPurseAssetType(m_AssetID), strTokenAssetType(theToken.GetAssetID()); OTLog::vError("ERROR: Tried to push token with wrong asset type in OTPurse::Push\nPurse Asset Type:\n%s\n" "Token Asset Type:\n%s\n", strPurseAssetType.Get(), strTokenAssetType.Get()); return false; } }
// Hypocritically (compared to Push) in the case of Pop(), we DO // allocate a OTToken and return the pointer. The caller IS // responsible to delete it when he's done with it. // // The apparent discrepancy is due to the fact that internally, // we aren't storing the token object but an encrypted string of it. // But this is hidden from the user of the purse, who perceives only // that he is passing tokens in and getting them back out again. OTToken * OTPurse::Pop(const OTPseudonym & theOwner) { if (m_dequeTokens.empty()) return NULL; // Grab a copy of the pointer and remove it from the deque OTASCIIArmor * pArmor = m_dequeTokens.front(); m_dequeTokens.pop_front(); // OTLog::vError("$$$$$$$$$$$$$$ ARMORED TEXT in PURSE POP:\n--------->%s<-----------\n", pArmor->Get()); // Copy the token contents into an Envelope, and delete the pointer. OTEnvelope theEnvelope(*pArmor); delete pArmor; pArmor = NULL; // Open the envelope into a string. OTString strToken; theEnvelope.Open(theOwner, strToken); // OTLog::vError("$$$$$$$$$$$$$$$ OPENED ENVELOPE TEXT in PURSE POP:\n--------->%s<-----------\n", strToken.Get()); // Create a new token with the same server and asset IDs as this purse. OTToken * pToken = new OTToken(*this); OT_ASSERT(NULL != pToken); // Load the token from the string we got out of the envelope. pToken->LoadContractFromString(strToken); if (pToken->GetAssetID() != m_AssetID || pToken->GetServerID() != m_ServerID) { delete pToken; pToken = NULL; OTLog::Error("ERROR: Token with wrong asset type in OTPurse::Pop\n"); } else { // We keep track of the purse's total value. m_lTotalValue -= pToken->GetDenomination(); } // CALLER is responsible to delete this token. return pToken; }