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; }
uint64_t BasePacketStreamer::get_packet_id_handler(easy_connection_t *c, void *packet) { UNUSED(c); int32_t packet_id = 0; if (packet != NULL) { BasePacket *bp = (BasePacket*)packet; packet_id = bp->getChannelId(); } if (packet_id == 0) { while (packet_id == 0 || packet_id == -1) { packet_id = (int32_t)easy_atomic32_add_return(&global_chid, 1); } } return packet_id; }
bool BasePacketStreamer::encode(tbnet::Packet* packet, tbnet::DataBuffer* output) { bool bret = NULL != packet && NULL != output; if (bret) { tbnet::PacketHeader* header = packet->getPacketHeader(); int32_t old_len = output->getDataLen(); BasePacket* bpacket = dynamic_cast<BasePacket*>(packet); int32_t iret = TFS_SUCCESS; int32_t header_length = 0; int64_t pos = 0; //v1 if (TFS_PACKET_VERSION_V1 == bpacket->get_version()) { TfsPacketNewHeaderV1 pheader; pheader.crc_ = bpacket->get_crc(); pheader.flag_ = TFS_PACKET_FLAG_V1; pheader.id_ = bpacket->get_id(); pheader.length_ = bpacket->get_data_length(); pheader.type_ = header->_pcode; pheader.version_ = bpacket->get_version(); header_length = pheader.length(); output->ensureFree(header_length + pheader.length_); iret = pheader.serialize(output->getFree(), output->getFreeLen(), pos); }//v2 tbnet else if (TFS_PACKET_VERSION_V2 == bpacket->get_version()) { TfsPacketNewHeaderV1 pheader; pheader.crc_ = bpacket->get_crc(); pheader.flag_ = TFS_PACKET_FLAG_V1; pheader.id_ = bpacket->getChannelId(); pheader.length_ = bpacket->get_data_length(); pheader.type_ = header->_pcode; pheader.version_ = bpacket->get_version(); header_length = pheader.length(); output->ensureFree(header_length + pheader.length_); iret = pheader.serialize(output->getFree(), output->getFreeLen(), pos); } else//v0 { TfsPacketNewHeaderV1 pheader; memset(&pheader, 0, sizeof(pheader)); pheader.flag_ = TFS_PACKET_FLAG_V0; char* header_data = reinterpret_cast<char*>(&pheader); int32_t length = TFS_PACKET_HEADER_V0_SIZE - 2; for (int32_t i = 0; i < length; i++) { pheader.version_ = static_cast<uint16_t>(*(header_data + i)); } header_length = pheader.length(); output->ensureFree(header_length + pheader.length_); iret = pheader.serialize(output->getFree(), output->getFreeLen(), pos); } bret = TFS_SUCCESS == iret; if (bret) { //TBSYS_LOG(DEBUG, "pcode: %d, header length: %d, body length : %" PRI64_PREFIX "d", bpacket->getPCode(), header_length, bpacket->get_data_length()); //Func::hex_dump(output->getData(), output->getDataLen()); output->pourData(header_length); bret = bpacket->encode(output); //Func::hex_dump(output->getData(), output->getDataLen()); } else { TBSYS_LOG(ERROR, "encode erorr, pcode: %d", header->_pcode); output->stripData(output->getDataLen() - old_len); } } return bret; }