Advertisement Jump to content
Sign in to follow this  
Dissipate

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

This topic is 1784 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 

Share this post


Link to post
Share on other sites
Advertisement

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.

Share this post


Link to post
Share on other sites

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;

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!