-
Notifications
You must be signed in to change notification settings - Fork 918
Closed
Description
Hello,
Sorry if my question is kind of stupid, I am new to message pack.
I'd like to use the SAX style parser with a partial buffer in C++.
Problem is when I continue reading an array, values are seen as if they where not part of an array.
I can take it into account in my processing, but I am wandering if I am using the API the way it should be ?
Does this exist in msgpack-c ? If not is it something which is usefull ?
I made a small example I wish that I could keep the fact that the previous parse iteration was in an array, without buffering all the content.
#include <msgpack.hpp>
#include <iostream>
#include <sstream>
#include <array>
#include <string>
struct json_like_visitor : msgpack::v2::null_visitor {
json_like_visitor(std::string& s):m_s(s) {}
bool visit_nil() {
m_s += "null";
return true;
}
bool visit_boolean(bool v) {
if (v) m_s += "true";
else m_s += "false";
return true;
}
bool visit_positive_integer(uint64_t v) {
std::stringstream ss;
ss << v;
m_s += ss.str();
return true;
}
bool visit_negative_integer(int64_t v) {
std::stringstream ss;
ss << v;
m_s += ss.str();
return true;
}
bool visit_str(const char* v, uint32_t size) {
// I omit escape process.
m_s += '"' + std::string(v, size) + '"';
return true;
}
bool start_array(uint32_t /*num_elements*/) {
m_s += "[";
return true;
}
bool end_array_item() {
m_s += ",";
return true;
}
bool end_array() {
m_s.erase(m_s.size() - 1, 1); // remove the last ','
m_s += "]";
return true;
}
bool start_map(uint32_t /*num_kv_pairs*/) {
m_s += "{";
return true;
}
bool end_map_key() {
m_s += ":";
return true;
}
bool end_map_value() {
m_s += ",";
return true;
}
bool end_map() {
m_s.erase(m_s.size() - 1, 1); // remove the last ','
m_s += "}";
return true;
}
void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) {
std::cerr << "parse error"<<std::endl;
}
void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) {
std::cout << "insufficient bytes"<<std::endl;
}
std::string& m_s;
};
int parse( char*& buffer, unsigned int & buffer_size, struct json_like_visitor & v )
{
std::size_t off = 0;
bool ret = msgpack::v2::parse(static_cast<const char*>(buffer), buffer_size, off, v);
if ( ret == false )
{
buffer_size = 0;
return -1;
}
if ( buffer_size == off )
{
buffer_size = 0;
return 0;
}
else
{
unsigned int remaining_bytes = buffer_size - off;
char* overflow = new char[remaining_bytes];
memcpy(overflow, buffer+off, remaining_bytes);
memcpy(buffer, overflow, remaining_bytes);
buffer_size = remaining_bytes;
return 1;
}
return -1;
}
int main()
{
std::array<int, 5> a = { 1, 2, 3, 4, 5 } ;
std::stringstream ss;
msgpack::pack(ss, a);
unsigned int length = 3;
unsigned int buff_size = length;
char * buffer = new char[buff_size];
ss.read (buffer, buff_size);
buff_size = ss.gcount();
std::string s;
json_like_visitor v(s);
while( buff_size > 0 )
{
std::cout << "Reading bytes ";
std::cout << std::hex;
for (int i = 0; i < buff_size; ++i)
{
std::cout << std::setfill('0') << std::setw(2) << +static_cast<unsigned char>(buffer[i]) << " ";
}
std::cout<<std::endl;
parse(buffer, buff_size, v);
ss.read(buffer,length-buff_size);
buff_size += ss.gcount();
}
std::cout << s << std::endl;
delete buffer;
return 0;
}output :
Reading bytes 95 01 02
insufficient bytes
Reading bytes 03 04 05
Reading bytes 04 05
Reading bytes 05
[1,2,345
expected output :
Reading bytes 95 01 02
insufficient bytes
Reading bytes 03 04 05
Reading bytes 04 05
Reading bytes 05
[1,2,3,4,5]
Metadata
Metadata
Assignees
Labels
No labels