views:

322

answers:

3

i need to serialize directory tree. i have no trouble with this type:

std::map<
   std::string, // string(path name)
   std::vector<std::string> // string array(file names in the path)
> tree;

but for the serialization the directory tree with the content i need other type:

std::map<
   std::string, // string(path name)
   std::vector< // files array
      std::pair<
         std::string, // file name
         std::vector< // array of file pieces
            std::pair< // <<<<<<<<<<<<<<<<<<<<<< for this i need lazy initialization
               std::string, // piece buf
               boost::uint32_t // crc32 summ on piece
            >
         >
      >
   >
> tree;

how can i initialize the object of type "std::pair" in the moment of its serialization? i.e. read file piece/calculate crc32 summ.

up

+1  A: 

I dont quite understand the question, but #including "boost/serialization/utility.hpp" gives you the implementation for serialising std::pair.

If you want to load the area of your code later on, then I think the best way would be to create a custom pair class:

class custom_pair : std::pair< std::string, // piece buf
               boost::uint32_t > // crc32 summ on piece
{

};

//...
         std::vector< // array of file pieces
            custom_pair // <<<<<<<<<<<<<<<<<<<<<< for this i need lazy initialization
         >
//...

template< class Archive >
void serialize( Archive & ar, custom_pair & p, const unsigned int version ) {
    ar & boost::serialization::make_nvp( "std::pair", std::pair<...>( p ) );
}

template<class Archive>
inline void load_construct_data( Archive & ar, custom_pair * p, const unsigned int file_version ) {
    std::string first;
    boost::uint32_t second;
    ar & boost::serialization::make_nvp( "first", first_ );
    ar & boost::serialization::make_nvp( "second", second_ );
    ::new( t )custom_pair;
    //...
}

template<class Archive>
inline void save_construct_data( Archive & ar, const custom_pair * p, const unsigned int file_version ) {
    ar & boost::serialization::make_nvp( "first", t->first );
    ar & boost::serialization::make_nvp( "second", t->second );
}
yuumei
A: 

I don't understand the question either.

#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>

If I put one element in the tree and go:

boost::archive::text_iarchive ia(std::cout);
oa << tree;

it outputs:

22 serialization::archive 7 0 0 1 0 0 0 3 foo 0 0 1 0 0 0 3 bar 0 0 1 0 0 0 3 baz 27

which i'm sure you can deserialize.

(tested with boost 1.42)

Ah. Now you changed 'serialize' to 'initialize'. There are no hooks to change your data on the fly, so you'll have to do it just before and just after.

Eddy Pronk
+1  A: 

I would replace the std::string in the vector by a custom class, let me say MyFileNames

class MyFileNames : std::string
{
// add forward constructors as needed

};

std::map<
   std::string, // string(path name)
   std::vector<MyFileNames> // string array(file names in the path)
> tree;

And define the save serialization function for MyFileNames by converting the std::string to a

std::pair<
     std::string, // file name
     std::vector< // array of file pieces
        std::pair< // <<<<<<<<<<<<<<<<<<<<<< for this i need lazy initialization
           std::string, // piece buf
           boost::uint32_t // crc32 summ on piece
        >
     >
>

and the serialize this type. This let you evaluate the lazy part only the data is serialized. For the load you could ignore the lazy data, as I suppose that this data can be calculated.

Vicente Botet Escriba