// This function will base64 ENCODE theData, // and then Set() that as the string contents. // Additionally it will pack and compress the data! // bool OTASCIIArmor::SetAndPackData(const OTData & theData, bool bLineBreaks/*=true*/) { char * pString = NULL; Release(); if (theData.GetSize() < 1) return true; // -------------------------------------------------------- OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // Here I use the default storage context to create the object (the blob.) // I also originally created OTASCIIArmor::GetPacker() using OTDB_DEFAULT_PACKER, // so I know everything is compatible. // OTDB::Blob * pBlob = dynamic_cast<OTDB::Blob *>(OTDB::CreateObject(OTDB::STORED_OBJ_BLOB)); OT_ASSERT(NULL != pBlob); // Beyond this point, responsible to delete pBlob. OTCleanup<OTDB::Blob> theBlobAngel(*pBlob); // make sure memory is cleaned up. // ---------------------------- pBlob->m_memBuffer.assign(static_cast<const unsigned char *>(theData.GetPointer()), static_cast<const unsigned char *>(theData.GetPointer())+theData.GetSize()); OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pBlob); // Now we PACK our data before compressing/encoding it. if (NULL == pBuffer) { OTLog::Error("Failed packing data in OTASCIIArmor::SetAndPackData. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- const uint8_t* pUint = static_cast<const uint8_t*>(pBuffer->GetData()); const size_t theSize = pBuffer->GetSize(); if (NULL != pUint) pString = OTCrypto::It()->Base64Encode(pUint, static_cast<int>(theSize), bLineBreaks); // pString = OT_base64_encode(pUint, static_cast<int> (theSize), (bLineBreaks ? 1 : 0)); else { OTLog::Error("Error while base64_encoding in OTASCIIArmor::SetAndPackData.\n"); return false; } // ------------------------------------- if (NULL != pString) { Set(pString); delete [] pString; pString=NULL; return true; } else { OTLog::Error("Error while base64_encoding in OTASCIIArmor::SetAndPackData.\n"); return false; } }
/// This function first Packs the incoming string, using whatever is the default packer. (MsgPack or Protobuf). /// Then it Compresses the packed binary data using zlib. (ezcompress.) /// Then it Base64-Encodes the compressed binary and sets it as a string on THIS OBJECT. /// /// I added these pieces 1-by-1 over time. At first the messages were too long, so I started compressing them. /// Then they were not binary compatible across various platforms, so I added the packing. // bool OTASCIIArmor::SetAndPackString(const OTString & strData, bool bLineBreaks) //=true { Release(); if (strData.GetLength() < 1) return true; // -------------------------------------------------------- OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // Here I use the default storage context to create the object (the blob.) // I also originally created OTASCIIArmor::GetPacker() using OTDB_DEFAULT_PACKER, // so I know everything is compatible. // OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING)); OT_ASSERT(NULL != pOTDBString); // Beyond this point, responsible to delete pString. OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // make sure memory is cleaned up. // ----------------------------- const uint32_t theStringSize32 = strData.GetLength(); const size_t theStringSize = theStringSize32; // might need a cast here. // todo make sure this will handle sizes as big as I need. pOTDBString->m_string.assign(strData.Get(), // const char * theStringSize); OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pOTDBString); // Now we PACK our string before compressing/encoding it. if (NULL == pBuffer) { OTLog::Error("Failed packing string in OTASCIIArmor::SetAndPackString. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- const uint8_t* pUint = static_cast<const uint8_t*>(pBuffer->GetData()); const size_t theSize = pBuffer->GetSize(); // -------------------------------------------------------- char * pString = NULL; // Set up source buffer and destination buffer long nDestLen = DEFAULT_BUFFER_SIZE_EASYZLIB; // todo stop hardcoding numbers (but this one is OK I think.) const long lSourcelen = static_cast<long> (theSize); unsigned char* pSource = new unsigned char[lSourcelen+10]; // for safety unsigned char* pDest = new unsigned char[nDestLen +10]; // for safety OT_ASSERT(NULL != pSource); OT_ASSERT(NULL != pDest); OTPassword::zeroMemory(pSource, lSourcelen+10); OTPassword::zeroMemory(pDest, nDestLen +10); // void * OTPassword::safe_memcpy(void * dest, // uint32_t dest_size, // const // void * src, // uint32_t src_length, // bool bZeroSource/*=false*/) // if true, sets the source buffer to zero after copying is done. OTPassword::safe_memcpy(pSource, lSourcelen, pUint, static_cast<uint32_t>(theSize)); // Now we are compressing first before base64-encoding (for strings, anyway) int nErr = ezcompress( pDest, &nDestLen, pSource, lSourcelen ); // If the destination buffer wasn't the right size the first time around, // then we re-allocate it to the right size (which we now know) and try again... if ( nErr == EZ_BUF_ERROR ) { delete [] pDest; pDest = new unsigned char [nDestLen+10]; // enough room now OT_ASSERT(NULL != pDest); OTPassword::zeroMemory(pDest, nDestLen+10); nErr = ezcompress( pDest, &nDestLen, pSource, lSourcelen ); } // Clean this up... delete [] pSource; pSource = NULL; // Still errors? if ( nErr == EZ_BUF_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("Error allocating memory in OTASCIIArmor::SetAndPackString\n"); } else if ( nErr == EZ_STREAM_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG( "pDest is NULL in OTASCIIArmor::SetAndPackString\n"); } else if ( nErr == EZ_DATA_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("corrupted pSrc passed to ezuncompress OTASCIIArmor::SetAndPackString\n"); } else if ( nErr == EZ_MEM_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("Out of memory in OTASCIIArmor::SetAndPackString\n"); } OT_ASSERT_MSG(pDest != NULL, "pDest NULL in OTASCIIArmor::SetAndPackString\n"); // Success if (0 < nDestLen) { // Now let's base-64 encode it... pString = OTCrypto::It()->Base64Encode((const uint8_t*)pDest, nDestLen, bLineBreaks); // pString = OT_base64_encode((const uint8_t*)pDest, nDestLen, (bLineBreaks ? 1 : 0)); delete [] pDest; pDest = NULL; if (pString) { Set(pString); delete [] pString; pString=NULL; return true; } else { OTLog::Error("pString NULL in OTASCIIArmor::SetAndPackString\n"); } } else { OTLog::Error("nDestLen 0 in OTASCIIArmor::SetAndPackString\n"); } if (pDest) delete [] pDest; pDest = NULL; return false; }
bool OTCron::GetMarketList (OTASCIIArmor & ascOutput, int & nMarketCount) { nMarketCount = 0; // This parameter is set to zero here, and incremented in the loop below. // ------------------------ OTMarket * pMarket = NULL; OTDB::MarketList * pMarketList = dynamic_cast<OTDB::MarketList*>(OTDB::CreateObject(OTDB::STORED_OBJ_MARKET_LIST)); OTCleanup<OTDB::MarketList> theListAngel(*pMarketList); // ----------------------------------------------------------- for (mapOfMarkets::iterator ii = m_mapMarkets.begin(); ii != m_mapMarkets.end(); ++ii) { pMarket = (*ii).second; OT_ASSERT(NULL != pMarket); OTDB::MarketData * pMarketData = dynamic_cast<OTDB::MarketData *>(OTDB::CreateObject(OTDB::STORED_OBJ_MARKET_DATA)); OTCleanup<OTDB::MarketData> theDataAngel(*pMarketData); // -------------------------------------------- const OTIdentifier MARKET_ID(*pMarket); const OTString str_MARKET_ID(MARKET_ID); const OTString str_ServerID(pMarket->GetServerID()); const OTString str_ASSET_ID(pMarket->GetAssetID()); const OTString str_CURRENCY_ID(pMarket->GetCurrencyID()); pMarketData->server_id = str_ServerID.Get(); pMarketData->market_id = str_MARKET_ID.Get(); pMarketData->asset_type_id = str_ASSET_ID.Get(); pMarketData->currency_type_id = str_CURRENCY_ID.Get(); // -------------------------------------------- const long & lScale = pMarket->GetScale(); pMarketData->scale = to_string<long>(lScale); // -------------------------------------------- const uint64_t theCurrentBid = pMarket->GetHighestBidPrice(); const uint64_t theCurrentAsk = pMarket->GetLowestAskPrice(); pMarketData->current_bid = to_string<uint64_t>(theCurrentBid); pMarketData->current_ask = to_string<uint64_t>(theCurrentAsk); // --------------------------------------------- const long & lLastSalePrice = pMarket->GetLastSalePrice(); const long & lTotalAvailableAssets = pMarket->GetTotalAvailableAssets(); pMarketData->total_assets = to_string<long>(lTotalAvailableAssets); pMarketData->last_sale_price = to_string<long>(lLastSalePrice); // --------------------------------------------- const mapOfOffers::size_type theBidCount = pMarket->GetBidCount(); const mapOfOffers::size_type theAskCount = pMarket->GetAskCount(); pMarketData->number_bids = to_string<mapOfOffers::size_type>(theBidCount); pMarketData->number_asks = to_string<mapOfOffers::size_type>(theAskCount); // --------------------------------------------- // In the past 24 hours. // (I'm not collecting this data yet, (maybe never), so these values aren't set at all.) // // pMarketData->volume_trades = ???; // pMarketData->volume_assets = ???; // pMarketData->volume_currency = ???; // // pMarketData->recent_highest_bid = ???; // pMarketData->recent_lowest_ask = ???; // --------------------------------------------- // *pMarketData is CLONED at this time (I'm still responsible to delete.) // That's also why I add it here, below: So the data is set right before the cloning occurs. // pMarketList->AddMarketData(*pMarketData); nMarketCount++; } // ------------------------------------------------------------- // Now pack the list into strOutput... if (nMarketCount == 0) return true; // Success, but the list contains 0 markets. else if (nMarketCount > 0) { OTDB::Storage * pStorage = OTDB::GetDefaultStorage(); OT_ASSERT(NULL != pStorage); OTDB::OTPacker * pPacker = pStorage->GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // ----------------------------- OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pMarketList); // Now we PACK our market list. if (NULL == pBuffer) { OTLog::Error("Failed packing pMarketList in OTCron::GetMarketList. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- // Now we need to translate pBuffer into strOutput. const uint8_t* pUint = static_cast<const uint8_t*>(pBuffer->GetData()); const size_t theSize = pBuffer->GetSize(); if ((theSize > 0) && (NULL != pUint)) { OTData theData(pUint, theSize); // This function will base64 ENCODE theData, // and then Set() that as the string contents. ascOutput.SetData(theData); // bool bSuccessSetData = false; // bSuccessSetData = ascOutput.SetData(theData); return true; } else OTLog::Error("OTCron::GetMarketList: 0 size, or null return value, while getting raw data from packed buffer.\n"); } else OTLog::vError("OTCron::GetMarketList: nMarketCount is less than zero: %d.\n", nMarketCount); return false; }
// Loops through ALL markets, and calls pMarket->GetNym_OfferList(NYM_ID, *pOfferList) for each. // Returns a list of all the offers that a specific Nym has on all the markets. // bool OTCron::GetNym_OfferList(OTASCIIArmor & ascOutput, const OTIdentifier & NYM_ID, int & nOfferCount) { nOfferCount = 0; // Outputs the number of offers on this nym. // --------------------------- OTDB::OfferListNym * pOfferList = dynamic_cast<OTDB::OfferListNym*>(OTDB::CreateObject(OTDB::STORED_OBJ_OFFER_LIST_NYM)); OTCleanup<OTDB::OfferListNym> theListAngel(*pOfferList); // ----------------------------------------------------------- for (mapOfMarkets::iterator ii = m_mapMarkets.begin(); ii != m_mapMarkets.end(); ++ii) { OTMarket * pMarket = (*ii).second; OT_ASSERT(NULL != pMarket); int nNymOfferCount = 0; if (false == pMarket->GetNym_OfferList(NYM_ID, *pOfferList, nNymOfferCount)) // appends to *pOfferList, each iteration. { // may wish to add a log later. Anyway, keep iterationg and appending, then send back whatever we have. } else // Success! nOfferCount += nNymOfferCount; } // ------------------------------------------------------------- // Now pack the list into strOutput... if (nOfferCount == 0) return true; // Success, but 0 offers being returned. (List is empty.) else if (nOfferCount > 0) { OTDB::Storage * pStorage = OTDB::GetDefaultStorage(); OT_ASSERT(NULL != pStorage); OTDB::OTPacker * pPacker = pStorage->GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // ----------------------------- OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pOfferList); // Now we PACK our nym's offer list. if (NULL == pBuffer) { OTLog::Error("Failed packing pOfferList in OTCron::GetNym_OfferList. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- // Now we need to translate pBuffer into strOutput. const uint8_t* pUint = static_cast<const uint8_t*>(pBuffer->GetData()); const size_t theSize = pBuffer->GetSize(); if ((NULL != pUint) || (theSize < 2)) { OTData theData(pUint, theSize); // This function will base64 ENCODE theData, // and then Set() that as the string contents. ascOutput.SetData(theData); return true; } else OTLog::Error("Null returned, or bad size, while getting buffer data in OTCron::GetNym_OfferList.\n"); } else OTLog::vError("Error: Less-than-zero nOfferCount in OTCron::GetNym_OfferList: %d.\n", nOfferCount); return false; }
bool OTASCIIArmor::SetAndPackStringMap(const std::map<std::string, std::string> & the_map, bool bLineBreaks/*=true*/) { char * pString = NULL; Release(); if (the_map.size() < 1) return true; // -------------------------------------------------------- OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // Here I use the default storage context to create the object (the string map.) // I also originally created OTASCIIArmor::GetPacker() using OTDB_DEFAULT_PACKER, // so I know everything is compatible. // OTDB::StringMap * pStringMap = dynamic_cast<OTDB::StringMap *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING_MAP)); OT_ASSERT(NULL != pStringMap); // Beyond this point, responsible to delete pStringMap. OTCleanup<OTDB::StringMap> theMapAngel(*pStringMap); // make sure memory is cleaned up. // ----------------------------- pStringMap->the_map = the_map; // ----------------------------- OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pStringMap); // Now we PACK our data before compressing/encoding it. if (NULL == pBuffer) { OTLog::Error("Failed packing data in OTASCIIArmor::SetAndPackStringMap. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- const uint8_t* pUint = static_cast<const uint8_t*>(pBuffer->GetData()); const size_t theSize = pBuffer->GetSize(); if (NULL != pUint) pString = OT_base64_encode(pUint, theSize, (bLineBreaks ? 1 : 0)); else { OTLog::Error("Error while base64_encoding in OTASCIIArmor::SetAndPackStringMap.\n"); return false; } // ------------------------------------- if (NULL != pString) { Set(pString); delete [] pString; pString=NULL; return true; } else { OTLog::Error("Error while base64_encoding in OTASCIIArmor::SetAndPackStringMap.\n"); return false; } }
/// This function first Packs the incoming string, using whatever is the default packer. (MsgPack or Protobuf). /// Then it Compresses the packed binary data using zlib. (ezcompress.) /// Then it Base64-Encodes the compressed binary and sets it as a string on THIS OBJECT. /// /// I added these pieces 1-by-1 over time. At first the messages were too int64_t, so I started compressing them. /// Then they were not binary compatible across various platforms, so I added the packing. // bool OTASCIIArmor::SetAndPackString(const OTString & strData, bool bLineBreaks) //=true { Release(); if (strData.GetLength() < 1) return true; // -------------------------------------------------------- OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // Here I use the default storage context to create the object (the blob.) // I also originally created OTASCIIArmor::GetPacker() using OTDB_DEFAULT_PACKER, // so I know everything is compatible. // OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING)); OT_ASSERT(NULL != pOTDBString); // Beyond this point, responsible to delete pString. OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // make sure memory is cleaned up. // ----------------------------- const uint32_t theStringSize32 = strData.GetLength(); const size_t theStringSize = theStringSize32; // might need a cast here. // todo make sure this will handle sizes as big as I need. pOTDBString->m_string.assign(strData.Get(), // const char * theStringSize); OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pOTDBString); // Now we PACK our string before compressing/encoding it. if (NULL == pBuffer) { OTLog::Error("Failed packing string in OTASCIIArmor::SetAndPackString. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- std::string str_packed(reinterpret_cast<const char *>(pBuffer->GetData()), pBuffer->GetSize()); std::string str_compressed = compress_string( str_packed ); // Success if (str_compressed.size()) { // Now let's base-64 encode it... // TODO: remove static cast, add check for longer than 'int32_t' length? (da2ce7) char * pString = OTCrypto::It()->Base64Encode((const uint8_t*)(str_compressed.data()), static_cast<int32_t>(str_compressed.size()), bLineBreaks); if (pString) { Set(pString); delete [] pString; pString=NULL; return true; } else { OTLog::vError("OTASCIIArmor::%s: pString NULL.\n", __FUNCTION__); } } else { OTLog::vError("OTASCIIArmor::%s: nDestLen 0.\n", __FUNCTION__); } return false; }