1+ #include < iostream>
2+ #include < sstream>
3+ #include < msgpack.hpp>
4+
5+ struct json_like_visitor : msgpack::v2::null_visitor {
6+ json_like_visitor (std::string& s):m_s(s), m_ref(false ) {} // m_ref is false by default
7+
8+ bool visit_nil () {
9+ m_s += " null" ;
10+ return true ;
11+ }
12+ bool visit_boolean (bool v) {
13+ if (v) m_s += " true" ;
14+ else m_s += " false" ;
15+ return true ;
16+ }
17+ bool visit_positive_integer (uint64_t v) {
18+ std::stringstream ss;
19+ ss << v;
20+ m_s += ss.str ();
21+ return true ;
22+ }
23+ bool visit_negative_integer (int64_t v) {
24+ std::stringstream ss;
25+ ss << v;
26+ m_s += ss.str ();
27+ return true ;
28+ }
29+ bool visit_str (const char * v, uint32_t size) {
30+ // I omit escape process.
31+ m_s += ' "' + std::string (v, size) + ' "' ;
32+ return true ;
33+ }
34+ bool start_array (uint32_t /* num_elements*/ ) {
35+ m_s += " [" ;
36+ return true ;
37+ }
38+ bool end_array_item () {
39+ m_s += " ," ;
40+ return true ;
41+ }
42+ bool end_array () {
43+ m_s.erase (m_s.size () - 1 , 1 ); // remove the last ','
44+ m_s += " ]" ;
45+ return true ;
46+ }
47+ bool start_map (uint32_t /* num_kv_pairs*/ ) {
48+ m_s += " {" ;
49+ return true ;
50+ }
51+ bool end_map_key () {
52+ m_s += " :" ;
53+ return true ;
54+ }
55+ bool end_map_value () {
56+ m_s += " ," ;
57+ return true ;
58+ }
59+ bool end_map () {
60+ m_s.erase (m_s.size () - 1 , 1 ); // remove the last ','
61+ m_s += " }" ;
62+ return true ;
63+ }
64+ void parse_error (size_t /* parsed_offset*/ , size_t /* error_offset*/ ) {
65+ std::cerr << " parse error" <<std::endl;
66+ }
67+ void insufficient_bytes (size_t /* parsed_offset*/ , size_t /* error_offset*/ ) {
68+ std::cout << " insufficient bytes" <<std::endl;
69+ }
70+ std::string& m_s;
71+
72+ // These two functions are required by parser.
73+ void set_referenced (bool ref) { m_ref = ref; }
74+ bool referenced () const { return m_ref; }
75+ bool m_ref;
76+ };
77+
78+ struct do_nothing {
79+ void operator ()(char * /* buffer*/ ) {
80+ }
81+ };
82+
83+ class json_like_printer : public msgpack ::parser<json_like_printer, do_nothing>,
84+ public json_like_visitor {
85+ typedef parser<json_like_printer, do_nothing> parser_t ;
86+ public:
87+ json_like_printer (std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE)
88+ :parser_t (do_nothing_, initial_buffer_size),
89+ json_like_visitor (json_str_) {
90+ }
91+
92+ json_like_visitor& visitor () { return *this ; }
93+ void print () { std::cout << json_str_ << std::endl; json_str_.clear ();}
94+ private:
95+ do_nothing do_nothing_;
96+ std::string json_str_;
97+ };
98+
99+ template <typename T>
100+ struct ref_buffer {
101+ ref_buffer (T& t):t(t) {}
102+ void write (char const * ptr, std::size_t len) {
103+ if (len > t.buffer_capacity ()) {
104+ t.reserve_buffer (len - t.buffer_capacity ());
105+ }
106+ std::memcpy (t.buffer (), ptr, len);
107+ t.buffer_consumed (len);
108+ }
109+ T& t;
110+ };
111+
112+ #define BUFFERING_SIZE_MAX 100
113+
114+ // simulates streamed content (a socket for example)
115+ bool produce ( std::stringstream & ss, char * buff, std::size_t & size)
116+ {
117+ ss.read (buff, BUFFERING_SIZE_MAX);
118+ size = ss.gcount ();
119+ return (size > 0 );
120+ }
121+
122+ // shows how you can treat data
123+ void consume ( const char * buff, const std::size_t size,
124+ ref_buffer<json_like_printer> & rb,
125+ json_like_printer & jp
126+ )
127+ {
128+ rb.write (buff,size);
129+ while ( jp.next () )
130+ {
131+ // here we print the data, you could do any wanted processing
132+ jp.print ();
133+ }
134+ }
135+
136+ int main () {
137+
138+ std::vector<std::vector<int >> vvi1 { { 1 ,2 ,3 ,4 ,5 }, { 6 ,7 ,8 ,9 ,10 } };
139+ std::vector<std::vector<int >> vvi2 { { 11 ,12 ,13 ,14 ,15 }, { 16 ,17 ,18 ,19 ,20 } };
140+
141+ std::stringstream ss;
142+
143+ msgpack::pack (ss, vvi1);
144+ msgpack::pack (ss, vvi2);
145+
146+ char buffer[BUFFERING_SIZE_MAX];
147+ std::size_t size = 0 ;
148+
149+ json_like_printer jp (1 ); // set initial buffer size explicitly
150+ ref_buffer<json_like_printer> rb (jp);
151+
152+ while ( produce (ss,buffer,size) )
153+ {
154+ consume (buffer, size, rb, jp);
155+ }
156+
157+ }
0 commit comments