int pyllbc_Service::SerializePyObj2Stream(PyObject *pyObj, LLBC_Stream &stream) { if (_codec == This::JsonCodec) { std::string out; if (UNLIKELY(pyllbc_ObjCoder::Encode(pyObj, out) != LLBC_RTN_OK)) return LLBC_RTN_FAILED; stream.WriteBuffer(out.data(), out.size()); return LLBC_RTN_OK; } else { // Create python layer Stream instance. PyObject *arg = PyTuple_New(2); PyTuple_SetItem(arg, 0, PyInt_FromLong(0)); // stream init size = 0. Py_INCREF(pyObj); PyTuple_SetItem(arg, 1, pyObj); // initWrite = pyObj(steal reference). PyObject *pyStreamObj = PyObject_CallObject(This::_streamCls, arg); if (UNLIKELY(!pyStreamObj)) { Py_DECREF(arg); pyllbc_TransferPyError(); return LLBC_RTN_FAILED; } // Get cobj property. PyObject *cobj = PyObject_GetAttr(pyStreamObj, _keyCObj); if (UNLIKELY(!cobj)) { Py_DECREF(pyStreamObj); Py_DECREF(arg); pyllbc_SetError("could not get llbc.Stream property 'cobj'"); return LLBC_RTN_FAILED; } // Convert to pyllbc_Stream *. pyllbc_Stream *cstream = NULL; PyArg_Parse(cobj, "l", &cstream); // Let stream attach to inlStream. LLBC_Stream &inlStream = cstream->GetLLBCStream(); stream.Attach(inlStream); (void)inlStream.Detach(); stream.SetAttachAttr(false); Py_DECREF(cobj); Py_DECREF(pyStreamObj); Py_DECREF(arg); return LLBC_RTN_OK; } }