Union in thrift shows all values setted in c++

≡放荡痞女 提交于 2019-12-18 09:05:59

问题


I made a simple union of three fields

union example{
    1:string STRING,
    2:i64 INT64,
    3:double DOUBLE
}

And I instantiate the example union in the client as:

example ex;
ex.__set_STRING("Example");
ex.__isset.STRING = true;

And send the example via a method that accepts example as an argument

In the server, the method that's called is done like this:

void get(const example &ex)
  {
    cout << ex.__isset.STRING << ' ' << ex.__isset.INT64 << ' ' <<
        ex.__isset.DOUBLE << endl;
    cout << ex << endl;
  }

And oddly the output for such a small program is:

1 1 1
example(STRING="Example", INT64=0, DOUBLE=0)

I don't know if this is the proper way of setting the union type, but I tried several combinations and none seems to work.

The sources for the snippet can be found here: https://github.com/enriquefynn/union_thrift


回答1:


uint32_t type_ex::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("type_ex");

  xfer += oprot->writeFieldBegin("STRING", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->STRING);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("INT64", ::apache::thrift::protocol::T_I64, 2);
  xfer += oprot->writeI64(this->INT64);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("DOUBLE", ::apache::thrift::protocol::T_DOUBLE, 3);
  xfer += oprot->writeDouble(this->DOUBLE);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

Looks like a bug with unions. The values are written unconditionally, whcih is right for struct but not for union. Consequently, the workaround would be to add an explicit optional:

union type_ex
{
    1 : optional string STRING,
    2 : optional i64 INT64,
    3 : optional double DOUBLE
}

Which gives us:

uint32_t type_ex::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("type_ex");

  if (this->__isset.STRING) {
    xfer += oprot->writeFieldBegin("STRING", ::apache::thrift::protocol::T_STRING, 1);
    xfer += oprot->writeString(this->STRING);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.INT64) {
    xfer += oprot->writeFieldBegin("INT64", ::apache::thrift::protocol::T_I64, 2);
    xfer += oprot->writeI64(this->INT64);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.DOUBLE) {
    xfer += oprot->writeFieldBegin("DOUBLE", ::apache::thrift::protocol::T_DOUBLE, 3);
    xfer += oprot->writeDouble(this->DOUBLE);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

Bug report filed.



来源:https://stackoverflow.com/questions/35488379/union-in-thrift-shows-all-values-setted-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!