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