/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include "serialization-precomp.h"  // Precompiled headers
//
#include <mrpt/core/exceptions.h>
#include <mrpt/serialization/CMessage.h>
#include <mrpt/serialization/CSerializable.h>
#include <mrpt/serialization/archiveFrom_std_streams.h>

#include <cstring>  // memcpy()
#include <sstream>

using namespace mrpt::serialization;

void CMessage::serializeObject(const CSerializable* obj)
{
  MRPT_START
  std::stringstream auxStream;
  auto arch = mrpt::serialization::archiveFrom<std::iostream>(auxStream);

  // Dump the object in the memory stream:
  arch.WriteObject(obj);

  // Copy data to message:
  const auto& data = auxStream.str();
  content.resize(data.size());
  memcpy(
      &content[0],  // Dest
      &data[0],     // Src
      content.size());

  MRPT_END
}

/*---------------------------------------------------------------
        deserializeIntoExistingObject
 ---------------------------------------------------------------*/
void CMessage::deserializeIntoExistingObject(CSerializable* obj)
{
  MRPT_START
  std::stringstream auxStream;
  auto arch = mrpt::serialization::archiveFrom<std::iostream>(auxStream);

  // Copy data into the stream:
  arch.WriteBuffer(&content[0], content.size());
  auxStream.seekg(0);

  // Try to parse data into existing object:
  arch.ReadObject(obj);

  MRPT_END
}

/*---------------------------------------------------------------
        deserializeIntoNewObject
 ---------------------------------------------------------------*/
void CMessage::deserializeIntoNewObject(CSerializable::Ptr& obj)
{
  MRPT_START
  std::stringstream auxStream;
  auto arch = mrpt::serialization::archiveFrom<std::iostream>(auxStream);

  // Copy data into the stream:
  if (!content.empty())
  {
    arch.WriteBuffer(&content[0], content.size());
    auxStream.seekg(0);

    // Try to parse data into a new object:
    obj = arch.ReadObject();
  }
  else
    obj.reset();

  MRPT_END
}

/*---------------------------------------------------------------
        setContentFromString
 ---------------------------------------------------------------*/
void CMessage::setContentFromString(const std::string& str)
{
  content.resize(str.size());
  if (content.size() > 0) memcpy(&content[0], str.c_str(), str.size());
}

/*---------------------------------------------------------------
        getContentAsString
 ---------------------------------------------------------------*/
void CMessage::getContentAsString(std::string& str)
{
  str.resize(content.size());
  if (content.size() > 0) memcpy(&str[0], &content[0], str.size());
}
