// OTCron IS responsible for cleaning up theMarket, and takes ownership. // So make SURE it is allocated on the HEAP before you pass it in here, and // also make sure to delete it again if this call fails! bool OTCron::AddMarket(OTMarket & theMarket, bool bSaveMarketFile/*=true*/) { OT_ASSERT(NULL != GetServerNym()); theMarket.SetCronPointer(*this); // This way every Market has a pointer to Cron. OTIdentifier MARKET_ID(theMarket); OTString str_MARKET_ID(MARKET_ID); std::string std_MARKET_ID = str_MARKET_ID.Get(); // See if there's something else already there with the same market ID. mapOfMarkets::iterator ii = m_mapMarkets.find(std_MARKET_ID); // If it's not already on the list, then add it... if ( ii == m_mapMarkets.end() ) { // If I've been instructed to save the market, and Cron did NOT successfully save the market // (to its own file), then return false. This will happen if filesystem problems. if (bSaveMarketFile && !theMarket.SaveMarket()) { OTLog::vError("Error saving market file while adding new Market to Cron:\n%s\n", std_MARKET_ID.c_str()); return false; } m_mapMarkets[std_MARKET_ID] = &theMarket; bool bSuccess = true; // When Cron serializes, it stores a list of all its markets in the main cron file. // The actual markets themselves serialize separately to the market folder. // if (bSaveMarketFile) // This executes only the first time that a market is added to Cron. // (versus when it's just being reloaded from file and added back to the internal list.) { // Since we added a market to the Cron, we SAVE it. bSuccess = SaveCron(); // If we're loading from file, and bSaveMarketFile is false, I don't want to save here. that's why it's in this block. if (bSuccess) OTLog::Output(3, "New Market has been added to Cron.\n"); else OTLog::Error("Error saving while adding new Market to Cron.\n"); } return bSuccess; } // Otherwise, if it was already there, log an error. else { OTLog::vError("Attempt to add Market that was already there: %s\n", std_MARKET_ID.c_str()); } return false; }
// return -1 if error, 0 if nothing, and 1 if the node was processed. int OTCron::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { OT_ASSERT(NULL != GetServerNym()); 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 (nReturnVal = OTContract::ProcessXMLNode(xml)) // return nReturnVal; if (!strcmp("cron", xml->getNodeName())) { m_strVersion = xml->getAttributeValue("version"); // --------------------- const OTString strServerID(xml->getAttributeValue("serverID")); m_SERVER_ID.SetString(strServerID); // --------------------- OTLog::vOutput(0, "\n\nLoading an OTCron object. ServerID:\n%s\n", strServerID.Get()); nReturnVal = 1; } else if (!strcmp("transactionNum", xml->getNodeName())) { long lTransactionNum = 0; lTransactionNum = atol(xml->getAttributeValue("value")); OTLog::vOutput(1, "Transaction Number %ld available for Cron.\n", lTransactionNum); AddTransactionNumber(lTransactionNum); // This doesn't save to disk. Make sure to save Cron when it changes. nReturnVal = 1; } else if (!strcmp("cronItem", xml->getNodeName())) { OTString strData; if (!LoadEncodedTextField(xml, strData) || !strData.Exists()) { OTLog::Error("Error in OTCron::ProcessXMLNode: cronItem field without value.\n"); return (-1); // error condition } else { OTCronItem * pItem = OTCronItem::NewCronItem(strData); if (NULL == pItem) { OTLog::Error("Unable to create cron item from data in cron file.\n"); return (-1); } if (AddCronItem(*pItem, false)) // bSaveReceipt=false. The receipt is only saved once: When item FIRST added to cron. { // But here, the item was ALREADY in cron, and is merely being loaded from disk. Thus, // it would be wrong to try to create the "original record" as if it were brand new // and still had the user's signature on it. (Once added to Cron, the signatures are // released and the SERVER signs it from there. That's why the user's version is saved // as a receipt in the first place -- so we have a record of the user's authorization.) OTLog::Output(2, "Successfully loaded cron item and added to list.\n"); } else { OTLog::Error("Though loaded successfully, unable to add cron item (from cron file) to cron list.\n"); delete pItem; pItem = NULL; return (-1); } } nReturnVal = 1; } else if (!strcmp("market", xml->getNodeName())) { const OTString strMarketID(xml->getAttributeValue("marketID")); const OTString strAssetID(xml->getAttributeValue("assetID")); const OTString strCurrencyID(xml->getAttributeValue("currencyID")); const long lScale = atol(xml->getAttributeValue("marketScale")); const OTIdentifier ASSET_ID(strAssetID), CURRENCY_ID(strCurrencyID); OTLog::vOutput(1, "Loaded cron entry for Market:\n%s.\n", strMarketID.Get()); // LoadMarket() needs this info to do its thing. OTMarket * pMarket = new OTMarket(m_SERVER_ID, ASSET_ID, CURRENCY_ID, lScale); OT_ASSERT(NULL != pMarket); pMarket->SetCronPointer(*this); // This way every Market has a pointer to Cron. // AddMarket normally saves to file, but we don't want that when we're LOADING from file, now do we? if (!pMarket->LoadMarket() || !pMarket->VerifySignature(*GetServerNym()) || !AddMarket(*pMarket, false)) // bSaveFile=false: don't save this file WHILE loading it!!! { OTLog::Error("Somehow error while loading, verifying, or adding market while loading Cron file.\n"); delete pMarket; pMarket = NULL; return (-1); } else { OTLog::Output(1, "Loaded market entry from cronfile, and also loaded the market file itself.\n"); } nReturnVal = 1; } return nReturnVal; }