1#ifndef ROSE_BinaryAnalysis_SerialIo_H
2#define ROSE_BinaryAnalysis_SerialIo_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
6#include <ROSE_UNUSED.h>
7#include <Rose/BinaryAnalysis/BasicTypes.h>
8#include <Rose/BinaryAnalysis/Serialization/SerialFrame.h>
9#include <Rose/Exception.h>
10#include <Rose/Progress.h>
12#include <Sawyer/Message.h>
13#include <Sawyer/ProgressBar.h>
14#include <Sawyer/Synchronization.h>
16#include <boost/filesystem.hpp>
17#include <boost/lexical_cast.hpp>
23#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
24#include <boost/archive/binary_iarchive.hpp>
25#include <boost/archive/binary_oarchive.hpp>
26#include <boost/archive/text_iarchive.hpp>
27#include <boost/archive/text_oarchive.hpp>
28#include <boost/archive/xml_iarchive.hpp>
29#include <boost/archive/xml_oarchive.hpp>
33namespace BinaryAnalysis {
104 Serialization::Format format = Serialization::BINARY;
105 std::function<std::shared_ptr<Deserializer>()> deserializer;
106 std::function<std::shared_ptr<Serializer>()> serializer;
113 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
114 Serialization::Format format_;
117 Serialization::Savable objectType_;
125 format_(Serialization::BINARY), progress_(
Progress::instance()), isOpen_(false),
126 objectType_(Serialization::NO_OBJECT), progressBar_(
mlog[
Sawyer::Message::MARCH]), fd_(-1) {
128 progressBar_.
suffix(
" bytes");
182 virtual void open(
const boost::filesystem::path&) = 0;
212 void setIsOpen(
bool b);
230 using Format = Serialization::Format;
231 static constexpr Format BINARY = Serialization::BINARY;
232 static constexpr Format TEXT = Serialization::TEXT;
233 static constexpr Format XML = Serialization::XML;
251 virtual std::vector<char>
297 std::shared_ptr<Serialization::SerialFrame> frame_;
298 std::shared_ptr<SerialIo::Serializer> serializer_;
305 void open(
const boost::filesystem::path& fileName)
override;
337#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
346#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
347 void saveAstHelper(
SgNode*);
365 template <
class T>
void saveObject(Serialization::Savable objectTypeId,
const T&
object) {
367 throw Exception(
"cannot save object when no file is open");
369 throw Exception(
"cannot save object because stream is in error state");
371 throw Exception(
"frame container not initialized");
373 throw Exception(
"serializer not initialized");
376 std::string errorMessage;
377 boost::thread worker(startWorker<T>,
this, objectTypeId,
object, errorMessage);
380 progressBar_.
prefix(
"writing");
382 while (!worker.try_join_for(timeout)) {
383 off_t cur = ::lseek(fd_, 0, SEEK_CUR);
387 progressBar_.
value(cur);
392 if (!errorMessage.empty())
399 startWorker(
SerialOutput* saver, Serialization::Savable objectTypeId,
const T&
object, std::string& errorMessage) {
400 saver->saveWorker(objectTypeId,
object, errorMessage);
404 void saveWorker(Serialization::Savable objectTypeId,
const T&
object, std::string& errorMessage) {
407 Serialization::FrameRecord frameRecord(objectTypeId,
format());
410 frameRecord.serializeObject(
object);
413 frame_->writeFrameRecord(frameRecord);
415 }
catch (
const std::exception& e) {
416 errorMessage = std::string(
"Failed to save object using container: ") + e.what();
418 errorMessage =
"failed to write object to output stream";
436 std::shared_ptr<Serialization::SerialFrame> frame_;
437 std::shared_ptr<SerialIo::Deserializer> deserializer_;
444 void open(
const boost::filesystem::path& fileName)
override;
485#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
496 template <
class T> T
loadObject(Serialization::Savable objectTypeId) {
498 throw Exception(
"serialization backend not initialized");
501 loadObject<T>(objectTypeId,
object);
504 template <
class T>
void loadObject(Serialization::Savable objectTypeId, T&
object) {
506 throw Exception(
"cannot load object when no file is open");
508 throw Exception(
"frame container not initialized");
510 throw Exception(
"deserializer not initialized");
517 frameRecord.deserializeObject(
object);
520 }
catch (
const boost::archive::archive_exception& e) {
521 throw Exception(std::string(
"Failed to load object from Boost archive: ") + e.what());
522 }
catch (
const std::exception& e) {
523 throw Exception(std::string(
"Failed to load object using container: ") + e.what());
531 void advanceObjectType();
534 void checkCompatibility(
const std::string& fileVersion);
Interface for deserializer implementations.
virtual Partitioner2::PartitionerPtr loadPartitioner(const std::vector< char > &data, Serialization::ProgressCallback progress)
Deserialize a partitioner from a binary payload with default partitioner settings.
virtual Partitioner2::PartitionerPtr loadPartitioner(const std::vector< char > &data, const Partitioner2::BasePartitionerSettings &settings, Serialization::ProgressCallback progress)=0
Deserialize a partitioner from a binary payload.
Interface for serializer implementations.
virtual std::vector< char > savePartitioner(const Partitioner2::PartitionerConstPtr &partitioner, Serialization::ProgressCallback progress)=0
Serialize a partitioner to a binary payload.
Extension of the base SerialIo class defined in BasicTypes.h.
Serialization::ProgressCallback makeProgressCB(const std::string &phase)
Create progress callbacks that wraps the IO progress reporting.
virtual void close()=0
Detach a file.
virtual ~SerialIo()
Destructor.
void progress(const Progress::Ptr &)
Property: Progress reporter.
void format(Serialization::Format)
Property: File format.
static Serialization::Savable userSavable(unsigned offset)
Create a new Savable enum constant.
SerialIoPtr Ptr
Reference counting pointer.
Progress::Ptr progress() const
Property: Progress reporter.
virtual void open(const boost::filesystem::path &)=0
Attach a file.
Serialization::Format format() const
Property: File format.
Serialization::Savable objectType() const
Type ID for next object.
bool isOpen() const
Whether a file is attached.
static Sawyer::Message::Facility mlog
Message facility.
Output binary analysis state.
SerialOutputPtr Ptr
Reference counting pointer.
static Ptr instance()
Factory method to create a new instance.
void saveObject(Serialization::Savable objectTypeId, const T &object)
Save an object to the output stream.
void close() override
Detach a file.
void savePartitioner(const Partitioner2::PartitionerConstPtr &)
Save a binary analysis partitioner.
void open(const boost::filesystem::path &fileName) override
Attach a file.
void saveAst(SgAsmNode *)
Save a binary AST.
Helper class for metadata and payload handling.
Base class for all ROSE exceptions.
A general, thread-safe way to report progress made on some task.
Holds a value or nothing.
const std::string & prefix() const
String to show before the beginning of the bar.
Suffix suffix()
Property: suffix.
ValueType value() const
Value for the progress bar.
Base class for all binary analysis IR nodes.
This class represents the base class for all IR nodes within Sage III.
std::shared_ptr< SerialInput > SerialInputPtr
Reference counting pointer.
std::shared_ptr< SerialOutput > SerialOutputPtr
Reference counting pointer.
std::shared_ptr< SerialIo > SerialIoPtr
Reference counting pointer.
double minimumUpdateInterval()
Minimum time between updates.
Settings that directly control a partitioner.
A single progress report.