BsFileSerializer.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include "BsFileSerializer.h"
  2. #include "BsException.h"
  3. #include "BsIReflectable.h"
  4. #include "BsBinarySerializer.h"
  5. #include "BsPath.h"
  6. #include "BsFileSystem.h"
  7. #include <numeric>
  8. using namespace std::placeholders;
  9. namespace BansheeEngine
  10. {
  11. FileSerializer::FileSerializer()
  12. {
  13. mWriteBuffer = (UINT8*)bs_alloc<ScratchAlloc>(WRITE_BUFFER_SIZE);
  14. }
  15. FileSerializer::~FileSerializer()
  16. {
  17. bs_free<ScratchAlloc>(mWriteBuffer);
  18. }
  19. void FileSerializer::encode(IReflectable* object, const Path& fileLocation)
  20. {
  21. Path parentDir = fileLocation.getDirectory();
  22. if (!FileSystem::exists(parentDir))
  23. FileSystem::createDir(parentDir);
  24. mOutputStream.open(fileLocation.toString().c_str(), std::ios::out | std::ios::binary);
  25. BinarySerializer bs;
  26. int totalBytesWritten = 0;
  27. bs.encode(object, mWriteBuffer, WRITE_BUFFER_SIZE, &totalBytesWritten, std::bind(&FileSerializer::flushBuffer, this, _1, _2, _3));
  28. mOutputStream.close();
  29. mOutputStream.clear();
  30. }
  31. std::shared_ptr<IReflectable> FileSerializer::decode(const Path& fileLocation)
  32. {
  33. mInputStream.open(fileLocation.toString().c_str(), std::ios::in | std::ios::ate | std::ios::binary);
  34. std::streamoff fileSize = mInputStream.tellg();
  35. if(fileSize > std::numeric_limits<UINT32>::max())
  36. {
  37. BS_EXCEPT(InternalErrorException,
  38. "File size is larger that UINT32 can hold. Ask a programmer to use a bigger data type.");
  39. }
  40. UINT8* readBuffer = (UINT8*)bs_alloc<ScratchAlloc>((UINT32)fileSize); // TODO - Low priority. Consider upgrading BinarySerializer so we don't have to read everything at once
  41. mInputStream.seekg(0, std::ios::beg);
  42. mInputStream.read((char*)readBuffer, fileSize);
  43. BinarySerializer bs;
  44. std::shared_ptr<IReflectable> object = bs.decode(readBuffer, (UINT32)fileSize);
  45. mInputStream.close();
  46. mInputStream.clear();
  47. bs_free<ScratchAlloc>(readBuffer);
  48. return object;
  49. }
  50. UINT8* FileSerializer::flushBuffer(UINT8* bufferStart, int bytesWritten, UINT32& newBufferSize)
  51. {
  52. mOutputStream.write((const char*)bufferStart, bytesWritten);
  53. return bufferStart;
  54. }
  55. }