Десериализация MessagePack Perl в C ++

Я новичок в пакете сообщений, и я пытаюсь взять хеш в perl, сериализовать его с помощью пакета сообщений, записать его в файл, передать его в код на С ++, где файл читается и десериализуется в карту.

Мой Perl-код для генерации файла (примечание — я добавил дополнительную часть, чтобы проверить, могу ли я прочитать файл обратно и правильно десериализовать его в Perl, хотя мне это не нужно):

#! perl

use strict;
use warnings;

use Data::MessagePack;

my %hTestHash = ('AAAAAA' => '20020101',
'BBBBBB' => '20030907');

my $packed = Data::MessagePack->pack(\%hTestHash);

open my $fh, '>', 'splodge.bin' or die "Failed to open slodge.bin for write: $!";
print $fh $packed;
close $fh;

open my $fh2, '<', 'splodge.bin' or die "Failed to open slodge.bin for read: $!";
local $/;
my $file = <$fh2>;

my $hrTest = Data::MessagePack->unpack($file);

Мой код на С ++ для десериализации:

#include "msgpack.hpp"#include <string>
#include <iostream>
#include <sstream>
#include <fstream>

int main(void)
{
// Deserialize the serialized data.
std::ifstream ifs("splodge.bin", std::ifstream::in);
std::stringstream buffer;
buffer << ifs.rdbuf();
msgpack::unpacked upd;
msgpack::unpack(&upd, buffer.str().data(), buffer.str().size());
msgpack::object obj = upd.get();
std::map<std::string, std::string> output_map;
msgpack::convert(output_map, obj);

string date = output_map.at("AAAAAA");

return 0;
}

Это создает 2-элементную карту в output_map, но он содержит только значения мусора — моя программа вылетает на output_map.at() с

{"▒▒▒▒▒▒"=>"▒▒▒▒▒▒▒▒", "▒▒▒▒▒▒"=>"▒▒▒▒▒▒▒▒"}
terminate called after throwing an instance of 'std::out_of_range'
what():  map::at
Aborted

Я не смог найти каких-либо примеров этого конкретного варианта использования и изо всех сил пытался понять, что же не так — это проблема в конце сериализации или (кажется более вероятной) в конце десериализации?

РЕДАКТИРОВАТЬ: Спасибо @ SinanÜnür за указание на мою ошибку, которую я сейчас обновил в этом вопросе. Это не меняет того факта, что хеш заполняется значениями мусора, поэтому выдается одно и то же исключение независимо от того, какой ключ ищется.

0

Решение

Наконец-то удалось заставить его работать с сочетанием правильного чтения двоичных файлов и некоторого манипулирования со странными внутренними типами данных, которые мы имеем.

Функциональный код (который десериализует структуру в Map<string, msgpack::object>, требующий дополнительного шага десериализации каждого значения, когда это необходимо):

#include "msgpack.hpp"#include "map.h"#include <string>
#include <iostream>
#include <fstream>

void unpack_map(const msgpack::object& o, Map<string,msgpack::object>& results){
ASSERT(o.type == msgpack::type::MAP);
for (msgpack::object_kv *p = o.via.map.ptr, *pend = (o.via.map.ptr + o.via.map.size); p != pend; ++p)
results[p->key.as<string>()] = p->val;
}

int main(void)
{
streampos size;
char * memblock;

ifstream file ("splodge.bin", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();

cout << "the entire file content is in memory";
}
else cout << "Unable to open file";

msgpack::unpacked upd;
msgpack::unpack(&upd, memblock, size);
msgpack::object obj = upd.get();

if(obj.type != msgpack::type::MAP) {
cout << ":(" << endl;
} else {
cout << ":)" << endl;
}
cout << "size: " << obj.via.map.size << endl;

Map<string, msgpack::object> objectMap;
unpack_map(obj, objectMap);

msgpack::object val  = objectMap["BBBBBB"];
string tmp = string(val.via.raw.ptr, val.via.raw.size);

delete[] memblock;
return 0;
}

где tmp принимает значение 20030907

-2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]