| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 | 
							- /*
 
-  * CBinaryReader.cpp, part of VCMI engine
 
-  *
 
-  * Authors: listed in file AUTHORS in main folder
 
-  *
 
-  * License: GNU General Public License v2.0 or later
 
-  * Full text of license available in license.txt file, in main folder
 
-  *
 
-  */
 
- #include "StdInc.h"
 
- #include "CBinaryReader.h"
 
- #include "CInputStream.h"
 
- VCMI_LIB_NAMESPACE_BEGIN
 
- #ifdef VCMI_ENDIAN_BIG
 
- template <typename CData>
 
- CData readLE(CData data)
 
- {
 
- 	auto dataPtr = (char*)&data;
 
- 	std::reverse(dataPtr, dataPtr + sizeof(data));
 
- 	return data;
 
- }
 
- #else
 
- template <typename CData>
 
- CData readLE(CData data)
 
- {
 
- 	return data;
 
- }
 
- #endif
 
- CBinaryReader::CBinaryReader() : stream(nullptr)
 
- {
 
- }
 
- CBinaryReader::CBinaryReader(CInputStream * stream) : stream(stream)
 
- {
 
- }
 
- CInputStream * CBinaryReader::getStream()
 
- {
 
- 	return stream;
 
- }
 
- void CBinaryReader::setStream(CInputStream * stream)
 
- {
 
- 	this->stream = stream;
 
- }
 
- si64 CBinaryReader::read(ui8 * data, si64 size)
 
- {
 
- 	si64 bytesRead = stream->read(data, size);
 
- 	if(bytesRead != size)
 
- 	{
 
- 		throw std::runtime_error(getEndOfStreamExceptionMsg(static_cast<long>(size)));
 
- 	}
 
- 	return bytesRead;
 
- }
 
- template <typename CData>
 
- CData CBinaryReader::readInteger()
 
- {
 
- 	CData val;
 
- 	stream->read(reinterpret_cast<unsigned char *>(&val), sizeof(val));
 
- 	return readLE(val);
 
- }
 
- //FIXME: any way to do this without macro?
 
- #define INSTANTIATE(datatype, methodname) \
 
- datatype CBinaryReader::methodname() \
 
- { return readInteger<datatype>(); }
 
- // While it is certanly possible to leave only template method
 
- // but typing template parameter every time can be annoying
 
- // and templates parameters can't be resolved by return type
 
- INSTANTIATE(ui8, readUInt8)
 
- INSTANTIATE(si8, readInt8)
 
- INSTANTIATE(ui16, readUInt16)
 
- INSTANTIATE(si16, readInt16)
 
- INSTANTIATE(ui32, readUInt32)
 
- INSTANTIATE(si32, readInt32)
 
- INSTANTIATE(ui64, readUInt64)
 
- INSTANTIATE(si64, readInt64)
 
- #undef INSTANTIATE
 
- std::string CBinaryReader::readBaseString()
 
- {
 
- 	unsigned int len = readUInt32();
 
- 	assert(len <= 500000); //not too long
 
- 	if (len > 0)
 
- 	{
 
- 		std::string ret;
 
- 		ret.resize(len);
 
- 		read(reinterpret_cast<ui8*>(&ret[0]), len);
 
- 		return ret;
 
- 	}
 
- 	return "";
 
- }
 
- void CBinaryReader::skip(int count)
 
- {
 
- 	stream->skip(count);
 
- }
 
- std::string CBinaryReader::getEndOfStreamExceptionMsg(long bytesToRead) const
 
- {
 
- 	std::stringstream ss;
 
- 	ss << "The end of the stream was reached unexpectedly. The stream has a length of " << stream->getSize() << " and the current reading position is "
 
- 				<< stream->tell() << ". The client wanted to read " << bytesToRead << " bytes.";
 
- 	return ss.str();
 
- }
 
- VCMI_LIB_NAMESPACE_END
 
 
  |