func packResponse()

in response.go [67:148]


func packResponse(header DubboHeader, ret interface{}) ([]byte, error) {
	var byteArray []byte

	response := EnsureResponse(ret)

	hb := header.Type == PackageHeartbeat

	// magic
	if hb {
		byteArray = append(byteArray, DubboResponseHeartbeatHeader[:]...)
	} else {
		byteArray = append(byteArray, DubboResponseHeaderBytes[:]...)
	}
	// set serialID, identify serialization types, eg: fastjson->6, hessian2->2
	byteArray[2] |= header.SerialID & SERIAL_MASK
	// response status
	if header.ResponseStatus != 0 {
		byteArray[3] = header.ResponseStatus
	}

	// request id
	binary.BigEndian.PutUint64(byteArray[4:], uint64(header.ID))

	// body
	encoder := NewEncoder()
	encoder.Append(byteArray[:HEADER_LENGTH])

	if header.ResponseStatus == Response_OK {
		if hb {
			encoder.Encode(nil)
		} else {
			atta := isSupportResponseAttachment(response.Attachments[DUBBO_VERSION_KEY])

			var resWithException, resValue, resNullValue int32
			if atta {
				resWithException = RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS
				resValue = RESPONSE_VALUE_WITH_ATTACHMENTS
				resNullValue = RESPONSE_NULL_VALUE_WITH_ATTACHMENTS
			} else {
				resWithException = RESPONSE_WITH_EXCEPTION
				resValue = RESPONSE_VALUE
				resNullValue = RESPONSE_NULL_VALUE
			}

			if response.Exception != nil { // throw error
				encoder.Encode(resWithException)
				if t, ok := response.Exception.(java_exception.Throwabler); ok {
					encoder.Encode(t)
				} else {
					encoder.Encode(java_exception.NewThrowable(response.Exception.Error()))
				}
			} else {
				if response.RspObj == nil {
					encoder.Encode(resNullValue)
				} else {
					encoder.Encode(resValue)
					encoder.Encode(response.RspObj) // result
				}
			}

			if atta {
				encoder.Encode(response.Attachments) // attachments
			}
		}
	} else {
		if response.Exception != nil { // throw error
			encoder.Encode(response.Exception.Error())
		} else {
			encoder.Encode(response.RspObj)
		}
	}

	byteArray = encoder.Buffer()
	byteArray = EncNull(byteArray) // if not, "java client" will throw exception  "unexpected end of file"
	pkgLen := len(byteArray)
	if pkgLen > int(DEFAULT_LEN) { // 8M
		return nil, perrors.Errorf("Data length %d too large, max payload %d", pkgLen, DEFAULT_LEN)
	}
	// byteArray{body length}
	binary.BigEndian.PutUint32(byteArray[12:], uint32(pkgLen-HEADER_LENGTH))
	return byteArray, nil
}