Jump to content

  • Log In with Google      Sign In   
  • Create Account

Why is txt/bin file being serialised mysterious numbers...?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 Dissipate   Members   -  Reputation: 345

Like
0Likes
Like

Posted 26 February 2014 - 04:32 PM

I am have created an ISerialization inteface that overshadows CBinaryFile and CTextFile that inherit it. I am using boost serialization to save some sample text to a 'text/binary' file. I am overriding and overloading the operator<< for the concrete classes. I think due to this I am getting strange numbers prefixing each output in the text file. I don't know whether the same is happening in the bin file but I assume it is.

 

The headers are left out. This code works fine when run in a test project without any classes - just the basic i/o code. See end of post for output:

class ISerialization
{
public:
	ISerialization(void) {}
	~ISerialization(void) {}

        ifstream m_ifs;
        ofstream m_ofs;

	unsigned int m_iBoostFlags;
	unsigned int m_iIOSFlags;

	boost::shared_ptr<boost::archive::binary_oarchive> m_spBinOA; // Bin Out
	boost::shared_ptr<boost::archive::binary_iarchive> m_spBinIA; // Bin In
	boost::shared_ptr<boost::archive::text_oarchive> m_spTxtOA; // Txt Out
	boost::shared_ptr<boost::archive::text_iarchive> m_spTxtIA; // Txt In
	boost::shared_ptr<boost::archive::xml_oarchive> m_spXmlOA; // Xml Out
	boost::shared_ptr<boost::archive::xml_iarchive> m_spXmlIA; // Xml In
		
	virtual void OpenOutput(std::string& s, unsigned int m_iIOSFlags) = 0;
	virtual void OpenInput(std::string& s, unsigned int m_iIOSFlags) = 0;

	virtual ISerialization& operator<< (const string& s) = 0;
	virtual ISerialization& operator<< (const int i) = 0;
	virtual ISerialization& operator<< (const unsigned int ui) = 0;
	virtual ISerialization& operator<< (const float f) = 0;
	virtual ISerialization& operator<< (const double d) = 0;

	friend ISerialization& operator<< (ISerialization& s, std::ostream& (*manip)(std::ostream &)) 
	{
		if (s.m_ofs.is_open()) 
		{
			manip(s.m_ofs);
			s.m_ofs.flush();
			return s;
		}
		else
			return s;
	}

private:

};

Here is the CBinaryFile class

class CBinaryFile : public ISerialization
{
public:
	CBinaryFile(void) {}
	~CBinaryFile(void) {}

	void OpenOutput(std::string& s, unsigned int m_iIOSFlags) override 
	{
		// Open filestream
		ISerialization::m_ofs = std::ofstream(s.c_str(), m_iIOSFlags | std::ios::binary);

		// Set flags for boost
		ISerialization::m_iBoostFlags = boost::archive::no_header;

		// Create boost binary output archive
		ISerialization::m_spBinOA = 
			boost::make_shared<boost::archive::binary_oarchive>(m_ofs, m_iBoostFlags);
	}

	void OpenInput(std::string& s, unsigned int m_iIOSFlags) override
	{
		// Open filestream
		ISerialization::m_ifs = std::ifstream(s.c_str(), m_iIOSFlags | std::ios::binary);

		// Set flags for boost
		ISerialization::m_iBoostFlags = boost::archive::no_header;

		// Create boost binary output archive
		ISerialization::m_spBinIA = 
			boost::make_shared<boost::archive::binary_iarchive>(m_ifs, m_iBoostFlags);
	}

	ISerialization& operator<< (const string& s) override {
		if (m_ofs.is_open())
			*m_spBinOA << s;
		
		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const int i) override {
		if (m_ofs.is_open())
			*m_spBinOA << i;

		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const unsigned int ui) override {
		if (m_ofs.is_open())
			*m_spBinOA << ui;

		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const float f) override {
		if (m_ofs.is_open())
			*m_spBinOA << f;

		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const double d) override {
		if (m_ofs.is_open())
			*m_spBinOA << d;
		return *(static_cast<ISerialization*>(this));
	}

private:

};

Here is the CTextFile class:

class CTextFile : public ISerialization
{
public:
	CTextFile(void) {}
	~CTextFile(void) {}

	void OpenOutput(std::string& s, unsigned int m_iIOSFlags) override 
	{
		// Open filestream
		ISerialization::m_ofs = std::ofstream(s.c_str(), m_iIOSFlags);

		// Set flags for boost
		ISerialization::m_iBoostFlags = boost::archive::no_header;

		// Create boost binary output archive
		ISerialization::m_spTxtOA = 
			boost::make_shared<boost::archive::text_oarchive>(m_ofs, m_iBoostFlags);
	}

	// NOT IMPLEMENTED as cant read an arbitrary text file.
	//void OpenInput(std::string& s, unsigned int m_iIOSFlags) override
	void OpenInput(std::string& s, unsigned int m_iIOSFlags) override {}
	//{
	//	// Open filestream
	//	ISerialization::m_ifs = std::ifstream(s.c_str(), m_iIOSFlags);

	//	// Set flags for boost
	//	ISerialization::m_iBoostFlags = boost::archive::no_header;

	//	// Create boost binary output archive
	//	ISerialization::m_spTxtIA = 
	//		boost::make_shared<boost::archive::text_iarchive>(m_ifs, m_iBoostFlags);
	//}

	ISerialization& operator<< (const string& s) override {
		stringstream ss;
		ss << s.c_str();
		if (m_ofs.is_open())
			*m_spTxtOA << ss.str();
		
		return *this;
	}

	ISerialization& operator<< (const int i) override {
		if (m_ofs.is_open())
			*m_spTxtOA << i;

		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const unsigned int ui) override {
		if (m_ofs.is_open())
			*m_spTxtOA << ui;

		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const float f) override {
		if (m_ofs.is_open())
			*m_spTxtOA << f;

		return *(static_cast<ISerialization*>(this));
	}

	ISerialization& operator<< (const double d) override {
		if (m_ofs.is_open())
			*m_spTxtOA << d;

		return *(static_cast<ISerialization*>(this));
	}

private:

};

This is how I call them:

int main()
{
	CBinaryFile MyBinaryFile;
	CTextFile   MyTextFile;

	string sBinFile = "MyBinFile.bin";
	string sTxtFile = "MyTxtFile.txt";

	// Open files
	MyBinaryFile.OpenOutput(sBinFile, ios::trunc | ios::binary);
	MyTextFile.OpenOutput(sTxtFile, ios::trunc);

	// Write stuff
	MyBinaryFile << "Hello " << "Should not be " << std::endl <<
		            "Numbers " << "Here" << std::endl;
	MyTextFile << "Bye the way " << "There " << std::endl <<
		          "should be " << " no numbers here either " << std::endl;

	// Close
	MyBinaryFile.CloseOutputFile();
	MyTextFile.CloseOutputFile();

	return 0;
}

Sorry for long post but maybe this will help a few people aswell. I really look forward to you reflective thoughts. Thank you in advance.

This is the Output:

12 Bye the way  6 There 
 10 should be  24  no numbers here either 



Sponsor:

#2 Ectara   Crossbones+   -  Reputation: 2968

Like
0Likes
Like

Posted 26 February 2014 - 05:35 PM

It would look as if the serializing function is outputting the length of the string to be read in when it is deserialized; if they went with null-terminated output, you couldn't store a null character in the string and have it recovered, so they had to include the length somehow.



#3 Dissipate   Members   -  Reputation: 345

Like
0Likes
Like

Posted 27 February 2014 - 03:54 AM

Ok, I've rewritten all the overloaded the operator<< to save the each data type to the ostream instead, which got rid of the prefixed spaces in front of any number I may wish to save. 2 quick questions:

1: How could I template overload these operators. I tried but my compiler keeps breaking; and

2: Should I really be doing:

ISerialization& operator<< (const string& s) override {
       /*do Stuff*/	
	return *(static_cast<ISerialization*>(this));
}

Instead of just:

return *this;





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS