i'm trying to send json messages trough boost message_queue using ptree for storing informations localy.
this is the code of the receiver:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <iostream>
#include <string>
//#include <boost/archive/text_iarchive.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/serialization/string.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree; using boost::property_tree::read_json;
#define MAX_SIZE 1000
int main()
{
message_queue mq (boost::interprocess::open_or_create,"coda",10,MAX_SIZE);
message_queue::size_type recv_size;
unsigned int priority;
ptree pt;
std::stringstream iss;
std::string serialized_string;
serialized_string.resize(MAX_SIZE);
mq.receive(&serialized_string[0],MAX_SIZE,recv_size,priority);
iss << serialized_string;
std::istringstream is(iss.str());
read_json(is, pt);
std::cout pt.get<std::string>("prefix") << pt.get<std::string>("faceID") << std::endl;
}
and this is the code of th sender:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree; using boost::property_tree::write_json;
#define MAX_SIZE 1000
void send(ptree pt)
{
std::stringstream oss;
write_json(oss,pt);
std::string serialized_strings(oss.str());
message_queue mq(boost::interprocess::open_only,"coda");
mq.send(serialized_strings.data(), serialized_strings.size(),0);
std::cout << oss.str() << std::endl;
}
int main()
{
ptree pt;
pt.put("prefix","standard");
pt.put("faceID",42);
send(pt);
}
the sender works and have this output:
$ ./sendptree
{
"prefix": "standard",
"faceID": "42"
}
the receiver receive the data correctly but fail to parse it (with the read_json call).
$ ./recvptree
{
"prefix": "standard",
"faceID": "42"
}
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::property_tree::json_parser::json_parser_error> >'
what(): <unspecified file>(5): expected end of input
[1] 24052 abort ./recvptree
I think it was just that your receive buffer was not null terminated. This code works:
Server:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree; using boost::property_tree::write_json;
#define MAX_SIZE 1000
void send(ptree pt)
{
std::stringstream oss;
write_json(oss,pt);
message_queue mq(boost::interprocess::open_or_create,"coda",10,MAX_SIZE);
mq.send(oss.str().c_str(), oss.str().size(),0);
std::cout << oss.str() << std::endl;
system("PAUSE");
}
int main()
{
ptree pt;
pt.put("prefix","standard");
pt.put("faceID",42);
send(pt);
}
Client:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <string>
#include <strstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/serialization/string.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
#define MAX_SIZE 1000
int main()
{
message_queue mq (boost::interprocess::open_or_create,"coda",10,MAX_SIZE);
size_t recv_size;
unsigned int priority;
ptree pt;
char buffer[MAX_SIZE];
mq.receive(buffer,MAX_SIZE,recv_size,priority);
buffer[recv_size] = 0;
std::istringstream is(buffer);
read_json(is, pt);
std::cout << "prefix: " << pt.get<std::string>("prefix") << " -- faceID: " << pt.get<std::string>("faceID") << std::endl;
system("PAUSE");
}
Related
I have written a code where i am writing a map in a binary file and than reading it using boost memory mapping, but whenever i display the result it is not correct it only shows value as
1852795252
. what should i do? Here's my code:
#include <iostream>
#include <vector>
#include <utility>
#include <fstream>
#include <utility>
#include <fstream>
#include <iterator>
#include <string>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <fstream>
#include <boost/serialization/map.hpp>
using namespace boost::archive;
using namespace boost::interprocess;
void save()
{
{
std::ofstream file{"archive1.bin"};
text_oarchive oa{file};
std::map<int,int> m;
m[3] = 9;
oa << m;
}
}
void load()
{
file_mapping fm("archive1.bin", read_only);
mapped_region region(fm, read_only);
int * m = (int *)region.get_address();
std::cout<<m[3]<<std::endl;
}
int main()
{
save();
load();
}
The problem is that you are not writing to archive1.bin what you think you are writing. This can be demonstrated by adding the lines:
text_oarchive oa2 {std::cout};
oa2 << m;
at the end of function save, and when you do this you see:
22 serialization::archive 17 0 0 1 0 0 0 3 9
printed to stdout.
To clarify further, change the last line of function load to:
std::cout << std::hex << m[3] << std::endl;
and then you see:
6e6f6974
which is ASCII noit, i.e. the fourth integer in archive1.bin.
All of which is a long-winded way of saying what john says in his comment above. You should read a boost archive using the approved serialisation functions.
Live demo.
I am still a novice for writing systemC-TLM. Now, I want to connect two modules by tlm_fifoFF. I am searching examples for a long time on net. But no use. Please help to give some ideas or examples how to achieve this.
This is my architecture:
and,this is my error information:
this is "main.cpp"
#include <systemc.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "merlin2.h"
#include "tlm.h"
#include <tlm_utils/simple_target_socket.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h>
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h>
using namespace sc_core;
using namespace tlm;
using namespace tlm_utils;
using namespace std;
int sc_main(int argc, char** argv){
Merlin2 merlin_test("merlin2_JW");
sc_start();
cout << "end" << endl;
return 0;
}
this is "merlin2.cpp"
#include "merlin2.h"
Merlin2::Merlin2(const sc_module_name& name)
{
ProcessEngine PE_TEST("test_PE");
test_PE TP("PE_test");
tlm::tlm_fifo <float> FF ("fifo");
TP.out(FF);
PE_TEST.in(FF);
}
this is "merlin2.h"
#ifndef __MERLIN2_H__
#define __MERLIN2_H__
#include <fstream>
#include <string>
#include <systemc.h>
#include "pe.h"
#include "test_PE.h"
class Merlin2: public sc_module
{
public:
SC_HAS_PROCESS(Merlin2);
Merlin2(const sc_module_name& name);
};
#endif
this is "pe.cpp"
#include <systemc.h>
#include <iostream>
#include "pe.h"
using namespace std;
ProcessEngine::ProcessEngine(const sc_module_name& name):in("in")
{
cout << "before SC_THREAD(run)" << endl;
SC_THREAD(run);
cout << "after SC_THREAD(run)" << endl;
}
void ProcessEngine::run()
{
int N = in.nb_get();
cout << " N=" << N << endl;
wait(1,SC_NS);
}
this is "pe.h"
#ifndef __PE_H__
#define __PE_H__
#include <iostream>
#include <bitset>
#include "tlm.h"
#include <tlm_utils/simple_target_socket.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h>
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h>
using namespace sc_core;
using namespace tlm;
using namespace tlm_utils;
using namespace std;
class ProcessEngine: public sc_module
{
public:
tlm::tlm_fifo<float> in;
void run();
ProcessEngine(const sc_module_name& name);
SC_HAS_PROCESS(ProcessEngine);
};
#endif
this is "test_PE.cpp"
#include <systemc.h>
#include <iostream>
#include "test_PE.h"
using namespace std;
test_PE::test_PE(const sc_module_name& name):out("out")
{
cout << "before start_test " << endl;
SC_THREAD(start_test);
cout << "After start_test " << endl;
}
void test_PE::start_test()
{
float A=5;
in.nb_put(A);
cout << "A=" << A << endl;
wait(1,SC_NS);
}
this is "test_PE.h"
#ifndef __TESTPE_H__
#define __TESTPE_H__
#include <fstream>
#include <string>
#include <systemc.h>
#include "tlm.h"
#include <tlm_utils/simple_target_socket.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h>
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h>
using namespace sc_core;
using namespace tlm;
using namespace tlm_utils;
using namespace std;
class test_PE:public sc_module
{
public:
tlm::tlm_fifo<float> out;
test_PE(const sc_module_name& name);
SC_HAS_PROCESS(test_PE);
void start_test();
private:
float A;
};
#endif
You're mixing SystemC/TLM notions and especially ports and channels.
tlm_fifo is a channel. It can be used to connect two ports. It's the yellow part of your image.
However, you can't directly connect a channel to a module. Instead, you need to use ports in each module you want to connect the channel. A port is associated to an interface defining methods you can use. In your case, you use nb_get(...) and nb_put(...).
For tlm_fifo, you can use these ports:
sc_port< tlm_nonblocking_put_if<float> >
sc_port< tlm_nonblocking_get_if<float> >
Finally, you create instances of your modules in your Merlin2 constructor. Objects are not persisted and deleted at the end of the constructor. They should be member of the class. Here is a complete working example of TLM-1.0 using tlm_fifo with non blocking interface.
Note: You're mixing TLM-2.0 and TLM-1.0 headers. I removed useless headers.
main.cpp
#include <systemc>
#include "merlin2.h"
using namespace sc_core;
using namespace std;
int sc_main(int argc, char** argv) {
Merlin2 merlin_test("merlin2_JW");
sc_start();
cout << "end" << endl;
return 0;
}
merlin2.h
#ifndef __MERLIN2_H__
#define __MERLIN2_H__
#include <fstream>
#include <string>
#include <systemc>
#include "pe.h"
#include "test_PE.h"
class Merlin2: public sc_module
{
public:
Merlin2(const sc_module_name& name);
tlm::tlm_fifo <float> FF;
ProcessEngine PE_TEST;
test_PE TP;
};
#endif
merlin2.cpp
#include "merlin2.h"
Merlin2::Merlin2(const sc_module_name& name):
PE_TEST("test_PE"),
TP("PE_test"),
FF("fifo")
{
TP.out(FF);
PE_TEST.in(FF);
}
pe.h
#ifndef __PE_H__
#define __PE_H__
#include <fstream>
#include <string>
#include <systemc>
#include <tlm>
using namespace sc_core;
using namespace tlm;
using namespace std;
class ProcessEngine: public sc_module
{
public:
sc_port< tlm_nonblocking_get_if<float> > in;
void run();
ProcessEngine(const sc_module_name& name);
SC_HAS_PROCESS(ProcessEngine);
};
#endif
pe.cpp
#include <systemc.h>
#include "pe.h"
using namespace std;
ProcessEngine::ProcessEngine(const sc_module_name& name):
in("in")
{
SC_THREAD(run);
}
void ProcessEngine::run()
{
sc_core::wait(1, SC_NS);
float N = 0;
bool r = in->nb_get(N);
cout << " N=" << N << endl;
}
test_PE.cpp
#include <systemc>
#include "test_PE.h"
using namespace std;
test_PE::test_PE(const sc_module_name& name):
out("out")
{
SC_THREAD(start_test);
}
void test_PE::start_test()
{
float A=5;
out->nb_put(A);
cout << "A=" << A << endl;
sc_core::wait(1, SC_NS);
}
test_PE.h
#ifndef __TESTPE_H__
#define __TESTPE_H__
#include <fstream>
#include <string>
#include <systemc>
#include <tlm>
using namespace sc_core;
using namespace tlm;
using namespace std;
class test_PE:public sc_module
{
public:
sc_port< tlm_nonblocking_put_if<float> > out;
test_PE(const sc_module_name& name);
SC_HAS_PROCESS(test_PE);
void start_test();
private:
float A;
};
#endif
#include "Stdafx.h"
#include "FishTracker.h"
#include <string>
#include "Utils.h"
#include <fstream>
using namespace std;
using namespace cv;
int main()
{
std::string videopath;
videopath = "E:\\TUKLNUST\\fishdata2\\Damo\\AR2-6\\Tetraodontidae_Lagocephalus_sceleratus_AD\\00001\\";
ifstream str;
str.open((videopath + DATA_TXT).c_str());
if (str.is_open())
{
cout << "file is open.";
}
}
file is open but str is this.
+ str {_Filebuffer={_Set_eback=0xcccccccc <Error reading characters of string.> _Set_egptr=0xcccccccc <Error reading characters of string.> ...} } std::basic_ifstream<char,std::char_traits<char> >
Configs:
win32, Debug
Visual Studio 2013
#include "Stdafx.h"
#include "FishTracker.h"
#include <string>
#include "Utils.h"
#include <fstream>
using namespace std;
using namespace cv;
int main()
{
std::string videopath;
videopath = "E:\\TUKLNUST\\fishdata2\\Damo\\AR2-6\\Tetraodontidae_Lagocephalus_sceleratus_AD\\00001\\";
ifstream str;
str.open((videopath + "DATA_TXT").c_str());
if (str.is_open())
{
cout << "file is open.";
}
}
boost::iostream bzip2_decompressor not decompressing file compressed by bzip2_compressor
Here's a simple self-contained example showing it to work:
Live On Coliru
#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <sstream>
namespace io = boost::iostreams;
int main()
{
std::stringstream ss;
{
io::filtering_stream<io::output> of;
of.push(io::bzip2_compressor{});
of.push(ss);
io::copy(std::cin, of);
}
std::cout << "Compressed input: " << ss.str().size() << " bytes\n";
ss.seekg(0ul);
{
io::filtering_stream<io::input> if_;
if_.push(io::bzip2_decompressor{});
if_.push(ss);
io::copy(if_, std::cout);
}
}
On Coliru it shows it compresses itself to 331 bytes, and back again to stdout
Perhaps you are forgetting to flush, have non-binary, whitespace skipping. We can't tell without a SSCCE
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream file;
boost::property_tree::ptree pt;
file.open ("json.txt");
if (!file)
cout << "problem";
//std::stringstream ss;
//ss << "{ \"root\": { \"values\": [1, 2, 3, 4, 5 ] } }";
boost::property_tree::read_json(file, pt);
ofstream filexml ("xml.txt");
boost::property_tree::write_xml(filexml, pt);
cout <<"done";
return 0;
}
However if I use the stringstream, it succeeds. The segmentation fault is at read_json call. The contents of the json.txt file are what is seen in the comments for stringstream. Can you point out what I'm doing wrong ?