Software Design

Design de software em C, C++, Java, etc…

C++: Serialização de objetos com boost serialization

Estou envolvido num projeto que emula a comunicação com um elemento de rede. Trata-se de um servidor simples que responde à requisições feitas por um outro serviço, utilizando o protocolo ROSE+ASN.1 codificado com BER.

O servidor tem 3 operações principais ( adicionar, remover e listar ). Quando um item é adicionado ele fica em memória até que o servidor receba o comando para excluí-lo. Porém durante os testes surgiu a necessidade de reiniciar o servidor sem perder as informações que estavam em memória.

Optei por utilizar a boost serialization já que não preciso de um banco de dados elaborado. Já tinha uma classe chamada Interception. Já tenho a struct que será utilizada para persistência ela estava assim:

struct Interception {
    string liid_;
    string targetId_;
    TargetType targetType_;
    string deliveryOfIRI_;
    string deliveryOfIPR_;
    string startTime_;
    string endTime_;
}

Basicamente o que precisei fazer foi:

  1. Adicionar os includes da boost serialization e linkar a biblioteca ao meu projeto
  2. Adicionar o código de serialização da classe Interception
  3. Criar métodos para ler e gravar em arquivos.

A serialização da boost é feita utilizando templates para o stream de destino. Para enviar dados para o stream você pode utilizar os operadores “<<”  ou “&”, para ler dados da stream utilize “>>” ou “&”. O operador & é melhor porque utilizando ele você não precisa definir métodos específicos para ler e salvar na stream. Apenas o método serialize resolve.

O código de serialização ficou assim:

#include <boost/serialization/serialization.hpp>
//....
   template
   void serialize(Archive &ar, const unsigned int version) {
        ar & liid_;
        ar & targetId_;
        ar & targetType_;
        ar & deliveryOfIRI_;
        ar & deliveryOfIPR_;
        ar & startTime_;
        ar & endTime_;
    };

Adicionei este template method à struct Interception como um membro. Se não fosse possível fazer isso ( ex.: se eu não pudesse alterar essa struct. A solução seria criar esse método dentro da namespace boost::serialization. Assim:

#include <boost/serialization/serialization.hpp>
//....
namespace boost {
namespace serialization {
 template
 void serialize(Archive &ar, Interception &i const unsigned int version) {
 ar & i.liid_;
 ar & i.targetId_;
 ar & i.targetType_;
 ar & i.deliveryOfIRI_;
 ar & i.deliveryOfIPR_;
 ar & i.startTime_;
 ar & i.endTime_;
 };
}}

Depois da implementação do método serialize, bastou criar os métodos de leitura e escrita em arquivos:

template
void saveToFile(const std::string &fileName, const ListType& in) {
    std::ofstream ofs(fileName.c_str());
    boost::archive::text_oarchive oa(ofs);
    boost::serialization::save(oa, in, 1);
}

template
void readFromFile(const std::string &fileName, ListType &out) {
    std::ifstream f(fileName.c_str());
    boost::archive::text_iarchive ia(f);
    boost::serialization::load(ia, out, 1);
}

Para usar as funções readFromFile e saveToFile o código ficou assim:

  string fn = "file.txt";
  saveToFile(fn, server->getConfig().getInterceptions());
//...
  readFromFile(fn, server->getConfig().getInterceptions());

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Informação

Publicado às agosto 24, 2012 por em boost, C++ e marcado , , , , , , .
%d blogueiros gostam disto: