// libeasy copy packet BasePacket* BasePacketStreamer::clone_packet(BasePacket* src) { int32_t pcode = src->getPCode(); int64_t length = src->length(); BasePacket* dest = dynamic_cast<BasePacket*>(_factory->createPacket(pcode)); assert(NULL != dest); // Stream stream(length); dest->stream_.expand(length); int ret = src->serialize(dest->stream_); if (TFS_SUCCESS == ret) { ret = dest->deserialize(dest->stream_); } TBSYS_LOG_DW(ret, "clone packet, ret=%d, pcode=%d, length=%ld, src=%p, dest=%p", ret, pcode, length, src, dest); if (TFS_SUCCESS != ret) { tbsys::gDelete(dest); dest = NULL; } else { dest->setChannelId(src->getChannelId()); dest->set_request(src->get_request()); dest->set_direction(src->get_direction()); } return dest; }
int BasePacketStreamer::encode_handler(easy_request_t *r, void *packet) { BasePacket* bp = (BasePacket*)packet; int32_t pcode = bp->getPCode(); int64_t length = bp->length(); TBSYS_LOG(DEBUG, "encode packet, pcode=%d, length=%ld, chid=%d", pcode, length, bp->getChannelId()); if (EASY_TYPE_CLIENT == r->ms->c->type) { uint32_t chid = ((easy_session_t*)r->ms)->packet_id; bp->setChannelId(chid); } else { if (((easy_message_t*)r->ms)->status == EASY_MESG_DESTROY) { return EASY_ERROR; } if (r->retcode == EASY_ABORT) { r->ms->c->pool->ref--; easy_atomic_dec(&r->ms->pool->ref); r->retcode = EASY_OK; } } easy_list_t list; easy_list_init(&list); Stream output(r->ms->pool, &list); output.reserve(TFS_PACKET_HEADER_V1_SIZE + bp->length()); output.set_int32(TFS_PACKET_FLAG_V1); char* len_pos = output.get_free(); // length() may not equal real data length output.set_int32(bp->length()); output.set_int16(bp->getPCode()); output.set_int16(TFS_PACKET_VERSION_V2); output.set_int64(bp->getChannelId()); output.set_int32(0); // crc, place holder if (TFS_SUCCESS != bp->serialize(output)) { return EASY_ERROR; } // use real length to replace header length if (bp->length() != output.get_data_length() - TFS_PACKET_HEADER_V1_SIZE) { // help to detect serialize problem TBSYS_LOG(DEBUG, "length()=%ld not equals to serialize()=%ld", bp->length(), output.get_data_length() - TFS_PACKET_HEADER_V1_SIZE); int64_t pos = 0; Serialization::set_int32(len_pos, INT_SIZE, pos, output.get_data_length() - TFS_PACKET_HEADER_V1_SIZE); } easy_request_addbuf_list(r, &list); return EASY_OK; }