Hi,

first I would like to tell you, that I have a new job. I'm now working 
at Comyno. We develop a middleware for banks based on cxxtools, tntdb 
and tntnet. And apache Qpid as a message broker. Really nice job.

I'm working on a tcp server and client, which talks with json. There I 
use the json serializer and deserializer. This makes it really easy. You 
send and get objects from the socket.

And I found a problem. When reading from a input stream like that:

std::istream& in = ...; // some input stream like a istream on a socket 
in my case
MyObject obj;  // a object, which is serialzable and deserializable with 
cxxtools;

in >> cxxtools::Json(obj);  // reads a object from the stream

This looks really easy. But it has a big problem.

The json deserializer do not read from a std::istream but a 
cxxtools::TextIStream with is a unicode input stream. It translates 
between a char stream (std::iostream) and unicode using a codec like 
cxxtools::Utf8Codec by default. To implement that input operator for 
cxxtools::Json a cxxtools::TextIStream is instantiated temporarily. So 
the json deserializer reads unicode data and the TextIStream reads a 
char stream to translate it.

So far so good. The problem is, that cxxtools::TextIStream bufferes 
data. It do not read just byte by byte but in greater chunks. When the 
json deserializer encounters the end of the json message, the temporary 
cxxtools::TextIStream is thrown away and the data read so far is 
discarded. When the code above tries to read the next message, there are 
some bytes lost and the deserializer will fail to read a complete json 
message.

To solve that, you have to read from a cxxtools::TextIStream like that:

std::istream& in = ...;
cxxtools::TextIStream tin(in, new cxxtools::Utf8Codec());

tin >> cxxtools::Json(obj);

And you have to be careful not to throw away the TextIStream between the 
calls.

There are 2 possible solutions for cxxtools to solve that. I have to 
change the constructor of cxxtools::JsonDeserializer.

Either just remove the possibility to read from a std.:istream, which 
makes it necessary for the user to instantiate a TextIStream, but makes 
it clear, that the user is responsible for the buffered data.

Or change the deserializer not to use the TextIStream but use the codec 
directly. This is less effective. But it keeps the easiness.

I will check, how difficult it is to implement the second solution. i 
like to keep the easiness and also compatibility.

Tommi

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Tntnet-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tntnet-general

Reply via email to