2
0

BsFileSerializer.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Serialization/BsFileSerializer.h"
  4. #include "Error/BsException.h"
  5. #include "Reflection/BsIReflectable.h"
  6. #include "Serialization/BsBinarySerializer.h"
  7. #include "FileSystem/BsFileSystem.h"
  8. #include "FileSystem/BsDataStream.h"
  9. #include "Debug/BsDebug.h"
  10. #include <numeric>
  11. using namespace std::placeholders;
  12. namespace bs
  13. {
  14. FileEncoder::FileEncoder(const Path& fileLocation)
  15. :mWriteBuffer(nullptr)
  16. {
  17. mWriteBuffer = (UINT8*)bs_alloc(WRITE_BUFFER_SIZE);
  18. Path parentDir = fileLocation.getDirectory();
  19. if (!FileSystem::exists(parentDir))
  20. FileSystem::createDir(parentDir);
  21. mOutputStream.open(fileLocation.toPlatformString().c_str(), std::ios::out | std::ios::binary);
  22. if (mOutputStream.fail())
  23. {
  24. LOGWRN("Failed to save file: \"" + fileLocation.toString() + "\". Error: " + strerror(errno) + ".");
  25. }
  26. }
  27. FileEncoder::~FileEncoder()
  28. {
  29. bs_free(mWriteBuffer);
  30. mOutputStream.close();
  31. mOutputStream.clear();
  32. }
  33. void FileEncoder::encode(IReflectable* object, const UnorderedMap<String, UINT64>& params)
  34. {
  35. if (object == nullptr)
  36. return;
  37. UINT64 curPos = (UINT64)mOutputStream.tellp();
  38. mOutputStream.seekp(sizeof(UINT32), std::ios_base::cur);
  39. BinarySerializer bs;
  40. UINT32 totalBytesWritten = 0;
  41. bs.encode(object, mWriteBuffer, WRITE_BUFFER_SIZE, &totalBytesWritten,
  42. std::bind(&FileEncoder::flushBuffer, this, _1, _2, _3), false, params);
  43. mOutputStream.seekp(curPos);
  44. mOutputStream.write((char*)&totalBytesWritten, sizeof(totalBytesWritten));
  45. mOutputStream.seekp(totalBytesWritten, std::ios_base::cur);
  46. }
  47. UINT8* FileEncoder::flushBuffer(UINT8* bufferStart, UINT32 bytesWritten, UINT32& newBufferSize)
  48. {
  49. mOutputStream.write((const char*)bufferStart, bytesWritten);
  50. return bufferStart;
  51. }
  52. FileDecoder::FileDecoder(const Path& fileLocation)
  53. {
  54. mInputStream = FileSystem::openFile(fileLocation, true);
  55. if (mInputStream == nullptr)
  56. return;
  57. if (mInputStream->size() > std::numeric_limits<UINT32>::max())
  58. {
  59. BS_EXCEPT(InternalErrorException,
  60. "File size is larger that UINT32 can hold. Ask a programmer to use a bigger data type.");
  61. }
  62. }
  63. SPtr<IReflectable> FileDecoder::decode(const UnorderedMap<String, UINT64>& params)
  64. {
  65. if (mInputStream->eof())
  66. return nullptr;
  67. UINT32 objectSize = 0;
  68. mInputStream->read(&objectSize, sizeof(objectSize));
  69. BinarySerializer bs;
  70. SPtr<IReflectable> object = bs.decode(mInputStream, objectSize, params);
  71. return object;
  72. }
  73. void FileDecoder::skip()
  74. {
  75. if (mInputStream->eof())
  76. return;
  77. UINT32 objectSize = 0;
  78. mInputStream->read(&objectSize, sizeof(objectSize));
  79. mInputStream->skip(objectSize);
  80. }
  81. }