BsFileSerializer.cpp 2.7 KB

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