// 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; }
void* BasePacketStreamer::decode_handler(easy_message_t *m) { // check if header complete if (m->input->last - m->input->pos < TFS_PACKET_HEADER_V1_SIZE) { TBSYS_LOG(DEBUG, "packet header not complete"); return NULL; } assert(m->pool->tlock <= 1 && m->pool->flags <= 1); // why? // decode packet header, get length and pcode Stream input(m->input); uint32_t flag = 0; int32_t len = 0; int16_t pcode = 0; int16_t version = 0; uint64_t id = 0; uint32_t crc = 0; input.get_int32(reinterpret_cast<int32_t*>(&flag)); input.get_int32(&len); input.get_int16(&pcode); input.get_int16(&version); input.get_int64(reinterpret_cast<int64_t*>(&id)); input.get_int32(reinterpret_cast<int32_t*>(&crc)); if (flag != TFS_PACKET_FLAG_V1 || len < 0 || len > (1<<26) /* 64M */) { TBSYS_LOG(ERROR, "decoding failed: flag=%x, len=%d, pcode=%d", flag, len, pcode); m->status = EASY_ERROR; return NULL; } // only received part of packet data if (m->input->last - m->input->pos < len) { //TBSYS_LOG(DEBUG, "data in buffer not enough: data_len=%d, buf_len=%d, pcode=%d", // len, static_cast<int32_t>(m->input->last - m->input->pos), pcode); m->next_read_len = len - (m->input->last - m->input->pos); m->input->pos -= TFS_PACKET_HEADER_V1_SIZE; return NULL; } TBSYS_LOG(DEBUG, "decode packet, pcode=%d, length=%d", pcode, len); BasePacket* bp = dynamic_cast<BasePacket*>(_factory->createPacket(pcode)); assert(NULL != bp); tbnet::PacketHeader header; header._chid = id; header._pcode = pcode; header._dataLen = len; bp->setPacketHeader(&header); // copy raw data to BasePacket's stream // because some Message hold the pointer bp->stream_.reserve(len); bp->stream_.set_bytes(m->input->pos, len); m->input->pos += len; assert(m->input->pos <= m->input->last); if(TFS_SUCCESS != bp->deserialize(bp->stream_)) { TBSYS_LOG(ERROR, "decoding packet failed, pcode=%d", pcode); tbsys::gDelete(bp); input.clear_last_read_mark(); m->status = EASY_ERROR; return NULL; } // help to detect serialize/deserialize not match problem if (bp->stream_.get_data_length() != 0) { TBSYS_LOG(DEBUG, "some data are useless, pcode=%d, unused_length=%ld", pcode, bp->stream_.get_data_length()); } assert(m->pool->tlock <= 1 && m->pool->flags <= 1); return bp; }