On Apr 5, 2012, at 6:27 AM, Piscium wrote:

> On 5 April 2012 01:02, Rush Manbert <[email protected]> wrote:
>> 
>> On Apr 2, 2012, at 12:47 AM, Piscium wrote:
>> 
>>> On C++ generated code,  __isset is set to true in the read function
>>> for the fields that have been received, however it is not looked at at
>>> all by the write function which always writes all fields regardless of
>>> the __isset value.
>>> 
>>> What is the reasoning behind this asymmetry? Is __isset intended only
>>> to cater for the receiving side, in particular for the use case in
>>> which the receiver is of a different software version than the sender?
> 
>> I don't think this is quite true. All required fields are always written, 
>> regardless of the state of their __isset. Optional fields are only written 
>> if their __isset is true. The read side always sets the __isset for 
>> everything it receives, but it doesn't receive the fields that are optional 
>> and didn't have __isset true when written.
> 
> Hi Rush,
> 
> I described what I found out in my tests. I only tested with Thrift v.
> 0.8.0, and only with C++ (things may be different with other Thrift
> versions or with Java or Python, I wouldn't know).
> 
> Anyway please see this minimal example (with comments):
> 
> ================
> namespace cpp test
> 
> struct Test {
>  1: i32 npotatoes, // optional field
> }
> 
> ================
> 
> This is the generated file (with some extra comments added by myself):
> 
> 
> uint32_t Test::write(::apache::thrift::protocol::TProtocol* oprot) const {
>  uint32_t xfer = 0;
>  xfer += oprot->writeStructBegin("Test");
>  xfer += oprot->writeFieldBegin("npotatoes",
> ::apache::thrift::protocol::T_I32, 1);
>  xfer += oprot->writeI32(this->npotatoes); //  <<<<<<<< This optional
> field is always written, regardless of __isset
>  xfer += oprot->writeFieldEnd();
>  xfer += oprot->writeFieldStop();
>  xfer += oprot->writeStructEnd();
>  return xfer;
> 
> =====
> 
> uint32_t Test::read(::apache::thrift::protocol::TProtocol* iprot) {
> //snip
> 
>    switch (fid)
>    {
>      case 1:
>        if (ftype == ::apache::thrift::protocol::T_I32) {
>          xfer += iprot->readI32(this->npotatoes);  //  <<<<<<<< This
> optional field is always read, regardless of __isset
>          // As __isset is not sent over the wire, it makes sense for
> the read function to set it when received
>          this->__isset.npotatos = true;
>        } else {
>          xfer += iprot->skip(ftype);
>        }
>        break;
>      default:
>        xfer += iprot->skip(ftype);
>        break;
>    }
> 
> //snip

Hi Piscium,

I'm using an older version of Thrift, but my code is all C++.

Try it with your Thrift IDL written like this and I think you'll see what I 
meant:

> ================
> namespace cpp test
> 
> struct Test {
>  1: optional i32 npotatoes, // optional field because it has the optional 
> keyword
  2:           i32 nonions,  // required field (but will be sent regardless of 
the __isset state)
> }
> 


- Rush

Reply via email to