/// if we pack, compress, encode on the way in, that means, therefore, we
/// need to decode, uncompress, then unpack on our way out. Right?
///
/// This function will base64-DECODE the string contents, then uncompress them using
/// zlib, and then unpack the result using whatever is the default packer (MsgPack, Protobuf, etc).
/// 
/// I originally added compression because message sizes were too big. Now I'm adding packing, 
/// to solve any issues of binary compatibility across various platforms.
//
bool OTASCIIArmor::GetAndUnpackString(OTString & strData, bool bLineBreaks) const //bLineBreaks=true
{	
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	strData.Release();
	
	if (GetLength() < 1)
	{
		return true;
	}
	// --------------------------------------------------------------
	pData = OTCrypto::It()->Base64Decode(this->Get(), &outSize, bLineBreaks);
//	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
        
        std::string str_decoded( pData, pData+outSize );
        
        delete [] pData; pData=NULL;

        std::string str_uncompressed = decompress_string( str_decoded );
		// ---------------------------------------
		// PUT THE PACKED BUFFER HERE, AND UNPACK INTO strData
		// --------------------------------------------------------
		OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either.
		
		OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up.
		OT_ASSERT(NULL != pBuffer);
		OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // This will make sure buffer is deleted later.
		      
        pBuffer->SetData(reinterpret_cast<const uint8_t *>(str_uncompressed.data()), str_uncompressed.size());
		// -----------------------------
		OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING));
		OT_ASSERT(NULL != pOTDBString);
		OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // clean up this string.
		
		bool bUnpacked = pPacker->Unpack(*pBuffer, *pOTDBString);
		// ----------------------
		if (false == bUnpacked)
		{
			OTLog::Error("Failed unpacking string in OTASCIIArmor::GetAndUnpackString.\n");
			
			return false;
		}
		// --------------------------------------------------------
		// This enforces the null termination. (using the 2nd parameter as nEnforcedMaxLength)
		strData.Set(pOTDBString->m_string.c_str(), static_cast<uint32_t> (pOTDBString->m_string.length()));
		
		return true;
	}
	else 
	{
		OTLog::Error("OTASCIIArmor::GetAndUnpackString: NULL pData while base64-decoding pData.\n");
		return false;
	}
}
// 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 will base64 DECODE the string contents
// and return them as binary in theData
// Additionally it will decompress and unpack the data!
//
bool OTASCIIArmor::GetAndUnpackData(OTData & theData, bool bLineBreaks) const //linebreaks=true
{	
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	theData.Release();
	
	if (GetLength() < 1)
		return true;
	
	// --------------------------------------------------------------
	//
	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
		// --------------------------------------------------------
		
		OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either.
		
		OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up.
		OT_ASSERT(NULL != pBuffer);
		OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure buffer is deleted.
		
		pBuffer->SetData(static_cast<const unsigned char*>(pData), outSize);
		delete [] pData; pData=NULL; 
		// -----------------------------
		
		OTDB::Blob * pBlob = dynamic_cast<OTDB::Blob *>(OTDB::CreateObject(OTDB::STORED_OBJ_BLOB));
		OT_ASSERT(NULL != pBlob);
		OTCleanup<OTDB::Blob> theBlobAngel(*pBlob); // clean up this blob.
		
		bool bUnpacked = pPacker->Unpack(*pBuffer, *pBlob);
		
		// ----------------------
		
		if (false == bUnpacked)
		{
			OTLog::Error("Failed unpacking data in OTASCIIArmor::GetAndUnpackData.\n");
			delete [] pData; pData=NULL;
			return false;
		}
		
		// --------------------------------------------------------
		
		theData.Assign(pBlob->m_memBuffer.data(), pBlob->m_memBuffer.size());
		delete [] pData; pData=NULL;
		return true;
	}
	else 
	{
		OTLog::Error("Error while base64_decoding in OTASCIIArmor::GetAndUnpackData.\n");
		return false;
	}
}
bool OTASCIIArmor::GetAndUnpackStringMap(std::map<std::string, std::string> & the_map, bool bLineBreaks/*=true*/) const
{
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	the_map.clear();
	
	if (GetLength() < 1)
		return true;
	
	// --------------------------------------------------------------
	//
	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
		// --------------------------------------------------------
		OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either.
		
		OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up.
		OT_ASSERT(NULL != pBuffer);
		OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure buffer is deleted.
		
		pBuffer->SetData(static_cast<const unsigned char*>(pData), outSize);
		delete [] pData; pData=NULL; 
		// -----------------------------
		
		OTDB::StringMap * pStringMap = dynamic_cast<OTDB::StringMap *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING_MAP));
		OT_ASSERT(NULL != pStringMap);
		OTCleanup<OTDB::StringMap> theMapAngel(*pStringMap); // clean up this map.
		
		bool bUnpacked = pPacker->Unpack(*pBuffer, *pStringMap);
		// ----------------------
		if (false == bUnpacked)
		{
			OTLog::Error("Failed unpacking data in OTASCIIArmor::GetAndUnpackStringMap.\n");
			delete [] pData; pData=NULL;
			return false;
		}
		// -----------------------------
		the_map = pStringMap->the_map;
		// -----------------------------
		delete [] pData; pData=NULL;
		return true;
	}
	else 
	{
		OTLog::Error("Error while base64_decoding in OTASCIIArmor::GetAndUnpackStringMap.\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;	
}
/// if we pack, compress, encode on the way in, that means, therefore, we
/// need to decode, uncompress, then unpack on our way out. Right?
///
/// This function will base64-DECODE the string contents, then uncompress them using
/// zlib, and then unpack the result using whatever is the default packer (MsgPack, Protobuf, etc).
/// 
/// I originally added compression because message sizes were too big. Now I'm adding packing, 
/// to solve any issues of binary compatibility across various platforms.
//
bool OTASCIIArmor::GetAndUnpackString(OTString & strData, bool bLineBreaks) const //bLineBreaks=true
{	
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	strData.Release();
	
	if (GetLength() < 1)
	{
		return true;
	}
	// --------------------------------------------------------------
	pData = OTCrypto::It()->Base64Decode(this->Get(), &outSize, bLineBreaks);
//	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
		// -------------------------------------------
		// EASY ZLIB
		//
		long nDestLen = DEFAULT_BUFFER_SIZE_EASYZLIB; // todo stop hardcoding numbers (but this one is OK I think.)
		unsigned char* pDest = new unsigned char [nDestLen+10]; // For safety.
		
		OT_ASSERT(NULL != pDest);
		
		int nErr = ezuncompress( pDest, &nDestLen, pData, static_cast<long> (outSize) );
		if ( nErr == EZ_BUF_ERROR )
		{
			delete [] pDest;
			pDest = new unsigned char [nDestLen]; // enough room now
			
			OT_ASSERT(NULL != pDest);
			
			nErr = ezuncompress( pDest, &nDestLen, pData, static_cast<long> (outSize) );
		}
		
		// Now we're done with this memory, let's free it.
		delete [] pData; pData=NULL;
		// ----------------------------------------
		if ( nErr == EZ_BUF_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_FAIL_MSG("Buffer error in OTASCIIArmor::GetAndUnpackString\n");
		}
		else if ( nErr == EZ_STREAM_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_FAIL_MSG("pDest is NULL in OTASCIIArmor::GetAndUnpackString\n");
		}
		else if ( nErr == EZ_DATA_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OTLog::vError("corrupted pSrc passed to ezuncompress OTASCIIArmor::GetAndUnpackString, size: %d\n", outSize);
			OT_FAIL;
		}
		else if ( nErr == EZ_MEM_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_FAIL_MSG("Out of memory in OTASCIIArmor::GetAndUnpackString\n");
		}
		// ---------------------------------------
		// PUT THE PACKED BUFFER HERE, AND UNPACK INTO strData
		// --------------------------------------------------------
		OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either.
		
		OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up.
		OT_ASSERT(NULL != pBuffer);
		OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // This will make sure buffer is deleted later.
		
		const size_t theDestLen = nDestLen;
		
		pBuffer->SetData(pDest, // const unsigned char *
						 theDestLen);

		delete [] pDest; pDest=NULL; 
		// -----------------------------
		OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING));
		OT_ASSERT(NULL != pOTDBString);
		OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // clean up this string.
		
		bool bUnpacked = pPacker->Unpack(*pBuffer, *pOTDBString);
		// ----------------------
		if (false == bUnpacked)
		{
			OTLog::Error("Failed unpacking string in OTASCIIArmor::GetAndUnpackString.\n");
			
			return false;
		}
		// --------------------------------------------------------
		// This enforces the null termination. (using the 2nd parameter as nEnforcedMaxLength)
		strData.Set(pOTDBString->m_string.c_str(), static_cast<uint32_t> (pOTDBString->m_string.length()));
		
		return true;
	}
	else 
	{
		OTLog::Error("OTASCIIArmor::GetAndUnpackString: NULL pData while base64-decoding pData.\n");
		return false;
	}
}
Exemple #7
0
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;
}
Exemple #8
0
// 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;	
}